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"),
91static const unsigned ZvfbfaVPOps[] = {ISD::VP_FNEG, ISD::VP_FABS,
103 !Subtarget.hasStdExtF()) {
104 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
105 "doesn't support the F instruction set extension (ignoring "
109 !Subtarget.hasStdExtD()) {
110 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
111 "doesn't support the D instruction set extension (ignoring "
130 MVT XLenVT = Subtarget.getXLenVT();
135 if (Subtarget.hasStdExtZfhmin())
137 if (Subtarget.hasStdExtZfbfmin() || Subtarget.hasVendorXAndesBFHCvt())
139 if (Subtarget.hasStdExtF())
141 if (Subtarget.hasStdExtD())
143 if (Subtarget.hasStdExtZhinxmin())
145 if (Subtarget.hasStdExtZfinx())
147 if (Subtarget.hasStdExtZdinx()) {
148 if (Subtarget.is64Bit())
155 MVT::nxv1i1, MVT::nxv2i1, MVT::nxv4i1, MVT::nxv8i1,
156 MVT::nxv16i1, MVT::nxv32i1, MVT::nxv64i1};
158 MVT::nxv1i8, MVT::nxv2i8, MVT::nxv4i8, MVT::nxv8i8, MVT::nxv16i8,
159 MVT::nxv32i8, MVT::nxv64i8, MVT::nxv1i16, MVT::nxv2i16, MVT::nxv4i16,
160 MVT::nxv8i16, MVT::nxv16i16, MVT::nxv32i16, MVT::nxv1i32, MVT::nxv2i32,
161 MVT::nxv4i32, MVT::nxv8i32, MVT::nxv16i32, MVT::nxv1i64, MVT::nxv2i64,
162 MVT::nxv4i64, MVT::nxv8i64};
164 MVT::nxv1f16, MVT::nxv2f16, MVT::nxv4f16,
165 MVT::nxv8f16, MVT::nxv16f16, MVT::nxv32f16};
167 MVT::nxv1bf16, MVT::nxv2bf16, MVT::nxv4bf16,
168 MVT::nxv8bf16, MVT::nxv16bf16, MVT::nxv32bf16};
170 MVT::nxv1f32, MVT::nxv2f32, MVT::nxv4f32, MVT::nxv8f32, MVT::nxv16f32};
172 MVT::nxv1f64, MVT::nxv2f64, MVT::nxv4f64, MVT::nxv8f64};
174 MVT::riscv_nxv1i8x2, MVT::riscv_nxv1i8x3, MVT::riscv_nxv1i8x4,
175 MVT::riscv_nxv1i8x5, MVT::riscv_nxv1i8x6, MVT::riscv_nxv1i8x7,
176 MVT::riscv_nxv1i8x8, MVT::riscv_nxv2i8x2, MVT::riscv_nxv2i8x3,
177 MVT::riscv_nxv2i8x4, MVT::riscv_nxv2i8x5, MVT::riscv_nxv2i8x6,
178 MVT::riscv_nxv2i8x7, MVT::riscv_nxv2i8x8, MVT::riscv_nxv4i8x2,
179 MVT::riscv_nxv4i8x3, MVT::riscv_nxv4i8x4, MVT::riscv_nxv4i8x5,
180 MVT::riscv_nxv4i8x6, MVT::riscv_nxv4i8x7, MVT::riscv_nxv4i8x8,
181 MVT::riscv_nxv8i8x2, MVT::riscv_nxv8i8x3, MVT::riscv_nxv8i8x4,
182 MVT::riscv_nxv8i8x5, MVT::riscv_nxv8i8x6, MVT::riscv_nxv8i8x7,
183 MVT::riscv_nxv8i8x8, MVT::riscv_nxv16i8x2, MVT::riscv_nxv16i8x3,
184 MVT::riscv_nxv16i8x4, MVT::riscv_nxv32i8x2};
186 if (Subtarget.hasVInstructions()) {
187 auto addRegClassForRVV = [
this](
MVT VT) {
191 if (VT.getVectorMinNumElements() < MinElts)
194 unsigned Size = VT.getSizeInBits().getKnownMinValue();
197 RC = &RISCV::VRRegClass;
199 RC = &RISCV::VRM2RegClass;
201 RC = &RISCV::VRM4RegClass;
203 RC = &RISCV::VRM8RegClass;
210 for (
MVT VT : BoolVecVTs)
211 addRegClassForRVV(VT);
212 for (
MVT VT : IntVecVTs) {
213 if (VT.getVectorElementType() == MVT::i64 &&
214 !Subtarget.hasVInstructionsI64())
216 addRegClassForRVV(VT);
219 if (Subtarget.hasVInstructionsF16Minimal() ||
220 Subtarget.hasVendorXAndesVPackFPH())
221 for (
MVT VT : F16VecVTs)
222 addRegClassForRVV(VT);
224 if (Subtarget.hasVInstructionsBF16Minimal() ||
225 Subtarget.hasVendorXAndesVBFHCvt())
226 for (
MVT VT : BF16VecVTs)
227 addRegClassForRVV(VT);
229 if (Subtarget.hasVInstructionsF32())
230 for (
MVT VT : F32VecVTs)
231 addRegClassForRVV(VT);
233 if (Subtarget.hasVInstructionsF64())
234 for (
MVT VT : F64VecVTs)
235 addRegClassForRVV(VT);
237 if (Subtarget.useRVVForFixedLengthVectors()) {
238 auto addRegClassForFixedVectors = [
this](
MVT VT) {
245 if (useRVVForFixedLengthVectorVT(VT))
246 addRegClassForFixedVectors(VT);
249 if (useRVVForFixedLengthVectorVT(VT))
250 addRegClassForFixedVectors(VT);
310 if (!(Subtarget.hasVendorXCValu() && !Subtarget.is64Bit())) {
320 if (!Subtarget.hasVendorXTHeadBb() && !Subtarget.hasVendorXqcibm() &&
321 !Subtarget.hasVendorXAndesPerf())
326 if (!Subtarget.hasStdExtZbb() && !Subtarget.hasStdExtP() &&
327 !Subtarget.hasVendorXTHeadBb() && !Subtarget.hasVendorXqcibm() &&
328 !Subtarget.hasVendorXAndesPerf() &&
329 !(Subtarget.hasVendorXCValu() && !Subtarget.is64Bit()))
332 if (Subtarget.hasStdExtZilsd() && !Subtarget.is64Bit()) {
337 if (Subtarget.is64Bit()) {
344 if (!Subtarget.hasStdExtZbb())
350 if (!Subtarget.hasStdExtZmmul()) {
352 }
else if (Subtarget.is64Bit()) {
359 if (!Subtarget.hasStdExtM()) {
362 }
else if (Subtarget.is64Bit()) {
364 {MVT::i8, MVT::i16, MVT::i32},
Custom);
374 if (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) {
375 if (Subtarget.is64Bit())
377 }
else if (Subtarget.hasVendorXTHeadBb()) {
378 if (Subtarget.is64Bit())
381 }
else if (Subtarget.hasVendorXCVbitmanip() && !Subtarget.is64Bit()) {
390 if ((Subtarget.hasVendorXCVbitmanip() || Subtarget.hasVendorXqcibm()) &&
391 !Subtarget.is64Bit()) {
397 if (Subtarget.hasStdExtZbkb())
401 if (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtP() ||
402 (Subtarget.hasVendorXCValu() && !Subtarget.is64Bit())) {
407 if (Subtarget.hasCTZLike()) {
408 if (Subtarget.is64Bit())
413 if (Subtarget.hasStdExtP() && Subtarget.is64Bit())
417 if (!Subtarget.hasCPOPLike()) {
420 if (Subtarget.is64Bit())
427 if (Subtarget.hasCLZLike()) {
431 if (Subtarget.is64Bit() &&
432 (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtP()))
438 if (Subtarget.hasStdExtP() ||
439 (Subtarget.hasVendorXCValu() && !Subtarget.is64Bit())) {
441 if (Subtarget.is64Bit())
443 }
else if (Subtarget.hasShortForwardBranchOpt()) {
446 }
else if (Subtarget.is64Bit()) {
450 if (!Subtarget.useMIPSCCMovInsn() && !Subtarget.hasVendorXTHeadCondMov())
453 if (Subtarget.hasVendorXqcia() && !Subtarget.is64Bit()) {
462 static const unsigned FPLegalNodeTypes[] = {
463 ISD::FMINNUM, ISD::FMAXNUM, ISD::FMINIMUMNUM,
464 ISD::FMAXIMUMNUM, ISD::LRINT, ISD::LLRINT,
476 static const unsigned FPOpToExpand[] = {
477 ISD::FSIN, ISD::FCOS, ISD::FSINCOS, ISD::FPOW,
480 static const unsigned FPRndMode[] = {
481 ISD::FCEIL, ISD::FFLOOR, ISD::FTRUNC, ISD::FRINT, ISD::FROUND,
484 static const unsigned ZfhminZfbfminPromoteOps[] = {
485 ISD::FMINNUM, ISD::FMAXNUM, ISD::FMAXIMUMNUM,
492 ISD::FTRUNC, ISD::FRINT, ISD::FROUND,
495 if (Subtarget.hasStdExtZfbfmin()) {
510 if (Subtarget.hasStdExtZfhminOrZhinxmin()) {
511 if (Subtarget.hasStdExtZfhOrZhinx()) {
518 if (Subtarget.hasStdExtZfa())
523 for (
auto Op : {ISD::LROUND, ISD::LLROUND, ISD::LRINT, ISD::LLRINT,
544 ISD::FNEARBYINT, MVT::f16,
545 Subtarget.hasStdExtZfh() && Subtarget.hasStdExtZfa() ?
Legal :
Promote);
547 ISD::FCOS, ISD::FSIN, ISD::FSINCOS, ISD::FEXP,
548 ISD::FEXP2, ISD::FEXP10, ISD::FLOG, ISD::FLOG2,
549 ISD::FLOG10, ISD::FLDEXP, ISD::FFREXP, ISD::FMODF},
561 if (Subtarget.is64Bit())
565 if (Subtarget.hasStdExtFOrZfinx()) {
587 if (Subtarget.hasStdExtZfa()) {
596 if (Subtarget.hasStdExtFOrZfinx() && Subtarget.is64Bit())
599 if (Subtarget.hasStdExtDOrZdinx()) {
602 if (!Subtarget.is64Bit())
605 if (Subtarget.hasStdExtZdinx() && !Subtarget.hasStdExtZilsd() &&
606 !Subtarget.is64Bit()) {
611 if (Subtarget.hasStdExtZfa()) {
617 if (Subtarget.is64Bit())
646 if (Subtarget.is64Bit()) {
653 if (Subtarget.hasStdExtFOrZfinx()) {
679 if (Subtarget.is64Bit())
689 if (Subtarget.is64Bit()) {
696 if (Subtarget.is64Bit())
699 if (Subtarget.hasVendorXMIPSCBOP())
701 else if (Subtarget.hasStdExtZicbop())
704 if (Subtarget.hasStdExtZalrsc()) {
706 if (Subtarget.hasStdExtZabha() && Subtarget.hasStdExtZacas())
710 }
else if (Subtarget.hasForcedAtomics()) {
725 if (Subtarget.hasVInstructions()) {
734 {MVT::i8, MVT::i16},
Custom);
735 if (Subtarget.is64Bit())
745 static const unsigned IntegerVPOps[] = {
746 ISD::VP_ADD, ISD::VP_SUB, ISD::VP_MUL,
747 ISD::VP_SDIV, ISD::VP_UDIV, ISD::VP_SREM,
748 ISD::VP_UREM, ISD::VP_AND, ISD::VP_OR,
749 ISD::VP_XOR, ISD::VP_SRA, ISD::VP_SRL,
750 ISD::VP_SHL, ISD::VP_REDUCE_ADD, ISD::VP_REDUCE_AND,
751 ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR, ISD::VP_REDUCE_SMAX,
752 ISD::VP_REDUCE_SMIN, ISD::VP_REDUCE_UMAX, ISD::VP_REDUCE_UMIN,
753 ISD::VP_MERGE, ISD::VP_SELECT, ISD::VP_FP_TO_SINT,
754 ISD::VP_FP_TO_UINT, ISD::VP_SETCC, ISD::VP_SIGN_EXTEND,
755 ISD::VP_ZERO_EXTEND, ISD::VP_TRUNCATE, ISD::VP_SMIN,
756 ISD::VP_SMAX, ISD::VP_UMIN, ISD::VP_UMAX,
757 ISD::VP_ABS, ISD::EXPERIMENTAL_VP_REVERSE, ISD::EXPERIMENTAL_VP_SPLICE,
758 ISD::VP_SADDSAT, ISD::VP_UADDSAT, ISD::VP_SSUBSAT,
759 ISD::VP_USUBSAT, ISD::VP_CTTZ_ELTS, ISD::VP_CTTZ_ELTS_ZERO_UNDEF,
760 ISD::EXPERIMENTAL_VP_SPLAT};
762 static const unsigned FloatingPointVPOps[] = {
763 ISD::VP_FADD, ISD::VP_FSUB, ISD::VP_FMUL,
764 ISD::VP_FDIV, ISD::VP_FNEG, ISD::VP_FABS,
765 ISD::VP_FMA, ISD::VP_REDUCE_FADD, ISD::VP_REDUCE_SEQ_FADD,
766 ISD::VP_REDUCE_FMIN, ISD::VP_REDUCE_FMAX, ISD::VP_MERGE,
767 ISD::VP_SELECT, ISD::VP_SINT_TO_FP, ISD::VP_UINT_TO_FP,
768 ISD::VP_SETCC, ISD::VP_FP_ROUND, ISD::VP_FP_EXTEND,
769 ISD::VP_SQRT, ISD::VP_FMINNUM, ISD::VP_FMAXNUM,
770 ISD::VP_FCEIL, ISD::VP_FFLOOR, ISD::VP_FROUND,
771 ISD::VP_FROUNDEVEN, ISD::VP_FCOPYSIGN, ISD::VP_FROUNDTOZERO,
772 ISD::VP_FRINT, ISD::VP_FNEARBYINT, ISD::VP_IS_FPCLASS,
773 ISD::VP_FMINIMUM, ISD::VP_FMAXIMUM, ISD::VP_LRINT,
774 ISD::VP_LLRINT, ISD::VP_REDUCE_FMINIMUM,
775 ISD::VP_REDUCE_FMAXIMUM, ISD::EXPERIMENTAL_VP_SPLAT};
777 static const unsigned IntegerVecReduceOps[] = {
778 ISD::VECREDUCE_ADD, ISD::VECREDUCE_AND, ISD::VECREDUCE_OR,
779 ISD::VECREDUCE_XOR, ISD::VECREDUCE_SMAX, ISD::VECREDUCE_SMIN,
780 ISD::VECREDUCE_UMAX, ISD::VECREDUCE_UMIN};
782 static const unsigned FloatingPointVecReduceOps[] = {
783 ISD::VECREDUCE_FADD, ISD::VECREDUCE_SEQ_FADD, ISD::VECREDUCE_FMIN,
784 ISD::VECREDUCE_FMAX, ISD::VECREDUCE_FMINIMUM, ISD::VECREDUCE_FMAXIMUM};
786 static const unsigned FloatingPointLibCallOps[] = {
787 ISD::FREM, ISD::FPOW, ISD::FCOS, ISD::FSIN, ISD::FSINCOS, ISD::FEXP,
788 ISD::FEXP2, ISD::FEXP10, ISD::FLOG, ISD::FLOG2, ISD::FLOG10};
790 if (!Subtarget.is64Bit()) {
799 ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR,
800 ISD::VP_REDUCE_SMAX, ISD::VP_REDUCE_SMIN,
801 ISD::VP_REDUCE_UMAX, ISD::VP_REDUCE_UMIN},
805 for (
MVT VT : BoolVecVTs) {
831 {ISD::VECREDUCE_AND, ISD::VECREDUCE_OR, ISD::VECREDUCE_XOR}, VT,
835 {ISD::VP_REDUCE_AND, ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR}, VT,
859 ISD::VP_TRUNCATE, ISD::VP_SETCC},
876 for (
MVT VT : IntVecVTs) {
887 if (VT.getVectorElementType() == MVT::i64 && !Subtarget.hasStdExtV())
937 {ISD::VP_LOAD, ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
938 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER, ISD::VP_SCATTER},
963 if (Subtarget.hasStdExtZvkb()) {
971 if (Subtarget.hasStdExtZvbb()) {
975 ISD::VP_CTTZ_ZERO_UNDEF, ISD::VP_CTPOP},
981 ISD::VP_CTTZ_ZERO_UNDEF, ISD::VP_CTPOP},
990 ISD::VP_CTLZ_ZERO_UNDEF, ISD::VP_CTTZ_ZERO_UNDEF},
998 for (
MVT VT : VecTupleVTs) {
1019 static const unsigned ZvfhminZvfbfminPromoteOps[] = {
1047 ISD::VECREDUCE_FMIN,
1048 ISD::VECREDUCE_FMAX,
1049 ISD::VECREDUCE_FMINIMUM,
1050 ISD::VECREDUCE_FMAXIMUM};
1053 static const unsigned ZvfhminZvfbfminPromoteVPOps[] = {
1059 ISD::VP_REDUCE_FMIN,
1060 ISD::VP_REDUCE_FMAX,
1068 ISD::VP_FROUNDTOZERO,
1074 ISD::VP_REDUCE_FMINIMUM,
1075 ISD::VP_REDUCE_FMAXIMUM};
1078 const auto SetCommonVFPActions = [&](
MVT VT) {
1094 {ISD::FMINNUM, ISD::FMAXNUM, ISD::FMAXIMUMNUM, ISD::FMINIMUMNUM}, VT,
1099 ISD::FROUNDEVEN, ISD::FRINT, ISD::FNEARBYINT,
1116 {ISD::VP_LOAD, ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1117 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER, ISD::VP_SCATTER},
1153 const auto SetCommonVFPExtLoadTruncStoreActions =
1155 for (
auto SmallVT : SmallerVTs) {
1163 const auto SetCommonPromoteToF32Actions = [&](
MVT VT) {
1191 ISD::MGATHER, ISD::MSCATTER, ISD::VP_LOAD,
1192 ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1193 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER,
1218 const auto SetZvfbfaActions = [&](
MVT VT) {
1250 ISD::MGATHER, ISD::MSCATTER, ISD::VP_LOAD,
1251 ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1252 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER,
1271 if (Subtarget.hasVInstructionsF16()) {
1272 for (
MVT VT : F16VecVTs) {
1275 SetCommonVFPActions(VT);
1277 }
else if (Subtarget.hasVInstructionsF16Minimal()) {
1278 for (
MVT VT : F16VecVTs) {
1281 SetCommonPromoteToF32Actions(VT);
1285 if (Subtarget.hasVInstructionsBF16()) {
1286 for (
MVT VT : BF16VecVTs) {
1289 SetZvfbfaActions(VT);
1291 }
else if (Subtarget.hasVInstructionsBF16Minimal()) {
1292 for (
MVT VT : BF16VecVTs) {
1295 SetCommonPromoteToF32Actions(VT);
1299 if (Subtarget.hasVInstructionsF32()) {
1300 for (
MVT VT : F32VecVTs) {
1303 SetCommonVFPActions(VT);
1304 SetCommonVFPExtLoadTruncStoreActions(VT, F16VecVTs);
1305 SetCommonVFPExtLoadTruncStoreActions(VT, BF16VecVTs);
1309 if (Subtarget.hasVInstructionsF64()) {
1310 for (
MVT VT : F64VecVTs) {
1313 SetCommonVFPActions(VT);
1314 SetCommonVFPExtLoadTruncStoreActions(VT, F16VecVTs);
1315 SetCommonVFPExtLoadTruncStoreActions(VT, BF16VecVTs);
1316 SetCommonVFPExtLoadTruncStoreActions(VT, F32VecVTs);
1320 if (Subtarget.useRVVForFixedLengthVectors()) {
1322 if (!useRVVForFixedLengthVectorVT(VT))
1367 {ISD::VECREDUCE_AND, ISD::VECREDUCE_OR, ISD::VECREDUCE_XOR}, VT,
1371 {ISD::VP_REDUCE_AND, ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR}, VT,
1398 ISD::VP_SETCC, ISD::VP_TRUNCATE},
1422 {ISD::MLOAD, ISD::MSTORE, ISD::MGATHER, ISD::MSCATTER}, VT,
Custom);
1425 ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1426 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER,
1458 ISD::VECREDUCE_SMIN, ISD::VECREDUCE_UMAX,
1459 ISD::VECREDUCE_UMIN},
1464 if (Subtarget.hasStdExtZvkb())
1467 if (Subtarget.hasStdExtZvbb()) {
1491 if (!useRVVForFixedLengthVectorVT(VT))
1514 ISD::MGATHER, ISD::MSCATTER},
1517 ISD::VP_SCATTER, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1518 ISD::EXPERIMENTAL_VP_STRIDED_STORE},
1527 !Subtarget.hasVInstructionsF16()) {
1537 if (Subtarget.hasStdExtZfhmin()) {
1563 if (Subtarget.hasStdExtZfbfmin()) {
1570 if (Subtarget.hasStdExtZvfbfa()) {
1593 ISD::FMA, ISD::FMINNUM, ISD::FMAXNUM,
1595 ISD::FMAXIMUM, ISD::FMINIMUM},
1599 ISD::FROUNDEVEN, ISD::FRINT, ISD::LRINT,
1600 ISD::LLRINT, ISD::LROUND, ISD::LLROUND,
1626 if (Subtarget.is64Bit())
1628 if (Subtarget.hasStdExtZfhminOrZhinxmin())
1630 if (Subtarget.hasStdExtZfbfmin())
1632 if (Subtarget.hasStdExtFOrZfinx())
1634 if (Subtarget.hasStdExtDOrZdinx())
1639 if (Subtarget.hasStdExtZaamo())
1642 if (Subtarget.hasForcedAtomics()) {
1645 {ISD::ATOMIC_CMP_SWAP, ISD::ATOMIC_SWAP, ISD::ATOMIC_LOAD_ADD,
1646 ISD::ATOMIC_LOAD_SUB, ISD::ATOMIC_LOAD_AND, ISD::ATOMIC_LOAD_OR,
1647 ISD::ATOMIC_LOAD_XOR, ISD::ATOMIC_LOAD_NAND, ISD::ATOMIC_LOAD_MIN,
1648 ISD::ATOMIC_LOAD_MAX, ISD::ATOMIC_LOAD_UMIN, ISD::ATOMIC_LOAD_UMAX},
1652 if (Subtarget.hasVendorXTHeadMemIdx()) {
1661 if (Subtarget.is64Bit()) {
1668 if (Subtarget.hasVendorXCVmem() && !Subtarget.is64Bit()) {
1679 if (Subtarget.hasStdExtZvqdotq() && Subtarget.getELen() >= 64) {
1680 static const unsigned MLAOps[] = {ISD::PARTIAL_REDUCE_SMLA,
1681 ISD::PARTIAL_REDUCE_UMLA,
1682 ISD::PARTIAL_REDUCE_SUMLA};
1689 if (Subtarget.useRVVForFixedLengthVectors()) {
1691 if (VT.getVectorElementType() != MVT::i32 ||
1692 !useRVVForFixedLengthVectorVT(VT))
1702 if (Subtarget.hasVendorXAndesBFHCvt() && !Subtarget.hasStdExtZfh()) {
1708 const Align FunctionAlignment(Subtarget.hasStdExtZca() ? 2 : 4);
1720 if (Subtarget.hasStdExtFOrZfinx())
1723 if (Subtarget.hasStdExtZbb())
1726 if ((Subtarget.hasStdExtZbs() && Subtarget.is64Bit()) ||
1727 Subtarget.hasVInstructions())
1730 if (Subtarget.hasStdExtZbkb())
1733 if (Subtarget.hasStdExtFOrZfinx())
1736 if (Subtarget.hasVInstructions())
1739 ISD::VP_GATHER, ISD::VP_SCATTER,
ISD::SRA,
1742 ISD::VP_STORE, ISD::VP_TRUNCATE, ISD::EXPERIMENTAL_VP_REVERSE,
1748 if (Subtarget.hasVendorXTHeadMemPair())
1750 if (Subtarget.useRVVForFixedLengthVectors())
1772 Subtarget.getMaxStoresPerMemmove(
true);
1784 if (Subtarget.hasVInstructions() &&
1795bool RISCVTargetLowering::shouldExpandGetVectorLength(
EVT TripCountVT,
1797 bool IsScalable)
const {
1804 if (TripCountVT != MVT::i32 && TripCountVT != Subtarget.
getXLenVT())
1822 return !Subtarget.hasVInstructions() ||
1830 auto &
DL =
I.getDataLayout();
1832 auto SetRVVLoadStoreInfo = [&](
unsigned PtrOp,
bool IsStore,
1833 bool IsUnitStrided,
bool UsePtrVal =
false) {
1838 Info.ptrVal =
I.getArgOperand(PtrOp);
1840 Info.fallbackAddressSpace =
1841 I.getArgOperand(PtrOp)->getType()->getPointerAddressSpace();
1845 MemTy =
I.getArgOperand(0)->getType();
1848 MemTy =
I.getType();
1863 Info.align =
DL.getABITypeAlign(MemTy);
1873 if (
I.hasMetadata(LLVMContext::MD_nontemporal))
1880 case Intrinsic::riscv_masked_atomicrmw_xchg:
1881 case Intrinsic::riscv_masked_atomicrmw_add:
1882 case Intrinsic::riscv_masked_atomicrmw_sub:
1883 case Intrinsic::riscv_masked_atomicrmw_nand:
1884 case Intrinsic::riscv_masked_atomicrmw_max:
1885 case Intrinsic::riscv_masked_atomicrmw_min:
1886 case Intrinsic::riscv_masked_atomicrmw_umax:
1887 case Intrinsic::riscv_masked_atomicrmw_umin:
1888 case Intrinsic::riscv_masked_cmpxchg:
1895 Info.memVT = MVT::i32;
1896 Info.ptrVal =
I.getArgOperand(0);
1898 Info.align =
Align(4);
1902 case Intrinsic::riscv_seg2_load_mask:
1903 case Intrinsic::riscv_seg3_load_mask:
1904 case Intrinsic::riscv_seg4_load_mask:
1905 case Intrinsic::riscv_seg5_load_mask:
1906 case Intrinsic::riscv_seg6_load_mask:
1907 case Intrinsic::riscv_seg7_load_mask:
1908 case Intrinsic::riscv_seg8_load_mask:
1909 case Intrinsic::riscv_sseg2_load_mask:
1910 case Intrinsic::riscv_sseg3_load_mask:
1911 case Intrinsic::riscv_sseg4_load_mask:
1912 case Intrinsic::riscv_sseg5_load_mask:
1913 case Intrinsic::riscv_sseg6_load_mask:
1914 case Intrinsic::riscv_sseg7_load_mask:
1915 case Intrinsic::riscv_sseg8_load_mask:
1916 return SetRVVLoadStoreInfo( 0,
false,
1918 case Intrinsic::riscv_seg2_store_mask:
1919 case Intrinsic::riscv_seg3_store_mask:
1920 case Intrinsic::riscv_seg4_store_mask:
1921 case Intrinsic::riscv_seg5_store_mask:
1922 case Intrinsic::riscv_seg6_store_mask:
1923 case Intrinsic::riscv_seg7_store_mask:
1924 case Intrinsic::riscv_seg8_store_mask:
1926 return SetRVVLoadStoreInfo(
I.arg_size() - 3,
1929 case Intrinsic::riscv_sseg2_store_mask:
1930 case Intrinsic::riscv_sseg3_store_mask:
1931 case Intrinsic::riscv_sseg4_store_mask:
1932 case Intrinsic::riscv_sseg5_store_mask:
1933 case Intrinsic::riscv_sseg6_store_mask:
1934 case Intrinsic::riscv_sseg7_store_mask:
1935 case Intrinsic::riscv_sseg8_store_mask:
1937 return SetRVVLoadStoreInfo(
I.arg_size() - 4,
1940 case Intrinsic::riscv_vlm:
1941 return SetRVVLoadStoreInfo( 0,
1945 case Intrinsic::riscv_vle:
1946 case Intrinsic::riscv_vle_mask:
1947 case Intrinsic::riscv_vleff:
1948 case Intrinsic::riscv_vleff_mask:
1949 return SetRVVLoadStoreInfo( 1,
1953 case Intrinsic::riscv_vsm:
1954 case Intrinsic::riscv_vse:
1955 case Intrinsic::riscv_vse_mask:
1956 return SetRVVLoadStoreInfo( 1,
1960 case Intrinsic::riscv_vlse:
1961 case Intrinsic::riscv_vlse_mask:
1962 case Intrinsic::riscv_vloxei:
1963 case Intrinsic::riscv_vloxei_mask:
1964 case Intrinsic::riscv_vluxei:
1965 case Intrinsic::riscv_vluxei_mask:
1966 return SetRVVLoadStoreInfo( 1,
1969 case Intrinsic::riscv_vsse:
1970 case Intrinsic::riscv_vsse_mask:
1971 case Intrinsic::riscv_vsoxei:
1972 case Intrinsic::riscv_vsoxei_mask:
1973 case Intrinsic::riscv_vsuxei:
1974 case Intrinsic::riscv_vsuxei_mask:
1975 return SetRVVLoadStoreInfo( 1,
1978 case Intrinsic::riscv_vlseg2:
1979 case Intrinsic::riscv_vlseg3:
1980 case Intrinsic::riscv_vlseg4:
1981 case Intrinsic::riscv_vlseg5:
1982 case Intrinsic::riscv_vlseg6:
1983 case Intrinsic::riscv_vlseg7:
1984 case Intrinsic::riscv_vlseg8:
1985 case Intrinsic::riscv_vlseg2ff:
1986 case Intrinsic::riscv_vlseg3ff:
1987 case Intrinsic::riscv_vlseg4ff:
1988 case Intrinsic::riscv_vlseg5ff:
1989 case Intrinsic::riscv_vlseg6ff:
1990 case Intrinsic::riscv_vlseg7ff:
1991 case Intrinsic::riscv_vlseg8ff:
1992 return SetRVVLoadStoreInfo(
I.arg_size() - 3,
1995 case Intrinsic::riscv_vlseg2_mask:
1996 case Intrinsic::riscv_vlseg3_mask:
1997 case Intrinsic::riscv_vlseg4_mask:
1998 case Intrinsic::riscv_vlseg5_mask:
1999 case Intrinsic::riscv_vlseg6_mask:
2000 case Intrinsic::riscv_vlseg7_mask:
2001 case Intrinsic::riscv_vlseg8_mask:
2002 case Intrinsic::riscv_vlseg2ff_mask:
2003 case Intrinsic::riscv_vlseg3ff_mask:
2004 case Intrinsic::riscv_vlseg4ff_mask:
2005 case Intrinsic::riscv_vlseg5ff_mask:
2006 case Intrinsic::riscv_vlseg6ff_mask:
2007 case Intrinsic::riscv_vlseg7ff_mask:
2008 case Intrinsic::riscv_vlseg8ff_mask:
2009 return SetRVVLoadStoreInfo(
I.arg_size() - 5,
2012 case Intrinsic::riscv_vlsseg2:
2013 case Intrinsic::riscv_vlsseg3:
2014 case Intrinsic::riscv_vlsseg4:
2015 case Intrinsic::riscv_vlsseg5:
2016 case Intrinsic::riscv_vlsseg6:
2017 case Intrinsic::riscv_vlsseg7:
2018 case Intrinsic::riscv_vlsseg8:
2019 case Intrinsic::riscv_vloxseg2:
2020 case Intrinsic::riscv_vloxseg3:
2021 case Intrinsic::riscv_vloxseg4:
2022 case Intrinsic::riscv_vloxseg5:
2023 case Intrinsic::riscv_vloxseg6:
2024 case Intrinsic::riscv_vloxseg7:
2025 case Intrinsic::riscv_vloxseg8:
2026 case Intrinsic::riscv_vluxseg2:
2027 case Intrinsic::riscv_vluxseg3:
2028 case Intrinsic::riscv_vluxseg4:
2029 case Intrinsic::riscv_vluxseg5:
2030 case Intrinsic::riscv_vluxseg6:
2031 case Intrinsic::riscv_vluxseg7:
2032 case Intrinsic::riscv_vluxseg8:
2033 return SetRVVLoadStoreInfo(
I.arg_size() - 4,
2036 case Intrinsic::riscv_vlsseg2_mask:
2037 case Intrinsic::riscv_vlsseg3_mask:
2038 case Intrinsic::riscv_vlsseg4_mask:
2039 case Intrinsic::riscv_vlsseg5_mask:
2040 case Intrinsic::riscv_vlsseg6_mask:
2041 case Intrinsic::riscv_vlsseg7_mask:
2042 case Intrinsic::riscv_vlsseg8_mask:
2043 case Intrinsic::riscv_vloxseg2_mask:
2044 case Intrinsic::riscv_vloxseg3_mask:
2045 case Intrinsic::riscv_vloxseg4_mask:
2046 case Intrinsic::riscv_vloxseg5_mask:
2047 case Intrinsic::riscv_vloxseg6_mask:
2048 case Intrinsic::riscv_vloxseg7_mask:
2049 case Intrinsic::riscv_vloxseg8_mask:
2050 case Intrinsic::riscv_vluxseg2_mask:
2051 case Intrinsic::riscv_vluxseg3_mask:
2052 case Intrinsic::riscv_vluxseg4_mask:
2053 case Intrinsic::riscv_vluxseg5_mask:
2054 case Intrinsic::riscv_vluxseg6_mask:
2055 case Intrinsic::riscv_vluxseg7_mask:
2056 case Intrinsic::riscv_vluxseg8_mask:
2057 return SetRVVLoadStoreInfo(
I.arg_size() - 6,
2060 case Intrinsic::riscv_vsseg2:
2061 case Intrinsic::riscv_vsseg3:
2062 case Intrinsic::riscv_vsseg4:
2063 case Intrinsic::riscv_vsseg5:
2064 case Intrinsic::riscv_vsseg6:
2065 case Intrinsic::riscv_vsseg7:
2066 case Intrinsic::riscv_vsseg8:
2067 return SetRVVLoadStoreInfo(
I.arg_size() - 3,
2070 case Intrinsic::riscv_vsseg2_mask:
2071 case Intrinsic::riscv_vsseg3_mask:
2072 case Intrinsic::riscv_vsseg4_mask:
2073 case Intrinsic::riscv_vsseg5_mask:
2074 case Intrinsic::riscv_vsseg6_mask:
2075 case Intrinsic::riscv_vsseg7_mask:
2076 case Intrinsic::riscv_vsseg8_mask:
2077 return SetRVVLoadStoreInfo(
I.arg_size() - 4,
2080 case Intrinsic::riscv_vssseg2:
2081 case Intrinsic::riscv_vssseg3:
2082 case Intrinsic::riscv_vssseg4:
2083 case Intrinsic::riscv_vssseg5:
2084 case Intrinsic::riscv_vssseg6:
2085 case Intrinsic::riscv_vssseg7:
2086 case Intrinsic::riscv_vssseg8:
2087 case Intrinsic::riscv_vsoxseg2:
2088 case Intrinsic::riscv_vsoxseg3:
2089 case Intrinsic::riscv_vsoxseg4:
2090 case Intrinsic::riscv_vsoxseg5:
2091 case Intrinsic::riscv_vsoxseg6:
2092 case Intrinsic::riscv_vsoxseg7:
2093 case Intrinsic::riscv_vsoxseg8:
2094 case Intrinsic::riscv_vsuxseg2:
2095 case Intrinsic::riscv_vsuxseg3:
2096 case Intrinsic::riscv_vsuxseg4:
2097 case Intrinsic::riscv_vsuxseg5:
2098 case Intrinsic::riscv_vsuxseg6:
2099 case Intrinsic::riscv_vsuxseg7:
2100 case Intrinsic::riscv_vsuxseg8:
2101 return SetRVVLoadStoreInfo(
I.arg_size() - 4,
2104 case Intrinsic::riscv_vssseg2_mask:
2105 case Intrinsic::riscv_vssseg3_mask:
2106 case Intrinsic::riscv_vssseg4_mask:
2107 case Intrinsic::riscv_vssseg5_mask:
2108 case Intrinsic::riscv_vssseg6_mask:
2109 case Intrinsic::riscv_vssseg7_mask:
2110 case Intrinsic::riscv_vssseg8_mask:
2111 case Intrinsic::riscv_vsoxseg2_mask:
2112 case Intrinsic::riscv_vsoxseg3_mask:
2113 case Intrinsic::riscv_vsoxseg4_mask:
2114 case Intrinsic::riscv_vsoxseg5_mask:
2115 case Intrinsic::riscv_vsoxseg6_mask:
2116 case Intrinsic::riscv_vsoxseg7_mask:
2117 case Intrinsic::riscv_vsoxseg8_mask:
2118 case Intrinsic::riscv_vsuxseg2_mask:
2119 case Intrinsic::riscv_vsuxseg3_mask:
2120 case Intrinsic::riscv_vsuxseg4_mask:
2121 case Intrinsic::riscv_vsuxseg5_mask:
2122 case Intrinsic::riscv_vsuxseg6_mask:
2123 case Intrinsic::riscv_vsuxseg7_mask:
2124 case Intrinsic::riscv_vsuxseg8_mask:
2125 return SetRVVLoadStoreInfo(
I.arg_size() - 5,
2179 if (Subtarget.is64Bit() || !SrcTy->isIntegerTy() || !DstTy->
isIntegerTy())
2181 unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();
2183 return (SrcBits == 64 && DestBits == 32);
2194 return (SrcBits == 64 && DestBits == 32);
2200 if (Subtarget.hasVInstructions() &&
2205 if (SrcBits == DestBits * 2) {
2217 EVT MemVT = LD->getMemoryVT();
2218 if ((MemVT == MVT::i8 || MemVT == MVT::i16) &&
2228 return Subtarget.is64Bit() && SrcVT == MVT::i32 && DstVT == MVT::i64;
2236 return Subtarget.hasCTZLike();
2240 return Subtarget.hasCLZLike();
2251 if (!Subtarget.hasBEXTILike())
2256 return !Mask->getValue().isSignedIntN(12) && Mask->getValue().isPowerOf2();
2260 EVT VT =
Y.getValueType();
2265 return (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) &&
2270 EVT VT =
Y.getValueType();
2275 return Subtarget.hasStdExtZvkb();
2280 if (Subtarget.hasStdExtZbs())
2281 return X.getValueType().isScalarInteger();
2284 if (Subtarget.hasVendorXTHeadBs())
2285 return C !=
nullptr;
2287 return C &&
C->getAPIntValue().ule(10);
2291 unsigned BinOpcode,
EVT VT,
unsigned SelectOpcode,
SDValue X,
2297 if (!VT.
isVector() || !Subtarget.hasVInstructions())
2308 assert(Ty->isIntegerTy());
2310 unsigned BitSize = Ty->getIntegerBitWidth();
2311 if (BitSize > Subtarget.getXLen())
2315 int64_t Val = Imm.getSExtValue();
2323 if (!Subtarget.enableUnalignedScalarMem())
2333 return Seq.
size() <= Subtarget.getMaxBuildIntsCost();
2339 unsigned OldShiftOpcode,
unsigned NewShiftOpcode,
2346 if (XC && OldShiftOpcode ==
ISD::SRL && XC->isOne())
2394 if (!Subtarget.hasStdExtZfa())
2397 bool IsSupportedVT =
false;
2398 if (VT == MVT::f16) {
2399 IsSupportedVT = Subtarget.hasStdExtZfh() || Subtarget.hasStdExtZvfh();
2400 }
else if (VT == MVT::f32) {
2401 IsSupportedVT =
true;
2402 }
else if (VT == MVT::f64) {
2403 assert(Subtarget.hasStdExtD() &&
"Expect D extension");
2404 IsSupportedVT =
true;
2414 bool ForCodeSize)
const {
2415 bool IsLegalVT =
false;
2417 IsLegalVT = Subtarget.hasStdExtZfhminOrZhinxmin();
2418 else if (VT == MVT::f32)
2419 IsLegalVT = Subtarget.hasStdExtFOrZfinx();
2420 else if (VT == MVT::f64)
2421 IsLegalVT = Subtarget.hasStdExtDOrZdinx();
2422 else if (VT == MVT::bf16)
2423 IsLegalVT = Subtarget.hasStdExtZfbfmin();
2439 return Imm.isZero();
2443 if (Imm.isNegZero())
2448 const int FmvCost = Subtarget.hasStdExtZfinx() ? 0 : 1;
2451 Subtarget.getXLen(), Subtarget);
2457 unsigned Index)
const {
2474 if (EltVT == MVT::i1)
2480 unsigned MinVLen = Subtarget.getRealMinVLen();
2487 if (Index + ResElts <= MinVLMAX && Index < 31)
2496 return (ResElts * 2) == SrcElts && (Index == 0 || Index == ResElts);
2504 if (VT == MVT::f16 && Subtarget.hasStdExtFOrZfinx() &&
2505 !Subtarget.hasStdExtZfhminOrZhinxmin())
2515 std::optional<MVT> RegisterVT)
const {
2517 if (VT == (Subtarget.is64Bit() ? MVT::i128 : MVT::i64) && RegisterVT &&
2518 *RegisterVT == MVT::Untyped)
2529 if (VT == MVT::f16 && Subtarget.hasStdExtFOrZfinx() &&
2530 !Subtarget.hasStdExtZfhminOrZhinxmin())
2538 unsigned &NumIntermediates,
MVT &RegisterVT)
const {
2540 Context, CC, VT, IntermediateVT, NumIntermediates, RegisterVT);
2558 !Subtarget.hasVendorXAndesPerf()) {
2564 ShAmt =
LHS.getValueSizeInBits() - 1 -
Log2_64(Mask);
2578 int64_t
C = RHSC->getSExtValue();
2588 if ((Subtarget.hasVendorXqcicm() || Subtarget.hasVendorXqcicli()) &&
2614 if ((Subtarget.hasVendorXqcicm() || Subtarget.hasVendorXqcicli()) &&
2649 if (VT.
SimpleTy >= MVT::riscv_nxv1i8x2 &&
2650 VT.
SimpleTy <= MVT::riscv_nxv1i8x8)
2652 if (VT.
SimpleTy >= MVT::riscv_nxv2i8x2 &&
2653 VT.
SimpleTy <= MVT::riscv_nxv2i8x8)
2655 if (VT.
SimpleTy >= MVT::riscv_nxv4i8x2 &&
2656 VT.
SimpleTy <= MVT::riscv_nxv4i8x8)
2658 if (VT.
SimpleTy >= MVT::riscv_nxv8i8x2 &&
2659 VT.
SimpleTy <= MVT::riscv_nxv8i8x8)
2661 if (VT.
SimpleTy >= MVT::riscv_nxv16i8x2 &&
2662 VT.
SimpleTy <= MVT::riscv_nxv16i8x4)
2664 if (VT.
SimpleTy == MVT::riscv_nxv32i8x2)
2674 switch (KnownSize) {
2702 return RISCV::VRRegClassID;
2704 return RISCV::VRM2RegClassID;
2706 return RISCV::VRM4RegClassID;
2708 return RISCV::VRM8RegClassID;
2716 static_assert(RISCV::sub_vrm1_7 == RISCV::sub_vrm1_0 + 7,
2717 "Unexpected subreg numbering");
2718 return RISCV::sub_vrm1_0 + Index;
2721 static_assert(RISCV::sub_vrm2_3 == RISCV::sub_vrm2_0 + 3,
2722 "Unexpected subreg numbering");
2723 return RISCV::sub_vrm2_0 + Index;
2726 static_assert(RISCV::sub_vrm4_1 == RISCV::sub_vrm4_0 + 1,
2727 "Unexpected subreg numbering");
2728 return RISCV::sub_vrm4_0 + Index;
2736 unsigned RegsPerField =
2739 switch (RegsPerField) {
2742 return RISCV::VRN2M1RegClassID;
2744 return RISCV::VRN3M1RegClassID;
2746 return RISCV::VRN4M1RegClassID;
2748 return RISCV::VRN5M1RegClassID;
2750 return RISCV::VRN6M1RegClassID;
2752 return RISCV::VRN7M1RegClassID;
2754 return RISCV::VRN8M1RegClassID;
2758 return RISCV::VRN2M2RegClassID;
2760 return RISCV::VRN3M2RegClassID;
2762 return RISCV::VRN4M2RegClassID;
2766 return RISCV::VRN2M4RegClassID;
2774 return RISCV::VRRegClassID;
2783std::pair<unsigned, unsigned>
2785 MVT VecVT,
MVT SubVecVT,
unsigned InsertExtractIdx,
2787 static_assert((RISCV::VRM8RegClassID > RISCV::VRM4RegClassID &&
2788 RISCV::VRM4RegClassID > RISCV::VRM2RegClassID &&
2789 RISCV::VRM2RegClassID > RISCV::VRRegClassID),
2790 "Register classes not ordered");
2797 if (VecRegClassID == SubRegClassID)
2798 return {RISCV::NoSubRegister, 0};
2801 "Only allow scalable vector subvector.");
2803 "Invalid vector tuple insert/extract for vector and subvector with "
2814 unsigned SubRegIdx = RISCV::NoSubRegister;
2815 for (
const unsigned RCID :
2816 {RISCV::VRM4RegClassID, RISCV::VRM2RegClassID, RISCV::VRRegClassID})
2817 if (VecRegClassID > RCID && SubRegClassID <= RCID) {
2821 SubRegIdx =
TRI->composeSubRegIndices(SubRegIdx,
2826 return {SubRegIdx, InsertExtractIdx};
2831bool RISCVTargetLowering::mergeStoresAfterLegalization(
EVT VT)
const {
2841 return Subtarget.is64Bit() ? Subtarget.hasVInstructionsI64() :
true;
2845 return Subtarget.hasVInstructions();
2847 return Subtarget.hasVInstructionsI64();
2849 return Subtarget.hasVInstructionsF16Minimal();
2851 return Subtarget.hasVInstructionsBF16Minimal();
2853 return Subtarget.hasVInstructionsF32();
2855 return Subtarget.hasVInstructionsF64();
2869 "Unexpected opcode");
2871 unsigned IntNo =
Op.getConstantOperandVal(HasChain ? 1 : 0);
2873 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo);
2876 return Op.getOperand(
II->VLOperand + 1 + HasChain);
2950bool RISCVTargetLowering::useRVVForFixedLengthVectorVT(
MVT VT)
const {
2951 return ::useRVVForFixedLengthVectorVT(VT, Subtarget);
2960 "Expected legal fixed length vector!");
2963 unsigned MaxELen = Subtarget.
getELen();
2997 return ::getContainerForFixedLengthVector(*
this, VT,
getSubtarget());
3004 "Expected to convert into a scalable vector!");
3005 assert(V.getValueType().isFixedLengthVector() &&
3006 "Expected a fixed length vector operand!");
3015 "Expected to convert into a fixed length vector!");
3016 assert(V.getValueType().isScalableVector() &&
3017 "Expected a scalable vector operand!");
3036 return DAG.
getNode(RISCVISD::VMSET_VL,
DL, MaskVT, VL);
3039static std::pair<SDValue, SDValue>
3048static std::pair<SDValue, SDValue>
3061static std::pair<SDValue, SDValue>
3078std::pair<unsigned, unsigned>
3086 unsigned VectorBitsMax = Subtarget.getRealMaxVLen();
3090 unsigned VectorBitsMin = Subtarget.getRealMinVLen();
3094 return std::make_pair(MinVLMAX, MaxVLMAX);
3106 EVT VT,
unsigned DefinedValues)
const {
3115 unsigned DLenFactor = Subtarget.getDLenFactor();
3120 std::tie(LMul, Fractional) =
3123 Cost = LMul <= DLenFactor ? (DLenFactor / LMul) : 1;
3125 Cost = (LMul * DLenFactor);
3139 bool Log2CostModel =
3141 if (Log2CostModel && LMULCost.isValid()) {
3142 unsigned Log =
Log2_64(LMULCost.getValue());
3144 return LMULCost * Log;
3146 return LMULCost * LMULCost;
3177 Op.getValueType() == MVT::bf16) {
3178 bool IsStrict =
Op->isStrictFPOpcode();
3183 {Op.getOperand(0), Op.getOperand(1)});
3185 {
Op.getValueType(), MVT::Other},
3191 DAG.
getNode(
Op.getOpcode(),
DL, MVT::f32,
Op.getOperand(0)),
3206 MVT DstVT =
Op.getSimpleValueType();
3215 Src.getValueType() == MVT::bf16) {
3221 Opc = IsSigned ? RISCVISD::FCVT_X : RISCVISD::FCVT_XU;
3222 else if (DstVT == MVT::i64 && SatVT == MVT::i32)
3223 Opc = IsSigned ? RISCVISD::FCVT_W_RV64 : RISCVISD::FCVT_WU_RV64;
3230 Opc,
DL, DstVT, Src,
3233 if (
Opc == RISCVISD::FCVT_WU_RV64)
3244 MVT SrcVT = Src.getSimpleValueType();
3250 if (SatVT != DstEltVT)
3253 MVT DstContainerVT = DstVT;
3254 MVT SrcContainerVT = SrcVT;
3260 "Expected same element count");
3269 {Src, Src, DAG.getCondCode(ISD::SETNE),
3270 DAG.getUNDEF(Mask.getValueType()), Mask, VL});
3274 if (DstEltSize > (2 * SrcEltSize)) {
3277 Src = DAG.
getNode(RISCVISD::FP_EXTEND_VL,
DL, InterVT, Src, Mask, VL);
3280 MVT CvtContainerVT = DstContainerVT;
3281 MVT CvtEltVT = DstEltVT;
3282 if (SrcEltSize > (2 * DstEltSize)) {
3288 IsSigned ? RISCVISD::VFCVT_RTZ_X_F_VL : RISCVISD::VFCVT_RTZ_XU_F_VL;
3291 while (CvtContainerVT != DstContainerVT) {
3295 unsigned ClipOpc = IsSigned ? RISCVISD::TRUNCATE_VECTOR_VL_SSAT
3296 : RISCVISD::TRUNCATE_VECTOR_VL_USAT;
3297 Res = DAG.
getNode(ClipOpc,
DL, CvtContainerVT, Res, Mask, VL);
3301 RISCVISD::VMV_V_X_VL,
DL, DstContainerVT, DAG.
getUNDEF(DstContainerVT),
3303 Res = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, DstContainerVT, IsNan, SplatZero,
3304 Res, DAG.
getUNDEF(DstContainerVT), VL);
3314 bool IsStrict =
Op->isStrictFPOpcode();
3315 SDValue SrcVal =
Op.getOperand(IsStrict ? 1 : 0);
3325 {
Op.getOperand(0), SrcVal});
3326 return DAG.
getNode(
Op.getOpcode(),
DL, {Op.getValueType(), MVT::Other},
3327 {Ext.getValue(1), Ext.getValue(0)});
3330 DAG.
getNode(ISD::FP_EXTEND,
DL, MVT::f32, SrcVal));
3339 case ISD::FROUNDEVEN:
3341 case ISD::VP_FROUNDEVEN:
3345 case ISD::VP_FROUNDTOZERO:
3349 case ISD::VP_FFLOOR:
3361 case ISD::VP_FROUND:
3371 case ISD::VP_LLRINT:
3385 MVT VT =
Op.getSimpleValueType();
3395 MVT ContainerVT = VT;
3402 if (
Op->isVPOpcode()) {
3403 Mask =
Op.getOperand(1);
3407 VL =
Op.getOperand(2);
3413 SDValue Abs = DAG.
getNode(RISCVISD::FABS_VL,
DL, ContainerVT, Src, Mask, VL);
3426 DAG.
getUNDEF(ContainerVT), MaxValNode, VL);
3431 DAG.
getNode(RISCVISD::SETCC_VL,
DL, SetccVT,
3440 switch (
Op.getOpcode()) {
3448 case ISD::VP_FFLOOR:
3450 case ISD::FROUNDEVEN:
3451 case ISD::VP_FROUND:
3452 case ISD::VP_FROUNDEVEN:
3453 case ISD::VP_FROUNDTOZERO: {
3456 Truncated = DAG.
getNode(RISCVISD::VFCVT_RM_X_F_VL,
DL, IntVT, Src, Mask,
3461 Truncated = DAG.
getNode(RISCVISD::VFCVT_RTZ_X_F_VL,
DL, IntVT, Src,
3464 case ISD::FNEARBYINT:
3465 case ISD::VP_FNEARBYINT:
3466 Truncated = DAG.
getNode(RISCVISD::VFROUND_NOEXCEPT_VL,
DL, ContainerVT, Src,
3472 if (Truncated.
getOpcode() != RISCVISD::VFROUND_NOEXCEPT_VL)
3473 Truncated = DAG.
getNode(RISCVISD::SINT_TO_FP_VL,
DL, ContainerVT, Truncated,
3477 Truncated = DAG.
getNode(RISCVISD::FCOPYSIGN_VL,
DL, ContainerVT, Truncated,
3478 Src, Src, Mask, VL);
3493 MVT VT =
Op.getSimpleValueType();
3497 MVT ContainerVT = VT;
3509 MVT MaskVT = Mask.getSimpleValueType();
3512 {Chain, Src, Src, DAG.getCondCode(ISD::SETUNE),
3513 DAG.getUNDEF(MaskVT), Mask, VL});
3515 Src = DAG.
getNode(RISCVISD::STRICT_FADD_VL,
DL,
3517 {Chain, Src, Src, Src, Unorder, VL});
3521 SDValue Abs = DAG.
getNode(RISCVISD::FABS_VL,
DL, ContainerVT, Src, Mask, VL);
3534 DAG.
getUNDEF(ContainerVT), MaxValNode, VL);
3538 RISCVISD::SETCC_VL,
DL, MaskVT,
3546 switch (
Op.getOpcode()) {
3556 RISCVISD::STRICT_VFCVT_RM_X_F_VL,
DL, DAG.
getVTList(IntVT, MVT::Other),
3557 {Chain, Src, Mask, DAG.getTargetConstant(FRM, DL, XLenVT), VL});
3562 DAG.
getNode(RISCVISD::STRICT_VFCVT_RTZ_X_F_VL,
DL,
3563 DAG.
getVTList(IntVT, MVT::Other), Chain, Src, Mask, VL);
3566 Truncated = DAG.
getNode(RISCVISD::STRICT_VFROUND_NOEXCEPT_VL,
DL,
3567 DAG.
getVTList(ContainerVT, MVT::Other), Chain, Src,
3575 Truncated = DAG.
getNode(RISCVISD::STRICT_SINT_TO_FP_VL,
DL,
3576 DAG.
getVTList(ContainerVT, MVT::Other), Chain,
3577 Truncated, Mask, VL);
3582 Truncated = DAG.
getNode(RISCVISD::FCOPYSIGN_VL,
DL, ContainerVT, Truncated,
3583 Src, Src, Mask, VL);
3593 MVT VT =
Op.getSimpleValueType();
3614 return DAG.
getNode(RISCVISD::FROUND,
DL, VT, Src, MaxValNode,
3622 MVT DstVT =
Op.getSimpleValueType();
3624 MVT SrcVT = Src.getSimpleValueType();
3629 MVT DstContainerVT = DstVT;
3630 MVT SrcContainerVT = SrcVT;
3642 if (SrcElemType == MVT::f16 || SrcElemType == MVT::bf16) {
3644 Src = DAG.
getNode(RISCVISD::FP_EXTEND_VL,
DL, F32VT, Src, Mask, VL);
3648 DAG.
getNode(RISCVISD::VFCVT_RM_X_F_VL,
DL, DstContainerVT, Src, Mask,
3668 return DAG.
getNode(RISCVISD::VSLIDEDOWN_VL,
DL, VT,
Ops);
3680 return DAG.
getNode(RISCVISD::VSLIDEUP_VL,
DL, VT,
Ops);
3705 return std::nullopt;
3723 unsigned EltSizeInBits) {
3726 return std::nullopt;
3727 bool IsInteger =
Op.getValueType().isInteger();
3729 std::optional<unsigned> SeqStepDenom;
3730 std::optional<APInt> SeqStepNum;
3731 std::optional<APInt> SeqAddend;
3732 std::optional<std::pair<APInt, unsigned>> PrevElt;
3733 assert(EltSizeInBits >=
Op.getValueType().getScalarSizeInBits());
3738 const unsigned OpSize =
Op.getScalarValueSizeInBits();
3739 for (
auto [Idx, Elt] :
enumerate(
Op->op_values())) {
3740 if (Elt.isUndef()) {
3741 Elts[Idx] = std::nullopt;
3745 Elts[Idx] = Elt->getAsAPIntVal().trunc(OpSize).zext(EltSizeInBits);
3750 return std::nullopt;
3751 Elts[Idx] = *ExactInteger;
3755 for (
auto [Idx, Elt] :
enumerate(Elts)) {
3764 unsigned IdxDiff = Idx - PrevElt->second;
3765 APInt ValDiff = *Elt - PrevElt->first;
3773 int64_t Remainder = ValDiff.
srem(IdxDiff);
3778 return std::nullopt;
3779 ValDiff = ValDiff.
sdiv(IdxDiff);
3784 SeqStepNum = ValDiff;
3785 else if (ValDiff != SeqStepNum)
3786 return std::nullopt;
3789 SeqStepDenom = IdxDiff;
3790 else if (IdxDiff != *SeqStepDenom)
3791 return std::nullopt;
3795 if (!PrevElt || PrevElt->first != *Elt)
3796 PrevElt = std::make_pair(*Elt, Idx);
3800 if (!SeqStepNum || !SeqStepDenom)
3801 return std::nullopt;
3805 for (
auto [Idx, Elt] :
enumerate(Elts)) {
3809 (
APInt(EltSizeInBits, Idx,
false,
true) *
3811 .sdiv(*SeqStepDenom);
3813 APInt Addend = *Elt - ExpectedVal;
3816 else if (Addend != SeqAddend)
3817 return std::nullopt;
3820 assert(SeqAddend &&
"Must have an addend if we have a step");
3822 return VIDSequence{SeqStepNum->getSExtValue(), *SeqStepDenom,
3823 SeqAddend->getSExtValue()};
3838 if (EltTy == MVT::i1 ||
3841 MVT SrcVT = Src.getSimpleValueType();
3857 MVT ContainerVT = VT;
3861 MVT SrcContainerVT = SrcVT;
3876 SDValue Gather = DAG.
getNode(RISCVISD::VRGATHER_VX_VL,
DL, ContainerVT, Src,
3877 Idx, DAG.
getUNDEF(ContainerVT), Mask, VL);
3885 MVT VT =
Op.getSimpleValueType();
3894 int64_t StepNumerator = SimpleVID->StepNumerator;
3895 unsigned StepDenominator = SimpleVID->StepDenominator;
3896 int64_t Addend = SimpleVID->Addend;
3898 assert(StepNumerator != 0 &&
"Invalid step");
3899 bool Negate =
false;
3900 int64_t SplatStepVal = StepNumerator;
3904 if (StepNumerator != 1 && StepNumerator !=
INT64_MIN &&
3906 Negate = StepNumerator < 0;
3908 SplatStepVal =
Log2_64(std::abs(StepNumerator));
3918 (SplatStepVal >= 0 || StepDenominator == 1) &&
isInt<32>(Addend)) {
3921 MVT VIDContainerVT =
3929 if ((StepOpcode ==
ISD::MUL && SplatStepVal != 1) ||
3930 (StepOpcode ==
ISD::SHL && SplatStepVal != 0)) {
3932 VID = DAG.
getNode(StepOpcode,
DL, VIDVT, VID, SplatStep);
3934 if (StepDenominator != 1) {
3939 if (Addend != 0 || Negate) {
3965 MVT VT =
Op.getSimpleValueType();
3974 unsigned NumElts =
Op.getNumOperands();
3977 unsigned MostCommonCount = 0;
3979 unsigned NumUndefElts =
3987 unsigned NumScalarLoads = 0;
3993 unsigned &
Count = ValueCounts[V];
3996 NumScalarLoads += !CFP->isExactlyValue(+0.0);
4001 if (++
Count >= MostCommonCount) {
4003 MostCommonCount =
Count;
4007 assert(DominantValue &&
"Not expecting an all-undef BUILD_VECTOR");
4008 unsigned NumDefElts = NumElts - NumUndefElts;
4009 unsigned DominantValueCountThreshold = NumDefElts <= 2 ? 0 : NumDefElts - 2;
4015 ((MostCommonCount > DominantValueCountThreshold) ||
4027 if (
SDValue LastOp =
Op->getOperand(
Op->getNumOperands() - 1);
4028 !LastOp.isUndef() && ValueCounts[LastOp] == 1 &&
4029 LastOp != DominantValue) {
4032 VT.
isFloatingPoint() ? RISCVISD::VFSLIDE1DOWN_VL : RISCVISD::VSLIDE1DOWN_VL;
4038 Processed.
insert(LastOp);
4044 if (V.isUndef() || !Processed.
insert(V).second)
4046 if (ValueCounts[V] == 1) {
4054 return DAG.getConstant(V == V1, DL, XLenVT);
4070 MVT VT =
Op.getSimpleValueType();
4079 unsigned NumElts =
Op.getNumOperands();
4100 unsigned NumViaIntegerBits = std::clamp(NumElts, 8u, Subtarget.
getXLen());
4101 NumViaIntegerBits = std::min(NumViaIntegerBits, Subtarget.
getELen());
4109 unsigned IntegerViaVecElts =
divideCeil(NumElts, NumViaIntegerBits);
4110 MVT IntegerViaVecVT =
4115 unsigned BitPos = 0, IntegerEltIdx = 0;
4118 for (
unsigned I = 0;
I < NumElts;) {
4120 bool BitValue = !V.isUndef() && V->getAsZExtVal();
4121 Bits |= ((
uint64_t)BitValue << BitPos);
4127 if (
I % NumViaIntegerBits == 0 ||
I == NumElts) {
4128 if (NumViaIntegerBits <= 32)
4131 Elts[IntegerEltIdx] = Elt;
4140 if (NumElts < NumViaIntegerBits) {
4144 assert(IntegerViaVecVT == MVT::v1i8 &&
"Unexpected mask vector type");
4159 : RISCVISD::VMV_V_X_VL;
4179 assert((ViaIntVT == MVT::i16 || ViaIntVT == MVT::i32) &&
4180 "Unexpected sequence type");
4184 unsigned ViaVecLen =
4192 const auto &SeqV =
OpIdx.value();
4193 if (!SeqV.isUndef())
4195 ((SeqV->getAsZExtVal() & EltMask) << (
OpIdx.index() * EltBitSize));
4201 if (ViaIntVT == MVT::i32)
4224 BV->getRepeatedSequence(Sequence) &&
4225 (Sequence.size() * EltBitSize) <= Subtarget.
getELen()) {
4226 unsigned SeqLen = Sequence.size();
4228 assert((ViaIntVT == MVT::i16 || ViaIntVT == MVT::i32 ||
4229 ViaIntVT == MVT::i64) &&
4230 "Unexpected sequence type");
4235 const unsigned RequiredVL = NumElts / SeqLen;
4236 const unsigned ViaVecLen =
4238 NumElts : RequiredVL;
4241 unsigned EltIdx = 0;
4246 for (
const auto &SeqV : Sequence) {
4247 if (!SeqV.isUndef())
4249 ((SeqV->getAsZExtVal() & EltMask) << (EltIdx * EltBitSize));
4256 if (ViaIntVT == MVT::i32)
4263 (!Subtarget.
is64Bit() && ViaIntVT == MVT::i64)) &&
4264 "Unexpected bitcast sequence");
4268 MVT ViaContainerVT =
4271 DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ViaContainerVT,
4275 if (ViaVecLen != RequiredVL)
4294 Source, DAG, Subtarget);
4295 SDValue Res = DAG.
getNode(RISCVISD::VSEXT_VL,
DL, ContainerVT, Source, Mask, VL);
4314 return RISCV::PACKH;
4316 return Subtarget.
is64Bit() ? RISCV::PACKW : RISCV::PACK;
4331 MVT VT =
Op.getSimpleValueType();
4339 if (!Subtarget.hasStdExtZbb() || !Subtarget.hasStdExtZba())
4344 if (ElemSizeInBits >= std::min(Subtarget.
getELen(), Subtarget.
getXLen()) ||
4358 if (Subtarget.hasStdExtZbkb())
4363 ElemDL, XLenVT,
A,
B),
4375 NewOperands.
reserve(NumElts / 2);
4377 NewOperands.
push_back(pack(
Op.getOperand(i),
Op.getOperand(i + 1)));
4381 return DAG.
getNode(ISD::BITCAST,
DL, VT,
4387 MVT VT =
Op.getSimpleValueType();
4398 if ((EltVT == MVT::f16 && !Subtarget.hasStdExtZvfh()) || EltVT == MVT::bf16) {
4403 if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
4404 (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin())) {
4414 NewOps[
I] = DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT, Elem);
4464 [](
const SDUse &U) { return U.get().isUndef(); })) {
4505 auto OneVRegOfOps =
ArrayRef(BuildVectorOps).slice(i, ElemsPerVReg);
4509 unsigned InsertIdx = (i / ElemsPerVReg) * NumOpElts;
4531 unsigned NumUndefElts =
4533 unsigned NumDefElts = NumElts - NumUndefElts;
4534 if (NumDefElts >= 8 && NumDefElts > NumElts / 2 &&
4541 for (
const auto &[Idx, U] :
enumerate(
Op->ops())) {
4543 if (Idx < NumElts / 2) {
4550 bool SelectMaskVal = (Idx < NumElts / 2);
4553 assert(SubVecAOps.
size() == NumElts && SubVecBOps.
size() == NumElts &&
4554 MaskVals.
size() == NumElts);
4589 unsigned UndefCount = 0;
4596 LinearBudget -= PerSlideCost;
4599 LinearBudget -= PerSlideCost;
4602 LinearBudget -= PerSlideCost;
4605 if (LinearBudget < 0)
4610 "Illegal type which will result in reserved encoding");
4626 bool SlideUp =
false;
4651 if (EVecEltVT != ContainerEltVT)
4672 std::reverse(Operands.
begin(), Operands.
end());
4700 Vec = getVSlide(ContainerVT, DAG.
getUNDEF(ContainerVT), Vec,
Offset, Mask,
4707 Opcode = SlideUp ? RISCVISD::VFSLIDE1UP_VL : RISCVISD::VFSLIDE1DOWN_VL;
4709 Opcode = SlideUp ? RISCVISD::VSLIDE1UP_VL : RISCVISD::VSLIDE1DOWN_VL;
4718 Vec = getVSlide(ContainerVT, DAG.
getUNDEF(ContainerVT), Vec,
Offset, Mask,
4734 if ((LoC >> 31) == HiC)
4735 return DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, VT, Passthru,
Lo, VL);
4747 auto InterVec = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, InterVT,
4749 return DAG.
getNode(ISD::BITCAST,
DL, VT, InterVec);
4756 Hi.getConstantOperandVal(1) == 31)
4757 return DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, VT, Passthru,
Lo, VL);
4762 return DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, VT, Passthru,
Lo, VL);
4765 return DAG.
getNode(RISCVISD::SPLAT_VECTOR_SPLIT_I64_VL,
DL, VT, Passthru,
Lo,
4775 assert(Scalar.getValueType() == MVT::i64 &&
"Unexpected VT!");
4787 bool HasPassthru = Passthru && !Passthru.
isUndef();
4788 if (!HasPassthru && !Passthru)
4795 if ((EltVT == MVT::f16 && !Subtarget.hasStdExtZvfh()) ||
4796 EltVT == MVT::bf16) {
4797 if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
4798 (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin()))
4799 Scalar = DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT, Scalar);
4801 Scalar = DAG.
getNode(ISD::BITCAST,
DL, MVT::i16, Scalar);
4803 Passthru = DAG.
getNode(ISD::BITCAST,
DL, IVT, Passthru);
4808 return DAG.
getNode(RISCVISD::VFMV_V_F_VL,
DL, VT, Passthru, Scalar, VL);
4812 if (Scalar.getValueType().bitsLE(XLenVT)) {
4819 Scalar = DAG.
getNode(ExtOpc,
DL, XLenVT, Scalar);
4820 return DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, VT, Passthru, Scalar, VL);
4823 assert(XLenVT == MVT::i32 && Scalar.getValueType() == MVT::i64 &&
4824 "Unexpected scalar for splat lowering!");
4827 return DAG.
getNode(RISCVISD::VMV_S_X_VL,
DL, VT, Passthru,
4853 MVT ExtractedContainerVT = ExtractedVT;
4856 DAG, ExtractedContainerVT, Subtarget);
4858 ExtractedVal, DAG, Subtarget);
4860 if (ExtractedContainerVT.
bitsLE(VT))
4872 if (!Scalar.getValueType().bitsLE(XLenVT))
4875 VT,
DL, DAG, Subtarget);
4883 Scalar = DAG.
getNode(ExtOpc,
DL, XLenVT, Scalar);
4924 Src && Src.
getValueType().getVectorNumElements() == (NumElts * 2))
4941 !Subtarget.hasVendorXRivosVizip())
4944 int Size = Mask.size();
4946 assert(
Size == (
int)NumElts &&
"Unexpected mask size");
4952 EvenSrc = StartIndexes[0];
4953 OddSrc = StartIndexes[1];
4956 if (EvenSrc != 0 && OddSrc != 0)
4966 int HalfNumElts = NumElts / 2;
4967 return ((EvenSrc % HalfNumElts) == 0) && ((OddSrc % HalfNumElts) == 0);
4972 std::array<std::pair<int, int>, 2> &SrcInfo) {
4977 if (SrcInfo[0].second == 0 && SrcInfo[1].second == 0)
4981 if ((SrcInfo[0].second > 0 && SrcInfo[1].second < 0) ||
4982 SrcInfo[1].second == 0)
4984 assert(SrcInfo[0].first != -1 &&
"Must find one slide");
4992 if (SrcInfo[1].first == -1)
4994 return SrcInfo[0].second < 0 && SrcInfo[1].second > 0 &&
4995 SrcInfo[1].second - SrcInfo[0].second == (int)NumElts;
5000 bool RequiredPolarity) {
5001 int NumElts = Mask.size();
5002 for (
const auto &[Idx, M] :
enumerate(Mask)) {
5005 int Src = M >= NumElts;
5006 int Diff = (int)Idx - (M % NumElts);
5007 bool C = Src == SrcInfo[1].first && Diff == SrcInfo[1].second;
5008 assert(
C != (Src == SrcInfo[0].first && Diff == SrcInfo[0].second) &&
5009 "Must match exactly one of the two slides");
5010 if (RequiredPolarity != (
C == (Idx / Factor) % 2))
5021static bool isZipEven(
const std::array<std::pair<int, int>, 2> &SrcInfo,
5023 Factor = SrcInfo[1].second;
5025 Mask.size() % Factor == 0 &&
5036static bool isZipOdd(
const std::array<std::pair<int, int>, 2> &SrcInfo,
5038 Factor = -SrcInfo[1].second;
5040 Mask.size() % Factor == 0 &&
5053 ElementCount SrcEC = Src.getValueType().getVectorElementCount();
5060 unsigned Shift = Index * EltBits;
5085 std::optional<int> SplatIdx;
5087 if (M == -1 ||
I == (
unsigned)M)
5089 if (SplatIdx && *SplatIdx != M)
5098 for (
int MaskIndex : Mask) {
5099 bool SelectMaskVal = MaskIndex == *SplatIdx;
5102 assert(MaskVals.
size() == NumElts &&
"Unexpected select-like shuffle");
5127 auto findNonEXTRACT_SUBVECTORParent =
5128 [](
SDValue Parent) -> std::pair<SDValue, uint64_t> {
5133 Parent.getOperand(0).getSimpleValueType().isFixedLengthVector()) {
5134 Offset += Parent.getConstantOperandVal(1);
5135 Parent = Parent.getOperand(0);
5137 return std::make_pair(Parent,
Offset);
5140 auto [V1Src, V1IndexOffset] = findNonEXTRACT_SUBVECTORParent(V1);
5141 auto [V2Src, V2IndexOffset] = findNonEXTRACT_SUBVECTORParent(V2);
5150 for (
size_t i = 0; i != NewMask.
size(); ++i) {
5151 if (NewMask[i] == -1)
5154 if (
static_cast<size_t>(NewMask[i]) < NewMask.
size()) {
5155 NewMask[i] = NewMask[i] + V1IndexOffset;
5159 NewMask[i] = NewMask[i] - NewMask.
size() + V2IndexOffset;
5165 if (NewMask[0] <= 0)
5169 for (
unsigned i = 1; i != NewMask.
size(); ++i)
5170 if (NewMask[i - 1] + 1 != NewMask[i])
5174 MVT SrcVT = Src.getSimpleValueType();
5203 int NumSubElts, Index;
5208 bool OpsSwapped = Mask[Index] < (int)NumElts;
5209 SDValue InPlace = OpsSwapped ? V2 : V1;
5210 SDValue ToInsert = OpsSwapped ? V1 : V2;
5221 if (NumSubElts + Index >= (
int)NumElts)
5232 Res = DAG.
getNode(RISCVISD::VMV_V_V_VL,
DL, ContainerVT, InPlace, ToInsert,
5235 Res =
getVSlideup(DAG, Subtarget,
DL, ContainerVT, InPlace, ToInsert,
5247 bool OpsSwapped =
false;
5262 const unsigned E = Mask.size() - ((
Offset > 0) ?
Offset : 0);
5263 for (
unsigned i = S; i !=
E; ++i)
5264 if (Mask[i] >= 0 && (
unsigned)Mask[i] !=
Base + i +
Offset)
5270 bool IsVSlidedown = isSlideMask(Mask, OpsSwapped ? 0 : NumElts, 1);
5271 if (!IsVSlidedown && !isSlideMask(Mask, OpsSwapped ? 0 : NumElts, -1))
5274 const int InsertIdx = Mask[IsVSlidedown ? (NumElts - 1) : 0];
5276 if (InsertIdx < 0 || InsertIdx / NumElts != (
unsigned)OpsSwapped)
5293 IsVSlidedown ? RISCVISD::VSLIDE1DOWN_VL : RISCVISD::VSLIDE1UP_VL,
DL,
5299 auto OpCode = IsVSlidedown ?
5300 (VT.
isFloatingPoint() ? RISCVISD::VFSLIDE1DOWN_VL : RISCVISD::VSLIDE1DOWN_VL) :
5301 (VT.
isFloatingPoint() ? RISCVISD::VFSLIDE1UP_VL : RISCVISD::VSLIDE1UP_VL);
5304 auto Vec = DAG.
getNode(OpCode,
DL, ContainerVT,
5307 Splat, TrueMask, VL);
5319 for (
unsigned i = 0; i < Mask.size(); i++)
5320 LaneIsUndef[i % Factor] &= (Mask[i] == -1);
5323 for (
unsigned i = 0; i < Factor; i++) {
5334 for (
unsigned i = 0; i < Mask.size() / Factor; i++) {
5335 unsigned j = i * Factor + Index;
5336 if (Mask[j] != -1 && (
unsigned)Mask[j] != i)
5345 assert(RISCVISD::RI_VZIPEVEN_VL ==
Opc || RISCVISD::RI_VZIPODD_VL ==
Opc ||
5346 RISCVISD::RI_VZIP2A_VL ==
Opc || RISCVISD::RI_VZIP2B_VL ==
Opc ||
5347 RISCVISD::RI_VUNZIP2A_VL ==
Opc || RISCVISD::RI_VUNZIP2B_VL ==
Opc);
5355 MVT ContainerVT = IntVT;
5362 MVT InnerVT = ContainerVT;
5366 (RISCVISD::RI_VUNZIP2A_VL ==
Opc || RISCVISD::RI_VUNZIP2B_VL ==
Opc)) {
5378 if (InnerVT.
bitsLT(ContainerVT))
5393 MVT VT = V.getSimpleValueType();
5408 EC.multiplyCoefficientBy(Factor));
5427 MVT VecContainerVT = VecVT;
5444 MVT WideContainerVT = WideVT;
5450 EvenV = DAG.
getBitcast(VecContainerVT, EvenV);
5457 if (Subtarget.hasStdExtZvbb()) {
5461 Interleaved = DAG.
getNode(RISCVISD::VWSLL_VL,
DL, WideContainerVT, OddV,
5462 OffsetVec, Passthru, Mask, VL);
5463 Interleaved = DAG.
getNode(RISCVISD::VWADDU_W_VL,
DL, WideContainerVT,
5464 Interleaved, EvenV, Passthru, Mask, VL);
5471 Interleaved = DAG.
getNode(RISCVISD::VWADDU_VL,
DL, WideContainerVT, EvenV,
5472 OddV, Passthru, Mask, VL);
5478 OddV, AllOnesVec, Passthru, Mask, VL);
5485 Interleaved = DAG.
getNode(RISCVISD::ADD_VL,
DL, WideContainerVT,
5486 Interleaved, OddsMul, Passthru, Mask, VL);
5493 Interleaved = DAG.
getBitcast(ResultContainerVT, Interleaved);
5539 if (ViaEltSize > NumElts)
5547 if (ViaEltSize > NumElts)
5553 if (ViaEltSize > NumElts)
5560 MVT &RotateVT,
unsigned &RotateAmt) {
5563 unsigned NumSubElts;
5565 NumElts, NumSubElts, RotateAmt))
5568 NumElts / NumSubElts);
5636 unsigned NumOfSrcRegs = NumElts / NumOpElts;
5637 unsigned NumOfDestRegs = NumElts / NumOpElts;
5646 Mask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs,
5648 [&](
ArrayRef<int> SrcSubMask,
unsigned SrcVecIdx,
unsigned DstVecIdx) {
5649 Operands.
emplace_back().emplace_back(SrcVecIdx, UINT_MAX,
5652 [&](
ArrayRef<int> SrcSubMask,
unsigned Idx1,
unsigned Idx2,
bool NewReg) {
5657 assert(Operands.
size() == NumOfDestRegs &&
"Whole vector must be processed");
5662 unsigned NumShuffles = std::accumulate(
5663 Operands.
begin(), Operands.
end(), 0u,
5669 for (const auto &P : Data) {
5670 unsigned Idx2 = std::get<1>(P);
5671 ArrayRef<int> Mask = std::get<2>(P);
5672 if (Idx2 != UINT_MAX)
5674 else if (ShuffleVectorInst::isIdentityMask(Mask, Mask.size()))
5679 if ((NumOfDestRegs > 2 && NumShuffles > NumOfDestRegs) ||
5680 (NumOfDestRegs <= 2 && NumShuffles >= 4))
5682 auto ExtractValue = [&, &DAG = DAG](
SDValue SrcVec,
unsigned ExtractIdx) {
5683 SDValue SubVec = DAG.getExtractSubvector(
DL, M1VT, SrcVec, ExtractIdx);
5687 auto PerformShuffle = [&, &DAG = DAG](
SDValue SubVec1,
SDValue SubVec2,
5689 SDValue SubVec = DAG.getVectorShuffle(OneRegVT,
DL, SubVec1, SubVec2, Mask);
5692 SDValue Vec = DAG.getUNDEF(ContainerVT);
5698 const auto &[Idx1, Idx2,
_] =
Data[
I];
5706 V = ExtractValue(Idx1 >= NumOfSrcRegs ? V2 : V1,
5707 (Idx1 % NumOfSrcRegs) * NumOpElts);
5708 if (Idx2 != UINT_MAX) {
5711 V = ExtractValue(Idx2 >= NumOfSrcRegs ? V2 : V1,
5712 (Idx2 % NumOfSrcRegs) * NumOpElts);
5716 for (
const auto &[Idx1, Idx2, Mask] :
Data) {
5718 SDValue V2 = Idx2 == UINT_MAX ? V1 : Values.
at(Idx2);
5719 V = PerformShuffle(V1, V2, Mask);
5723 unsigned InsertIdx =
I * NumOpElts;
5725 Vec = DAG.getInsertSubvector(
DL, Vec, V, InsertIdx);
5735 bool SawUndef =
false;
5736 for (
const auto &[Idx, M] :
enumerate(Mask)) {
5743 if (Idx > (
unsigned)M)
5776 for (
int Idx : Mask) {
5779 unsigned SrcIdx = Idx % Mask.size();
5780 int Src = (
uint32_t)Idx < Mask.size() ? 0 : 1;
5781 if (Srcs[SrcIdx] == -1)
5784 else if (Srcs[SrcIdx] != Src)
5790 for (
int Lane : Srcs) {
5803 for (
unsigned I = 0;
I < Mask.size();
I++) {
5807 NewMask[
I] = Mask[
I] % Mask.size();
5821 if ((M / Span) != (
int)(
I / Span))
5823 int SpanIdx =
I % Span;
5833 return all_of(Mask, [&](
const auto &Idx) {
return Idx == -1 || Idx < Span; });
5845 int SpanIdx =
I % Span;
5846 if (Mask[SpanIdx] != M)
5860 MVT VT =
Op.getSimpleValueType();
5868 if (ElementSize > 32)
5891 MVT VT =
Op.getSimpleValueType();
5919 auto [TrueMask, VL] = TrueMaskVL;
5934 V.getOperand(0).getSimpleValueType().getVectorNumElements();
5935 V = V.getOperand(
Offset / OpElements);
5965 MVT SplatVT = ContainerVT;
5968 if (SVT == MVT::bf16 ||
5969 (SVT == MVT::f16 && !Subtarget.hasStdExtZfh())) {
5978 V = DAG.
getLoad(SVT,
DL, Ld->getChain(), NewAddr,
5979 Ld->getPointerInfo().getWithOffset(
Offset),
5980 Ld->getBaseAlign(), Ld->getMemOperand()->
getFlags());
5983 Ld->getPointerInfo().getWithOffset(
Offset), SVT,
5985 Ld->getMemOperand()->getFlags());
5989 : RISCVISD::VMV_V_X_VL;
5997 assert(Lane < (
int)NumElts &&
"Unexpected lane!");
6000 DAG.
getUNDEF(ContainerVT), TrueMask, VL);
6022 if (Subtarget.hasStdExtZvkb())
6038 assert(MaxFactor == 2 || MaxFactor == 4 || MaxFactor == 8);
6039 for (
unsigned Factor = 2; Factor <= MaxFactor; Factor <<= 1) {
6042 1 <
count_if(Mask, [](
int Idx) {
return Idx != -1; })) {
6046 [&Mask](
int Idx) {
return Idx < (int)Mask.size(); }) &&
6047 1 <
count_if(Mask, [&Mask](
int Idx) {
6048 return Idx >= (int)Mask.size();
6078 if (Subtarget.hasVendorXRivosVizip() &&
6080 1 <
count_if(Mask, [](
int Idx) {
return Idx != -1; })) {
6082 Index == 0 ? RISCVISD::RI_VUNZIP2A_VL : RISCVISD::RI_VUNZIP2B_VL;
6098 [&Mask](
int Idx) {
return Idx < (int)Mask.size(); }) &&
6100 [&Mask](
int Idx) {
return Idx >= (int)Mask.size(); })) {
6104 if (NumElts < MinVLMAX) {
6128 int EvenSrc, OddSrc;
6138 bool LaneIsUndef[2] = {
true,
true};
6139 for (
const auto &[Idx, M] :
enumerate(Mask))
6140 LaneIsUndef[Idx % 2] &= (M == -1);
6142 int Size = Mask.size();
6144 if (LaneIsUndef[0]) {
6147 assert(EvenSrc >= 0 &&
"Undef source?");
6148 EvenV = (EvenSrc /
Size) == 0 ? V1 : V2;
6152 if (LaneIsUndef[1]) {
6155 assert(OddSrc >= 0 &&
"Undef source?");
6156 OddV = (OddSrc /
Size) == 0 ? V1 : V2;
6162 if (Subtarget.hasVendorXRivosVizip()) {
6165 return lowerVZIP(RISCVISD::RI_VZIP2A_VL, EvenV, OddV,
DL, DAG, Subtarget);
6176 std::array<std::pair<int, int>, 2> SrcInfo;
6183 auto GetSourceFor = [&](
const std::pair<int, int> &
Info) {
6184 int SrcIdx =
Info.first;
6185 assert(SrcIdx == 0 || SrcIdx == 1);
6186 SDValue &Src = Sources[SrcIdx];
6188 SDValue SrcV = SrcIdx == 0 ? V1 : V2;
6193 auto GetSlide = [&](
const std::pair<int, int> &Src,
SDValue Mask,
6195 auto [TrueMask, VL] = TrueMaskVL;
6196 SDValue SrcV = GetSourceFor(Src);
6197 int SlideAmt = Src.second;
6198 if (SlideAmt == 0) {
6200 assert(Mask == TrueMask);
6207 return getVSlideup(DAG, Subtarget,
DL, ContainerVT, Passthru, SrcV,
6212 if (SrcInfo[1].first == -1) {
6214 Res = GetSlide(SrcInfo[0], TrueMask, Res);
6218 if (Subtarget.hasVendorXRivosVizip()) {
6219 bool TryWiden =
false;
6223 SDValue Src1 = SrcInfo[0].first == 0 ? V1 : V2;
6224 SDValue Src2 = SrcInfo[1].first == 0 ? V1 : V2;
6225 return lowerVZIP(RISCVISD::RI_VZIPEVEN_VL, Src1, Src2,
DL, DAG,
6230 if (
isZipOdd(SrcInfo, Mask, Factor)) {
6232 SDValue Src1 = SrcInfo[1].first == 0 ? V1 : V2;
6233 SDValue Src2 = SrcInfo[0].first == 0 ? V1 : V2;
6234 return lowerVZIP(RISCVISD::RI_VZIPODD_VL, Src1, Src2,
DL, DAG,
6252 for (
const auto &[Idx, M] :
enumerate(Mask)) {
6254 (SrcInfo[1].second > 0 && Idx < (
unsigned)SrcInfo[1].second)) {
6258 int Src = M >= (int)NumElts;
6259 int Diff = (int)Idx - (M % NumElts);
6260 bool C = Src == SrcInfo[1].first && Diff == SrcInfo[1].second;
6261 assert(
C ^ (Src == SrcInfo[0].first && Diff == SrcInfo[0].second) &&
6262 "Must match exactly one of the two slides");
6265 assert(MaskVals.
size() == NumElts &&
"Unexpected select-like shuffle");
6272 Res = GetSlide(SrcInfo[0], TrueMask, Res);
6273 Res = GetSlide(SrcInfo[1], SelectMask, Res);
6278 assert(!V1.
isUndef() &&
"Unexpected shuffle canonicalization");
6293 assert(MaxFactor == 2 || MaxFactor == 4 || MaxFactor == 8);
6294 for (
unsigned Factor = 4; Factor <= MaxFactor; Factor <<= 1) {
6309 if (NumElts > MinVLMAX) {
6310 unsigned MaxIdx = 0;
6314 MaxIdx = std::max(std::max((
unsigned)
I, (
unsigned)M), MaxIdx);
6316 unsigned NewNumElts =
6318 if (NewNumElts != NumElts) {
6322 Mask.take_front(NewNumElts));
6339 for (
auto Idx : Mask) {
6342 assert(Idx >= 0 && (
unsigned)Idx < NumElts);
6352 any_of(Mask, [&](
const auto &Idx) {
return Idx > 255; })) {
6362 unsigned GatherVVOpc = RISCVISD::VRGATHER_VV_VL;
6368 GatherVVOpc = RISCVISD::VRGATHEREI16_VV_VL;
6377 GatherVVOpc = RISCVISD::VRGATHEREI16_VV_VL;
6381 MVT IndexContainerVT =
6386 for (
int MaskIndex : Mask) {
6387 bool IsLHSIndex = MaskIndex < (int)NumElts && MaskIndex >= 0;
6397 if (NumElts <= MinVLMAX) {
6399 DAG.
getUNDEF(ContainerVT), TrueMask, VL);
6405 auto [InnerTrueMask, InnerVL] =
6417 for (
int i = 0; i <
N; i++) {
6421 DAG.
getNode(GatherVVOpc,
DL, M1VT, SubV1, SubIndex,
6422 DAG.
getUNDEF(M1VT), InnerTrueMask, InnerVL);
6439 DAG.
getUNDEF(M1VT), InnerTrueMask, InnerVL);
6441 for (
int i = 0; i <
N; i++)
6457 for (
int i = 0; i <
N; i++) {
6460 DAG.
getUNDEF(IndexContainerVT), LHSIndices,
6461 SlideAmt, TrueMask, VL);
6465 DAG.
getNode(GatherVVOpc,
DL, M1VT, SubV1, SubIndex,
6466 DAG.
getUNDEF(M1VT), InnerTrueMask, InnerVL);
6476 DAG.
getUNDEF(ContainerVT), TrueMask, VL);
6486 for (
int MaskIndex : Mask) {
6487 bool IsLHSOrUndefIndex = MaskIndex < (int)NumElts;
6488 ShuffleMaskLHS.
push_back(IsLHSOrUndefIndex && MaskIndex >= 0
6490 ShuffleMaskRHS.
push_back(IsLHSOrUndefIndex ? -1 : (MaskIndex - NumElts));
6521 for (
int MaskIndex : Mask) {
6522 bool SelectMaskVal = (MaskIndex < (int)NumElts) ^ !SwapOps;
6526 assert(MaskVals.
size() == NumElts &&
"Unexpected select-like shuffle");
6544 const unsigned NumElts = M.size();
6551 std::array<std::pair<int, int>, 2> SrcInfo;
6562RISCVTargetLowering::lowerCTLZ_CTTZ_ZERO_UNDEF(
SDValue Op,
6564 MVT VT =
Op.getSimpleValueType();
6568 MVT ContainerVT = VT;
6571 if (
Op->isVPOpcode()) {
6572 Mask =
Op.getOperand(1);
6576 VL =
Op.getOperand(2);
6582 MVT FloatEltVT = (EltSize >= 32) ? MVT::f64 :
MVT::f32;
6584 FloatEltVT = MVT::f32;
6591 "Expected legal float type!");
6598 }
else if (
Op.getOpcode() == ISD::VP_CTTZ_ZERO_UNDEF) {
6601 Src = DAG.
getNode(ISD::VP_AND,
DL, VT, Src, Neg, Mask, VL);
6606 if (FloatVT.
bitsGT(VT)) {
6607 if (
Op->isVPOpcode())
6608 FloatVal = DAG.
getNode(ISD::VP_UINT_TO_FP,
DL, FloatVT, Src, Mask, VL);
6617 if (!
Op->isVPOpcode())
6621 MVT ContainerFloatVT =
6623 FloatVal = DAG.
getNode(RISCVISD::VFCVT_RM_F_XU_VL,
DL, ContainerFloatVT,
6624 Src, Mask, RTZRM, VL);
6631 unsigned ShiftAmt = FloatEltVT == MVT::f64 ? 52 : 23;
6635 if (
Op->isVPOpcode()) {
6644 else if (IntVT.
bitsGT(VT))
6649 unsigned ExponentBias = FloatEltVT == MVT::f64 ? 1023 : 127;
6654 if (
Op.getOpcode() == ISD::VP_CTTZ_ZERO_UNDEF)
6655 return DAG.
getNode(ISD::VP_SUB,
DL, VT, Exp,
6660 unsigned Adjust = ExponentBias + (EltSize - 1);
6662 if (
Op->isVPOpcode())
6672 else if (
Op.getOpcode() == ISD::VP_CTLZ)
6673 Res = DAG.
getNode(ISD::VP_UMIN,
DL, VT, Res,
6681 MVT XLenVT = Subtarget.getXLenVT();
6683 MVT SrcVT =
Source.getSimpleValueType();
6692 SrcVT = ContainerVT;
6704 SDValue Res = DAG.
getNode(RISCVISD::VFIRST_VL,
DL, XLenVT, Source, Mask, EVL);
6705 if (
Op->getOpcode() == ISD::VP_CTTZ_ELTS_ZERO_UNDEF)
6723 assert(Load &&
Load->getMemoryVT().isVector() &&
"Expected vector load");
6726 Load->getMemoryVT(),
6727 *
Load->getMemOperand()))
6731 MVT VT =
Op.getSimpleValueType();
6733 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
6734 "Unexpected unaligned RVV load type");
6738 "Expecting equally-sized RVV vector types to be legal");
6740 Load->getPointerInfo(),
Load->getBaseAlign(),
6741 Load->getMemOperand()->getFlags());
6752 assert(Store &&
Store->getValue().getValueType().isVector() &&
6753 "Expected vector store");
6756 Store->getMemoryVT(),
6757 *
Store->getMemOperand()))
6764 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
6765 "Unexpected unaligned RVV store type");
6769 "Expecting equally-sized RVV vector types to be legal");
6770 StoredVal = DAG.
getBitcast(NewVT, StoredVal);
6772 Store->getPointerInfo(),
Store->getBaseAlign(),
6773 Store->getMemOperand()->getFlags());
6778 assert(
Op.getValueType() == MVT::i64 &&
"Unexpected VT");
6807 unsigned ShiftAmt, AddOpc;
6818 MVT VT =
Op.getSimpleValueType();
6822 bool Negate =
false;
6826 if (Index < 0 &&
Imm.isNegative()) {
6843 return DAG.
getNode(ISD::FNEG,
DL, VT, Const);
6849 unsigned IsData =
Op.getConstantOperandVal(4);
6852 if (Subtarget.hasVendorXMIPSCBOP() && !IsData)
6853 return Op.getOperand(0);
6865 if (Subtarget.hasStdExtZtso()) {
6873 return DAG.
getNode(ISD::MEMBARRIER, dl, MVT::Other,
Op.getOperand(0));
6881 return DAG.
getNode(ISD::MEMBARRIER, dl, MVT::Other,
Op.getOperand(0));
6889 MVT VT =
Op.getSimpleValueType();
6890 MVT XLenVT = Subtarget.getXLenVT();
6891 unsigned Check =
Op.getConstantOperandVal(1);
6892 unsigned TDCMask = 0;
6920 MVT VT0 =
Op.getOperand(0).getSimpleValueType();
6925 if (
Op.getOpcode() == ISD::VP_IS_FPCLASS) {
6927 VL =
Op.getOperand(3);
6930 VL,
Op->getFlags());
6945 if (
Op.getOpcode() == ISD::VP_IS_FPCLASS) {
6947 MVT MaskContainerVT =
6950 VL =
Op.getOperand(3);
6954 SDValue FPCLASS = DAG.
getNode(RISCVISD::FCLASS_VL,
DL, ContainerDstVT, Op0,
6955 Mask, VL,
Op->getFlags());
6957 TDCMaskV = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerDstVT,
6958 DAG.
getUNDEF(ContainerDstVT), TDCMaskV, VL);
6961 DAG.
getNode(RISCVISD::SETCC_VL,
DL, ContainerVT,
6967 TDCMaskV, DAG.
getUNDEF(ContainerDstVT), Mask, VL);
6970 SplatZero = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerDstVT,
6971 DAG.
getUNDEF(ContainerDstVT), SplatZero, VL);
6991 MVT VT =
Op.getSimpleValueType();
7017 Op.getOpcode() == ISD::FMAXIMUM ? RISCVISD::FMAX : RISCVISD::FMIN;
7025 MVT ContainerVT = VT;
7033 if (
Op->isVPOpcode()) {
7034 Mask =
Op.getOperand(2);
7038 VL =
Op.getOperand(3);
7045 SDValue XIsNonNan = DAG.
getNode(RISCVISD::SETCC_VL,
DL, Mask.getValueType(),
7046 {X, X, DAG.getCondCode(ISD::SETOEQ),
7047 DAG.getUNDEF(ContainerVT), Mask, VL});
7048 NewY = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, ContainerVT, XIsNonNan,
Y,
X,
7054 SDValue YIsNonNan = DAG.
getNode(RISCVISD::SETCC_VL,
DL, Mask.getValueType(),
7055 {Y, Y, DAG.getCondCode(ISD::SETOEQ),
7056 DAG.getUNDEF(ContainerVT), Mask, VL});
7057 NewX = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, ContainerVT, YIsNonNan,
X,
Y,
7062 Op.getOpcode() == ISD::FMAXIMUM ||
Op->getOpcode() == ISD::VP_FMAXIMUM
7063 ? RISCVISD::VFMAX_VL
7064 : RISCVISD::VFMIN_VL;
7066 DAG.
getUNDEF(ContainerVT), Mask, VL);
7074 bool IsFABS =
Op.getOpcode() == ISD::FABS;
7075 assert((IsFABS ||
Op.getOpcode() == ISD::FNEG) &&
7076 "Wrong opcode for lowering FABS or FNEG.");
7079 MVT VT =
Op.getSimpleValueType();
7080 assert((VT == MVT::f16 || VT == MVT::bf16) &&
"Unexpected type");
7084 DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT,
Op.getOperand(0));
7087 Mask = Mask.sext(Subtarget.
getXLen());
7092 return DAG.
getNode(RISCVISD::FMV_H_X,
DL, VT, Logic);
7100 MVT VT =
Op.getSimpleValueType();
7101 assert((VT == MVT::f16 || VT == MVT::bf16) &&
"Unexpected type");
7111 if (SignSize == Subtarget.
getXLen())
7112 return DAG.
getNode(ISD::BITCAST,
DL, XLenVT, Sign);
7115 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT, Sign);
7117 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTW_RV64,
DL, XLenVT, Sign);
7119 assert(XLenVT == MVT::i32 &&
"Unexpected type");
7122 return DAG.
getNode(RISCVISD::SplitF64,
DL, {MVT::i32, MVT::i32}, Sign)
7152 return DAG.
getNode(RISCVISD::FMV_H_X,
DL, VT, CopiedSign);
7157#define OP_CASE(NODE) \
7159 return RISCVISD::NODE##_VL;
7160#define VP_CASE(NODE) \
7161 case ISD::VP_##NODE: \
7162 return RISCVISD::NODE##_VL;
7164 switch (
Op.getOpcode()) {
7243 case ISD::VP_CTLZ_ZERO_UNDEF:
7244 return RISCVISD::CTLZ_VL;
7246 case ISD::VP_CTTZ_ZERO_UNDEF:
7247 return RISCVISD::CTTZ_VL;
7250 return RISCVISD::VFMADD_VL;
7252 return RISCVISD::STRICT_VFMADD_VL;
7255 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
7256 return RISCVISD::VMAND_VL;
7257 return RISCVISD::AND_VL;
7260 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
7261 return RISCVISD::VMOR_VL;
7262 return RISCVISD::OR_VL;
7265 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
7266 return RISCVISD::VMXOR_VL;
7267 return RISCVISD::XOR_VL;
7270 return RISCVISD::VZEXT_VL;
7272 return RISCVISD::VSEXT_VL;
7274 return RISCVISD::SETCC_VL;
7276 return RISCVISD::VMERGE_VL;
7277 case ISD::VP_SELECT:
7279 return RISCVISD::VMERGE_VL;
7281 return RISCVISD::SRA_VL;
7283 return RISCVISD::SRL_VL;
7285 return RISCVISD::FSQRT_VL;
7286 case ISD::VP_SIGN_EXTEND:
7287 return RISCVISD::VSEXT_VL;
7288 case ISD::VP_ZERO_EXTEND:
7289 return RISCVISD::VZEXT_VL;
7290 case ISD::VP_FP_TO_SINT:
7291 return RISCVISD::VFCVT_RTZ_X_F_VL;
7292 case ISD::VP_FP_TO_UINT:
7293 return RISCVISD::VFCVT_RTZ_XU_F_VL;
7295 case ISD::FMINIMUMNUM:
7296 case ISD::VP_FMINNUM:
7297 return RISCVISD::VFMIN_VL;
7299 case ISD::FMAXIMUMNUM:
7300 case ISD::VP_FMAXNUM:
7301 return RISCVISD::VFMAX_VL;
7305 case ISD::VP_LLRINT:
7306 return RISCVISD::VFCVT_RM_X_F_VL;
7315 return (
Op.getValueType() == MVT::nxv32f16 &&
7318 (
Op.getValueType() == MVT::nxv32bf16 &&
7332 for (
unsigned j = 0; j !=
Op.getNumOperands(); ++j) {
7333 if (!
Op.getOperand(j).getValueType().isVector()) {
7334 LoOperands[j] =
Op.getOperand(j);
7335 HiOperands[j] =
Op.getOperand(j);
7338 std::tie(LoOperands[j], HiOperands[j]) =
7343 DAG.
getNode(
Op.getOpcode(),
DL, LoVT, LoOperands,
Op->getFlags());
7345 DAG.
getNode(
Op.getOpcode(),
DL, HiVT, HiOperands,
Op->getFlags());
7358 for (
unsigned j = 0; j !=
Op.getNumOperands(); ++j) {
7360 std::tie(LoOperands[j], HiOperands[j]) =
7364 if (!
Op.getOperand(j).getValueType().isVector()) {
7365 LoOperands[j] =
Op.getOperand(j);
7366 HiOperands[j] =
Op.getOperand(j);
7369 std::tie(LoOperands[j], HiOperands[j]) =
7374 DAG.
getNode(
Op.getOpcode(),
DL, LoVT, LoOperands,
Op->getFlags());
7376 DAG.
getNode(
Op.getOpcode(),
DL, HiVT, HiOperands,
Op->getFlags());
7386 auto [EVLLo, EVLHi] =
7387 DAG.
SplitEVL(
Op.getOperand(3),
Op.getOperand(1).getValueType(),
DL);
7391 {Op.getOperand(0), Lo, MaskLo, EVLLo},
Op->getFlags());
7393 {ResLo, Hi, MaskHi, EVLHi},
Op->getFlags());
7410 for (
unsigned j = 0; j !=
Op.getNumOperands(); ++j) {
7411 if (!
Op.getOperand(j).getValueType().isVector()) {
7412 LoOperands[j] =
Op.getOperand(j);
7413 HiOperands[j] =
Op.getOperand(j);
7416 std::tie(LoOperands[j], HiOperands[j]) =
7421 DAG.
getNode(
Op.getOpcode(),
DL, LoVTs, LoOperands,
Op->getFlags());
7424 DAG.
getNode(
Op.getOpcode(),
DL, HiVTs, HiOperands,
Op->getFlags());
7432RISCVTargetLowering::lowerXAndesBfHCvtBFloat16Load(
SDValue Op,
7434 assert(Subtarget.hasVendorXAndesBFHCvt() && !Subtarget.hasStdExtZfh() &&
7435 "Unexpected bfloat16 load lowering");
7439 EVT MemVT =
LD->getMemoryVT();
7444 LD->getMemOperand());
7452 DAG.
getNode(RISCVISD::NDS_FMV_BF16_X,
DL, MVT::bf16, OrSixteenOne);
7457RISCVTargetLowering::lowerXAndesBfHCvtBFloat16Store(
SDValue Op,
7459 assert(Subtarget.hasVendorXAndesBFHCvt() && !Subtarget.hasStdExtZfh() &&
7460 "Unexpected bfloat16 store lowering");
7465 Subtarget.getXLenVT(),
ST->getValue());
7467 ST->getChain(),
DL, FMV,
ST->getBasePtr(),
7469 ST->getMemOperand());
7474 switch (
Op.getOpcode()) {
7477 "Unimplemented RISCVTargetLowering::LowerOperation Case");
7480 case ISD::ATOMIC_FENCE:
7483 return lowerGlobalAddress(
Op, DAG);
7485 return lowerBlockAddress(
Op, DAG);
7487 return lowerConstantPool(
Op, DAG);
7489 return lowerJumpTable(
Op, DAG);
7491 return lowerGlobalTLSAddress(
Op, DAG);
7495 return lowerConstantFP(
Op, DAG);
7497 return lowerSELECT(
Op, DAG);
7499 return lowerBRCOND(
Op, DAG);
7501 return lowerVASTART(
Op, DAG);
7503 return lowerFRAMEADDR(
Op, DAG);
7505 return lowerRETURNADDR(
Op, DAG);
7507 return lowerShiftLeftParts(
Op, DAG);
7509 return lowerShiftRightParts(
Op, DAG,
true);
7511 return lowerShiftRightParts(
Op, DAG,
false);
7514 if (
Op.getValueType().isFixedLengthVector()) {
7515 assert(Subtarget.hasStdExtZvkb());
7516 return lowerToScalableOp(
Op, DAG);
7518 assert(Subtarget.hasVendorXTHeadBb() &&
7519 !(Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) &&
7520 "Unexpected custom legalization");
7525 case ISD::BITCAST: {
7527 EVT VT =
Op.getValueType();
7530 MVT XLenVT = Subtarget.getXLenVT();
7531 if (Op0VT == MVT::i16 &&
7532 ((VT == MVT::f16 && Subtarget.hasStdExtZfhminOrZhinxmin()) ||
7533 (VT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()))) {
7535 return DAG.
getNode(RISCVISD::FMV_H_X,
DL, VT, NewOp0);
7537 if (VT == MVT::f32 && Op0VT == MVT::i32 && Subtarget.is64Bit() &&
7538 Subtarget.hasStdExtFOrZfinx()) {
7540 return DAG.
getNode(RISCVISD::FMV_W_X_RV64,
DL, MVT::f32, NewOp0);
7542 if (VT == MVT::f64 && Op0VT == MVT::i64 && !Subtarget.is64Bit() &&
7543 Subtarget.hasStdExtDOrZdinx()) {
7546 return DAG.
getNode(RISCVISD::BuildPairF64,
DL, MVT::f64,
Lo,
Hi);
7558 "Unexpected types");
7590 return LowerINTRINSIC_WO_CHAIN(
Op, DAG);
7592 return LowerINTRINSIC_W_CHAIN(
Op, DAG);
7594 return LowerINTRINSIC_VOID(
Op, DAG);
7596 return LowerIS_FPCLASS(
Op, DAG);
7598 MVT VT =
Op.getSimpleValueType();
7600 assert(Subtarget.hasStdExtZvbb());
7601 return lowerToScalableOp(
Op, DAG);
7604 assert(Subtarget.hasStdExtZbkb() &&
"Unexpected custom legalization");
7608 return DAG.
getNode(RISCVISD::BREV8,
DL, VT, BSwap);
7614 if (!
Op.getSimpleValueType().isVector())
7616 return lowerVectorTruncLike(
Op, DAG);
7619 if (
Op.getOperand(0).getValueType().isVector() &&
7620 Op.getOperand(0).getValueType().getVectorElementType() == MVT::i1)
7621 return lowerVectorMaskExt(
Op, DAG, 1);
7622 if (
Op.getValueType().isScalableVector())
7624 return lowerToScalableOp(
Op, DAG);
7626 if (
Op.getOperand(0).getValueType().isVector() &&
7627 Op.getOperand(0).getValueType().getVectorElementType() == MVT::i1)
7628 return lowerVectorMaskExt(
Op, DAG, -1);
7629 if (
Op.getValueType().isScalableVector())
7631 return lowerToScalableOp(
Op, DAG);
7633 return lowerSPLAT_VECTOR_PARTS(
Op, DAG);
7635 return lowerINSERT_VECTOR_ELT(
Op, DAG);
7637 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
7639 MVT VT =
Op.getSimpleValueType();
7647 MVT ContainerVT = VT;
7654 V = DAG.
getNode(RISCVISD::VFMV_S_F_VL,
DL, ContainerVT,
7655 DAG.
getUNDEF(ContainerVT), Scalar, VL);
7658 V = DAG.
getNode(RISCVISD::VMV_S_X_VL,
DL, ContainerVT,
7659 DAG.
getUNDEF(ContainerVT), Scalar, VL);
7666 MVT XLenVT = Subtarget.getXLenVT();
7667 MVT VT =
Op.getSimpleValueType();
7686 }
else if (
Log2 > 3) {
7690 }
else if ((Val % 8) == 0) {
7708 if (
Op.getValueType() == MVT::f16 && Subtarget.is64Bit() &&
7709 Op.getOperand(1).getValueType() == MVT::i32) {
7713 DAG.
getNode(ISD::FPOWI,
DL, MVT::f32, Op0,
Op.getOperand(1));
7724 case ISD::FP_EXTEND:
7726 return lowerVectorFPExtendOrRoundLike(
Op, DAG);
7729 return lowerStrictFPExtendOrRoundLike(
Op, DAG);
7732 if (
Op.getValueType().isVector() &&
7733 ((
Op.getValueType().getScalarType() == MVT::f16 &&
7734 (Subtarget.hasVInstructionsF16Minimal() &&
7735 !Subtarget.hasVInstructionsF16())) ||
7736 Op.getValueType().getScalarType() == MVT::bf16)) {
7752 Op1.getValueType().isVector() &&
7753 ((Op1.getValueType().getScalarType() == MVT::f16 &&
7754 (Subtarget.hasVInstructionsF16Minimal() &&
7755 !Subtarget.hasVInstructionsF16())) ||
7756 Op1.getValueType().getScalarType() == MVT::bf16)) {
7762 Op1.getValueType().getVectorElementCount());
7765 return DAG.
getNode(
Op.getOpcode(),
DL,
Op.getValueType(), WidenVec);
7775 MVT VT =
Op.getSimpleValueType();
7778 bool IsStrict =
Op->isStrictFPOpcode();
7779 SDValue Src =
Op.getOperand(0 + IsStrict);
7780 MVT SrcVT = Src.getSimpleValueType();
7791 "Unexpected vector element types");
7795 if (EltSize > (2 * SrcEltSize)) {
7807 Op.getOperand(0), Ext);
7811 assert(SrcEltVT == MVT::f16 &&
"Unexpected FP_TO_[US]INT lowering");
7816 auto [FExt, Chain] =
7818 return DAG.
getNode(
Op.getOpcode(),
DL,
Op->getVTList(), Chain, FExt);
7825 if (SrcEltSize > (2 * EltSize)) {
7828 assert(EltVT == MVT::f16 &&
"Unexpected [US]_TO_FP lowering");
7833 Op.getOperand(0), Src);
7848 Op.getOperand(0), Src);
7862 unsigned RVVOpc = 0;
7863 switch (
Op.getOpcode()) {
7867 RVVOpc = RISCVISD::VFCVT_RTZ_X_F_VL;
7870 RVVOpc = RISCVISD::VFCVT_RTZ_XU_F_VL;
7873 RVVOpc = RISCVISD::SINT_TO_FP_VL;
7876 RVVOpc = RISCVISD::UINT_TO_FP_VL;
7879 RVVOpc = RISCVISD::STRICT_VFCVT_RTZ_X_F_VL;
7882 RVVOpc = RISCVISD::STRICT_VFCVT_RTZ_XU_F_VL;
7885 RVVOpc = RISCVISD::STRICT_SINT_TO_FP_VL;
7888 RVVOpc = RISCVISD::STRICT_UINT_TO_FP_VL;
7895 "Expected same element count");
7902 Op.getOperand(0), Src, Mask, VL);
7906 Src = DAG.
getNode(RVVOpc,
DL, ContainerVT, Src, Mask, VL);
7912 case ISD::FP_TO_BF16: {
7915 assert(!Subtarget.isSoftFPABI() &&
"Unexpected custom legalization");
7921 makeLibCall(DAG, LC, MVT::f32,
Op.getOperand(0), CallOptions,
DL).first;
7922 if (Subtarget.is64Bit())
7923 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTW_RV64,
DL, MVT::i64, Res);
7926 case ISD::BF16_TO_FP: {
7927 assert(Subtarget.hasStdExtFOrZfinx() &&
"Unexpected custom legalization");
7928 MVT VT =
Op.getSimpleValueType();
7933 SDValue Res = Subtarget.is64Bit()
7934 ? DAG.
getNode(RISCVISD::FMV_W_X_RV64,
DL, MVT::f32,
Op)
7938 return DAG.
getNode(ISD::FP_EXTEND,
DL, VT, Res);
7941 case ISD::STRICT_FP_TO_FP16:
7942 case ISD::FP_TO_FP16: {
7945 assert(Subtarget.hasStdExtFOrZfinx() &&
"Unexpected custom legalisation");
7948 bool IsStrict =
Op->isStrictFPOpcode();
7949 SDValue Op0 = IsStrict ?
Op.getOperand(1) :
Op.getOperand(0);
7953 std::tie(Res, Chain) =
7954 makeLibCall(DAG, LC, MVT::f32, Op0, CallOptions,
DL, Chain);
7955 if (Subtarget.is64Bit())
7956 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTW_RV64,
DL, MVT::i64, Res);
7962 case ISD::STRICT_FP16_TO_FP:
7963 case ISD::FP16_TO_FP: {
7966 assert(Subtarget.hasStdExtFOrZfinx() &&
"Unexpected custom legalisation");
7969 bool IsStrict =
Op->isStrictFPOpcode();
7970 SDValue Op0 = IsStrict ?
Op.getOperand(1) :
Op.getOperand(0);
7972 SDValue Arg = Subtarget.is64Bit()
7973 ? DAG.
getNode(RISCVISD::FMV_W_X_RV64,
DL, MVT::f32, Op0)
7976 std::tie(Res, Chain) =
makeLibCall(DAG, RTLIB::FPEXT_F16_F32, MVT::f32, Arg,
7977 CallOptions,
DL, Chain);
7985 case ISD::FNEARBYINT:
7988 case ISD::FROUNDEVEN:
7995 case ISD::LLROUND: {
7996 if (
Op.getValueType().isVector())
7998 assert(
Op.getOperand(0).getValueType() == MVT::f16 &&
7999 "Unexpected custom legalisation");
8002 return DAG.
getNode(
Op.getOpcode(),
DL,
Op.getValueType(), Ext);
8008 assert(
Op.getOperand(1).getValueType() == MVT::f16 &&
8009 "Unexpected custom legalisation");
8012 {
Op.getOperand(0),
Op.getOperand(1)});
8013 return DAG.
getNode(
Op.getOpcode(),
DL, {Op.getValueType(), MVT::Other},
8014 {Ext.getValue(1), Ext.getValue(0)});
8016 case ISD::VECREDUCE_ADD:
8017 case ISD::VECREDUCE_UMAX:
8018 case ISD::VECREDUCE_SMAX:
8019 case ISD::VECREDUCE_UMIN:
8020 case ISD::VECREDUCE_SMIN:
8021 return lowerVECREDUCE(
Op, DAG);
8022 case ISD::VECREDUCE_AND:
8023 case ISD::VECREDUCE_OR:
8024 case ISD::VECREDUCE_XOR:
8025 if (
Op.getOperand(0).getValueType().getVectorElementType() == MVT::i1)
8026 return lowerVectorMaskVecReduction(
Op, DAG,
false);
8027 return lowerVECREDUCE(
Op, DAG);
8028 case ISD::VECREDUCE_FADD:
8029 case ISD::VECREDUCE_SEQ_FADD:
8030 case ISD::VECREDUCE_FMIN:
8031 case ISD::VECREDUCE_FMAX:
8032 case ISD::VECREDUCE_FMAXIMUM:
8033 case ISD::VECREDUCE_FMINIMUM:
8034 return lowerFPVECREDUCE(
Op, DAG);
8035 case ISD::VP_REDUCE_ADD:
8036 case ISD::VP_REDUCE_UMAX:
8037 case ISD::VP_REDUCE_SMAX:
8038 case ISD::VP_REDUCE_UMIN:
8039 case ISD::VP_REDUCE_SMIN:
8040 case ISD::VP_REDUCE_FADD:
8041 case ISD::VP_REDUCE_SEQ_FADD:
8042 case ISD::VP_REDUCE_FMIN:
8043 case ISD::VP_REDUCE_FMAX:
8044 case ISD::VP_REDUCE_FMINIMUM:
8045 case ISD::VP_REDUCE_FMAXIMUM:
8048 return lowerVPREDUCE(
Op, DAG);
8049 case ISD::VP_REDUCE_AND:
8050 case ISD::VP_REDUCE_OR:
8051 case ISD::VP_REDUCE_XOR:
8052 if (
Op.getOperand(1).getValueType().getVectorElementType() == MVT::i1)
8053 return lowerVectorMaskVecReduction(
Op, DAG,
true);
8054 return lowerVPREDUCE(
Op, DAG);
8055 case ISD::VP_CTTZ_ELTS:
8056 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
8057 return lowerVPCttzElements(
Op, DAG);
8061 DAG.
getUNDEF(ContainerVT), DAG, Subtarget);
8064 return lowerINSERT_SUBVECTOR(
Op, DAG);
8066 return lowerEXTRACT_SUBVECTOR(
Op, DAG);
8068 return lowerVECTOR_DEINTERLEAVE(
Op, DAG);
8070 return lowerVECTOR_INTERLEAVE(
Op, DAG);
8072 return lowerSTEP_VECTOR(
Op, DAG);
8074 return lowerVECTOR_REVERSE(
Op, DAG);
8076 return lowerVECTOR_SPLICE(
Op, DAG);
8078 MVT VT =
Op.getSimpleValueType();
8080 if (!Subtarget.is64Bit() && EltVT == MVT::i64)
8085 MVT VT =
Op.getSimpleValueType();
8087 if ((EltVT == MVT::f16 && !Subtarget.hasStdExtZvfh()) ||
8088 EltVT == MVT::bf16) {
8091 if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
8092 (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin()))
8093 Elt = DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, Subtarget.getXLenVT(),
8096 Elt = DAG.
getNode(ISD::BITCAST,
DL, MVT::i16,
Op.getOperand(0));
8098 return DAG.
getNode(ISD::BITCAST,
DL, VT,
8102 if (EltVT == MVT::i1)
8103 return lowerVectorMaskSplat(
Op, DAG);
8112 MVT VT =
Op.getSimpleValueType();
8113 MVT ContainerVT = VT;
8125 if (
Op.getNumOperands() > 2 &&
8129 size_t HalfNumOps =
Op.getNumOperands() / 2;
8131 Op->ops().take_front(HalfNumOps));
8133 Op->ops().drop_front(HalfNumOps));
8137 unsigned NumOpElts =
8138 Op.getOperand(0).getSimpleValueType().getVectorMinNumElements();
8151 EVT VT = Load->getValueType(0);
8152 if (VT == MVT::f64) {
8153 assert(Subtarget.hasStdExtZdinx() && !Subtarget.hasStdExtZilsd() &&
8154 !Subtarget.is64Bit() &&
"Unexpected custom legalisation");
8158 SDValue BasePtr = Load->getBasePtr();
8159 SDValue Chain = Load->getChain();
8162 DAG.
getLoad(MVT::i32,
DL, Chain, BasePtr, Load->getPointerInfo(),
8163 Load->getBaseAlign(), Load->getMemOperand()->getFlags());
8166 MVT::i32,
DL, Chain, BasePtr, Load->getPointerInfo().getWithOffset(4),
8167 Load->getBaseAlign(), Load->getMemOperand()->getFlags());
8175 if (VT == MVT::bf16)
8176 return lowerXAndesBfHCvtBFloat16Load(
Op, DAG);
8181 MVT XLenVT = Subtarget.getXLenVT();
8184 unsigned NumElts = Sz / (NF * 8);
8185 int Log2LMUL =
Log2_64(NumElts) - 3;
8188 Flag.setNoUnsignedWrap(
true);
8190 SDValue BasePtr = Load->getBasePtr();
8198 for (
unsigned i = 0; i < NF; ++i) {
8203 Ret = DAG.
getNode(RISCVISD::TUPLE_INSERT,
DL, VT, Ret, LoadVal,
8211 if (
auto V = expandUnalignedRVVLoad(
Op, DAG))
8213 if (
Op.getValueType().isFixedLengthVector())
8214 return lowerFixedLengthVectorLoadToRVV(
Op, DAG);
8219 SDValue StoredVal = Store->getValue();
8221 if (VT == MVT::f64) {
8222 assert(Subtarget.hasStdExtZdinx() && !Subtarget.hasStdExtZilsd() &&
8223 !Subtarget.is64Bit() &&
"Unexpected custom legalisation");
8227 SDValue BasePtr = Store->getBasePtr();
8228 SDValue Chain = Store->getChain();
8230 DAG.
getVTList(MVT::i32, MVT::i32), StoredVal);
8233 Store->getPointerInfo(), Store->getBaseAlign(),
8234 Store->getMemOperand()->getFlags());
8237 Store->getPointerInfo().getWithOffset(4),
8238 Store->getBaseAlign(),
8239 Store->getMemOperand()->getFlags());
8242 if (VT == MVT::i64) {
8243 assert(Subtarget.hasStdExtZilsd() && !Subtarget.is64Bit() &&
8244 "Unexpected custom legalisation");
8245 if (Store->isTruncatingStore())
8248 if (!Subtarget.enableUnalignedScalarMem() && Store->getAlign() < 8)
8259 {Store->getChain(), Lo, Hi, Store->getBasePtr()}, MVT::i64,
8260 Store->getMemOperand());
8263 if (VT == MVT::bf16)
8264 return lowerXAndesBfHCvtBFloat16Store(
Op, DAG);
8269 MVT XLenVT = Subtarget.getXLenVT();
8272 unsigned NumElts = Sz / (NF * 8);
8273 int Log2LMUL =
Log2_64(NumElts) - 3;
8276 Flag.setNoUnsignedWrap(
true);
8278 SDValue Chain = Store->getChain();
8279 SDValue BasePtr = Store->getBasePtr();
8286 for (
unsigned i = 0; i < NF; ++i) {
8288 DAG.
getNode(RISCVISD::TUPLE_EXTRACT,
DL,
8291 Ret = DAG.
getStore(Chain,
DL, Extract, BasePtr,
8293 Store->getBaseAlign(),
8294 Store->getMemOperand()->getFlags());
8295 Chain = Ret.getValue(0);
8301 if (
auto V = expandUnalignedRVVStore(
Op, DAG))
8303 if (
Op.getOperand(1).getValueType().isFixedLengthVector())
8304 return lowerFixedLengthVectorStoreToRVV(
Op, DAG);
8309 return lowerMaskedLoad(
Op, DAG);
8310 case ISD::VP_LOAD_FF:
8311 return lowerLoadFF(
Op, DAG);
8314 return lowerMaskedStore(
Op, DAG);
8316 return lowerVectorCompress(
Op, DAG);
8325 EVT VT =
Op.getValueType();
8336 MVT OpVT =
Op.getOperand(0).getSimpleValueType();
8338 MVT VT =
Op.getSimpleValueType();
8343 "Unexpected CondCode");
8376 return DAG.
getSetCC(
DL, VT, RHS, LHS, CCVal);
8382 return lowerToScalableOp(
Op, DAG);
8399 return lowerToScalableOp(
Op, DAG);
8403 if (
Op.getSimpleValueType().isFixedLengthVector())
8404 return lowerToScalableOp(
Op, DAG);
8406 assert(
Op.getOperand(1).getValueType() == MVT::i32 && Subtarget.is64Bit() &&
8407 "Unexpected custom legalisation");
8411 if (
Op.getValueType() == MVT::f16 ||
Op.getValueType() == MVT::bf16)
8422 case ISD::FMINIMUMNUM:
8423 case ISD::FMAXIMUMNUM:
8439 return lowerToScalableOp(
Op, DAG);
8443 EVT VT =
Op->getValueType(0);
8458 return lowerABS(
Op, DAG);
8463 if (Subtarget.hasStdExtZvbb())
8464 return lowerToScalableOp(
Op, DAG);
8466 return lowerCTLZ_CTTZ_ZERO_UNDEF(
Op, DAG);
8468 if (
Op.getValueType() == MVT::f16 ||
Op.getValueType() == MVT::bf16)
8472 return lowerToScalableOp(
Op, DAG);
8481 return lowerToScalableOp(
Op, DAG);
8484 return lowerVectorStrictFSetcc(
Op, DAG);
8494 case ISD::VP_GATHER:
8495 return lowerMaskedGather(
Op, DAG);
8497 case ISD::VP_SCATTER:
8498 return lowerMaskedScatter(
Op, DAG);
8500 return lowerGET_ROUNDING(
Op, DAG);
8501 case ISD::SET_ROUNDING:
8502 return lowerSET_ROUNDING(
Op, DAG);
8503 case ISD::GET_FPENV:
8504 return lowerGET_FPENV(
Op, DAG);
8505 case ISD::SET_FPENV:
8506 return lowerSET_FPENV(
Op, DAG);
8507 case ISD::RESET_FPENV:
8508 return lowerRESET_FPENV(
Op, DAG);
8509 case ISD::GET_FPMODE:
8510 return lowerGET_FPMODE(
Op, DAG);
8511 case ISD::SET_FPMODE:
8512 return lowerSET_FPMODE(
Op, DAG);
8513 case ISD::RESET_FPMODE:
8514 return lowerRESET_FPMODE(
Op, DAG);
8516 return lowerEH_DWARF_CFA(
Op, DAG);
8518 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
8519 return lowerVPMergeMask(
Op, DAG);
8521 case ISD::VP_SELECT:
8529 case ISD::VP_UADDSAT:
8530 case ISD::VP_USUBSAT:
8531 case ISD::VP_SADDSAT:
8532 case ISD::VP_SSUBSAT:
8534 case ISD::VP_LLRINT:
8535 return lowerVPOp(
Op, DAG);
8539 return lowerLogicVPOp(
Op, DAG);
8548 case ISD::VP_FMINNUM:
8549 case ISD::VP_FMAXNUM:
8550 case ISD::VP_FCOPYSIGN:
8557 return lowerVPOp(
Op, DAG);
8558 case ISD::VP_IS_FPCLASS:
8559 return LowerIS_FPCLASS(
Op, DAG);
8560 case ISD::VP_SIGN_EXTEND:
8561 case ISD::VP_ZERO_EXTEND:
8562 if (
Op.getOperand(0).getSimpleValueType().getVectorElementType() == MVT::i1)
8563 return lowerVPExtMaskOp(
Op, DAG);
8564 return lowerVPOp(
Op, DAG);
8565 case ISD::VP_TRUNCATE:
8566 return lowerVectorTruncLike(
Op, DAG);
8567 case ISD::VP_FP_EXTEND:
8568 case ISD::VP_FP_ROUND:
8569 return lowerVectorFPExtendOrRoundLike(
Op, DAG);
8570 case ISD::VP_SINT_TO_FP:
8571 case ISD::VP_UINT_TO_FP:
8572 if (
Op.getValueType().isVector() &&
8573 ((
Op.getValueType().getScalarType() == MVT::f16 &&
8574 (Subtarget.hasVInstructionsF16Minimal() &&
8575 !Subtarget.hasVInstructionsF16())) ||
8576 Op.getValueType().getScalarType() == MVT::bf16)) {
8589 case ISD::VP_FP_TO_SINT:
8590 case ISD::VP_FP_TO_UINT:
8592 Op1.getValueType().isVector() &&
8593 ((Op1.getValueType().getScalarType() == MVT::f16 &&
8594 (Subtarget.hasVInstructionsF16Minimal() &&
8595 !Subtarget.hasVInstructionsF16())) ||
8596 Op1.getValueType().getScalarType() == MVT::bf16)) {
8602 Op1.getValueType().getVectorElementCount());
8606 {WidenVec, Op.getOperand(1), Op.getOperand(2)});
8608 return lowerVPFPIntConvOp(
Op, DAG);
8612 if (
Op.getOperand(0).getSimpleValueType().getVectorElementType() == MVT::i1)
8613 return lowerVPSetCCMaskOp(
Op, DAG);
8619 case ISD::VP_BITREVERSE:
8621 return lowerVPOp(
Op, DAG);
8623 case ISD::VP_CTLZ_ZERO_UNDEF:
8624 if (Subtarget.hasStdExtZvbb())
8625 return lowerVPOp(
Op, DAG);
8626 return lowerCTLZ_CTTZ_ZERO_UNDEF(
Op, DAG);
8628 case ISD::VP_CTTZ_ZERO_UNDEF:
8629 if (Subtarget.hasStdExtZvbb())
8630 return lowerVPOp(
Op, DAG);
8631 return lowerCTLZ_CTTZ_ZERO_UNDEF(
Op, DAG);
8633 return lowerVPOp(
Op, DAG);
8634 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
8635 return lowerVPStridedLoad(
Op, DAG);
8636 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
8637 return lowerVPStridedStore(
Op, DAG);
8639 case ISD::VP_FFLOOR:
8641 case ISD::VP_FNEARBYINT:
8642 case ISD::VP_FROUND:
8643 case ISD::VP_FROUNDEVEN:
8644 case ISD::VP_FROUNDTOZERO:
8648 case ISD::VP_FMAXIMUM:
8649 case ISD::VP_FMINIMUM:
8653 case ISD::EXPERIMENTAL_VP_SPLICE:
8654 return lowerVPSpliceExperimental(
Op, DAG);
8655 case ISD::EXPERIMENTAL_VP_REVERSE:
8656 return lowerVPReverseExperimental(
Op, DAG);
8657 case ISD::EXPERIMENTAL_VP_SPLAT:
8658 return lowerVPSplatExperimental(
Op, DAG);
8661 "llvm.clear_cache only needs custom lower on Linux targets");
8664 return emitFlushICache(DAG,
Op.getOperand(0),
Op.getOperand(1),
8665 Op.getOperand(2), Flags,
DL);
8667 case ISD::DYNAMIC_STACKALLOC:
8668 return lowerDYNAMIC_STACKALLOC(
Op, DAG);
8669 case ISD::INIT_TRAMPOLINE:
8670 return lowerINIT_TRAMPOLINE(
Op, DAG);
8671 case ISD::ADJUST_TRAMPOLINE:
8672 return lowerADJUST_TRAMPOLINE(
Op, DAG);
8673 case ISD::PARTIAL_REDUCE_UMLA:
8674 case ISD::PARTIAL_REDUCE_SMLA:
8675 case ISD::PARTIAL_REDUCE_SUMLA:
8676 return lowerPARTIAL_REDUCE_MLA(
Op, DAG);
8683 MakeLibCallOptions CallOptions;
8684 std::pair<SDValue, SDValue> CallResult =
8685 makeLibCall(DAG, RTLIB::RISCV_FLUSH_ICACHE, MVT::isVoid,
8686 {Start, End, Flags}, CallOptions,
DL, InChain);
8689 return CallResult.second;
8694 if (!Subtarget.is64Bit())
8702 std::unique_ptr<MCCodeEmitter> CodeEmitter(
8730 const bool HasCFBranch =
8731 Subtarget.hasStdExtZicfilp() &&
8733 "cf-protection-branch");
8734 const unsigned StaticChainIdx = HasCFBranch ? 5 : 4;
8735 const unsigned StaticChainOffset = StaticChainIdx * 4;
8736 const unsigned FunctionAddressOffset = StaticChainOffset + 8;
8740 auto GetEncoding = [&](
const MCInst &MC) {
8743 CodeEmitter->encodeInstruction(MC, CB, Fixups, *STI);
8750 SmallVector<uint32_t> Encodings;
8755 GetEncoding(MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X7).addImm(0)),
8759 GetEncoding(MCInstBuilder(RISCV::LD)
8762 .addImm(FunctionAddressOffset)),
8765 GetEncoding(MCInstBuilder(RISCV::LD)
8768 .addImm(StaticChainOffset)),
8771 GetEncoding(MCInstBuilder(RISCV::JALR)
8779 GetEncoding(MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X0).addImm(0)),
8782 GetEncoding(MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X28).addImm(0)),
8786 GetEncoding(MCInstBuilder(RISCV::LD)
8789 .addImm(FunctionAddressOffset - 4)),
8792 GetEncoding(MCInstBuilder(RISCV::LD)
8795 .addImm(StaticChainOffset - 4)),
8798 GetEncoding(MCInstBuilder(RISCV::JALR)
8810 Root, dl, DAG.
getConstant(Encoding, dl, MVT::i64), Addr,
8811 MachinePointerInfo(TrmpAddr, Idx * 4), MVT::i32));
8815 SDValue FunctionAddress =
Op.getOperand(2);
8819 struct OffsetValuePair {
8823 } OffsetValues[] = {
8824 {StaticChainOffset, StaticChain},
8825 {FunctionAddressOffset, FunctionAddress},
8827 for (
auto &OffsetValue : OffsetValues) {
8830 DAG.
getConstant(OffsetValue.Offset, dl, MVT::i64));
8831 OffsetValue.Addr = Addr;
8833 DAG.
getStore(Root, dl, OffsetValue.Value, Addr,
8834 MachinePointerInfo(TrmpAddr, OffsetValue.Offset)));
8837 assert(OutChains.
size() == StaticChainIdx + 2 &&
8838 "Size of OutChains mismatch");
8843 SDValue EndOfTrmp = OffsetValues[0].Addr;
8854 if (!Subtarget.is64Bit())
8857 return Op.getOperand(0);
8866 MVT VT =
Op.getSimpleValueType();
8872 MVT ArgVT =
A.getSimpleValueType();
8873 assert(ArgVT ==
B.getSimpleValueType() &&
8883 MVT ContainerVT = VT;
8892 switch (
Op.getOpcode()) {
8893 case ISD::PARTIAL_REDUCE_SMLA:
8894 Opc = RISCVISD::VQDOT_VL;
8896 case ISD::PARTIAL_REDUCE_UMLA:
8897 Opc = RISCVISD::VQDOTU_VL;
8899 case ISD::PARTIAL_REDUCE_SUMLA:
8900 Opc = RISCVISD::VQDOTSU_VL;
8926 N->getOffset(), Flags);
8955template <
class NodeTy>
8957 bool IsLocal,
bool IsExternWeak)
const {
8967 if (IsLocal && !Subtarget.allowTaggedGlobals())
8971 return DAG.
getNode(RISCVISD::LLA,
DL, Ty, Addr);
8994 if (Subtarget.hasVendorXqcili()) {
8998 return DAG.
getNode(RISCVISD::QC_E_LI,
DL, Ty, Addr);
9005 return DAG.
getNode(RISCVISD::ADD_LO,
DL, Ty, MNHi, AddrLo);
9029 return DAG.
getNode(RISCVISD::LLA,
DL, Ty, Addr);
9037 return DAG.
getNode(RISCVISD::LLA,
DL, Ty, Addr);
9045 assert(
N->getOffset() == 0 &&
"unexpected offset in global node");
9046 const GlobalValue *GV =
N->getGlobal();
9054 return getAddr(
N, DAG);
9061 return getAddr(
N, DAG);
9068 return getAddr(
N, DAG);
9073 bool UseGOT)
const {
9076 const GlobalValue *GV =
N->getGlobal();
9077 MVT XLenVT = Subtarget.getXLenVT();
9114 DAG.
getNode(RISCVISD::ADD_TPREL,
DL, Ty, MNHi, TPReg, AddrAdd);
9115 return DAG.
getNode(RISCVISD::ADD_LO,
DL, Ty, MNAdd, AddrLo);
9123 const GlobalValue *GV =
N->getGlobal();
9134 Args.emplace_back(Load, CallTy);
9137 TargetLowering::CallLoweringInfo CLI(DAG);
9151 const GlobalValue *GV =
N->getGlobal();
9167 assert(
N->getOffset() == 0 &&
"unexpected offset in global node");
9181 Addr = getStaticTLSAddr(
N, DAG,
false);
9184 Addr = getStaticTLSAddr(
N, DAG,
true);
9189 : getDynamicTLSAddr(
N, DAG);
9206 if (
LHS == LHS2 &&
RHS == RHS2) {
9211 }
else if (
LHS == RHS2 &&
RHS == LHS2) {
9219 return std::nullopt;
9231 MVT VT =
N->getSimpleValueType(0);
9258 uint64_t TrueM1 = TrueC->getZExtValue() - 1;
9260 unsigned ShAmount =
Log2_64(TrueM1);
9262 return DAG.
getNode(RISCVISD::SHL_ADD,
DL, VT, CondV,
9278 if (~TrueVal == FalseVal) {
9318 if (Subtarget.hasShortForwardBranchOpt())
9321 unsigned SelOpNo = 0;
9331 unsigned ConstSelOpNo = 1;
9332 unsigned OtherSelOpNo = 2;
9339 if (!ConstSelOpNode || ConstSelOpNode->
isOpaque())
9344 if (!ConstBinOpNode || ConstBinOpNode->
isOpaque())
9350 SDValue NewConstOps[2] = {ConstSelOp, ConstBinOp};
9352 std::swap(NewConstOps[0], NewConstOps[1]);
9364 SDValue NewNonConstOps[2] = {OtherSelOp, ConstBinOp};
9366 std::swap(NewNonConstOps[0], NewNonConstOps[1]);
9369 SDValue NewT = (ConstSelOpNo == 1) ? NewConstOp : NewNonConstOp;
9370 SDValue NewF = (ConstSelOpNo == 1) ? NewNonConstOp : NewConstOp;
9379 MVT VT =
Op.getSimpleValueType();
9380 MVT XLenVT = Subtarget.getXLenVT();
9401 return DAG.
getNode(RISCVISD::CZERO_EQZ,
DL, VT, TrueV, CondV);
9404 return DAG.
getNode(RISCVISD::CZERO_NEZ,
DL, VT, FalseV, CondV);
9408 auto getNotOperand = [](
const SDValue &
Op) -> std::optional<const SDValue> {
9409 using namespace llvm::SDPatternMatch;
9414 return std::nullopt;
9420 auto NotOperand = (TrueV.
getOperand(0) == FalseV)
9422 : getNotOperand(TrueV.getOperand(0));
9425 DAG.
getNode(RISCVISD::CZERO_EQZ,
DL, VT, *NotOperand, CondV);
9431 DAG.
getNode(RISCVISD::CZERO_NEZ,
DL, VT, FalseV, CondV));
9438 auto NotOperand = (FalseV.
getOperand(0) == TrueV)
9440 : getNotOperand(FalseV.getOperand(0));
9443 DAG.
getNode(RISCVISD::CZERO_NEZ,
DL, VT, *NotOperand, CondV);
9449 DAG.
getNode(RISCVISD::CZERO_EQZ,
DL, VT, TrueV, CondV));
9466 int64_t TrueImm =
TrueVal.getSExtValue();
9467 int64_t FalseImm =
FalseVal.getSExtValue();
9486 if ((TrueVal - FalseVal).isPowerOf2() &&
FalseVal.isSignedIntN(12)) {
9491 if ((FalseVal - TrueVal).isPowerOf2() &&
TrueVal.isSignedIntN(12)) {
9498 auto getCost = [&](
const APInt &Delta,
const APInt &Addend) {
9500 Delta, Subtarget.getXLen(), Subtarget,
true);
9502 if (Addend.isSignedIntN(12))
9505 Addend, Subtarget.getXLen(), Subtarget,
true);
9506 return AddendCost + DeltaCost;
9508 bool IsCZERO_NEZ =
getCost(FalseVal - TrueVal, TrueVal) <=
9509 getCost(TrueVal - FalseVal, FalseVal);
9511 IsCZERO_NEZ ? FalseVal - TrueVal : TrueVal - FalseVal,
DL, VT);
9513 DAG.
getNode(IsCZERO_NEZ ? RISCVISD::CZERO_NEZ : RISCVISD::CZERO_EQZ,
9514 DL, VT, LHSVal, CondV);
9522 SDValue ConstVal = IsCZERO_NEZ ? TrueV : FalseV;
9523 SDValue RegV = IsCZERO_NEZ ? FalseV : TrueV;
9526 if (RawConstVal == -0x800) {
9529 DAG.
getNode(IsCZERO_NEZ ? RISCVISD::CZERO_NEZ : RISCVISD::CZERO_EQZ,
9530 DL, VT, XorOp, CondV);
9538 DAG.
getNode(IsCZERO_NEZ ? RISCVISD::CZERO_NEZ : RISCVISD::CZERO_EQZ,
9539 DL, VT, SubOp, CondV);
9546 if (!Subtarget.hasConditionalMoveFusion())
9549 DAG.
getNode(RISCVISD::CZERO_EQZ,
DL, VT, TrueV, CondV),
9550 DAG.
getNode(RISCVISD::CZERO_NEZ,
DL, VT, FalseV, CondV),
9554 if (
Op.hasOneUse()) {
9555 unsigned UseOpc =
Op->user_begin()->getOpcode();
9557 SDNode *BinOp = *
Op->user_begin();
9564 return lowerSELECT(NewSel, DAG);
9618 if (TrueVal - 1 == FalseVal)
9620 if (TrueVal + 1 == FalseVal)
9627 RHS == TrueV &&
LHS == FalseV) {
9658 MVT XLenVT = Subtarget.getXLenVT();
9669 return DAG.
getNode(RISCVISD::BR_CC,
DL,
Op.getValueType(),
Op.getOperand(0),
9670 LHS,
RHS, TargetCC,
Op.getOperand(2));
9673 return DAG.
getNode(RISCVISD::BR_CC,
DL,
Op.getValueType(),
Op.getOperand(0),
9680 RISCVMachineFunctionInfo *FuncInfo = MF.
getInfo<RISCVMachineFunctionInfo>();
9690 MachinePointerInfo(SV));
9695 const RISCVRegisterInfo &RI = *Subtarget.getRegisterInfo();
9700 int XLenInBytes = Subtarget.getXLen() / 8;
9702 EVT VT =
Op.getValueType();
9705 unsigned Depth =
Op.getConstantOperandVal(0);
9707 int Offset = -(XLenInBytes * 2);
9719 const RISCVRegisterInfo &RI = *Subtarget.getRegisterInfo();
9723 MVT XLenVT = Subtarget.getXLenVT();
9724 int XLenInBytes = Subtarget.getXLen() / 8;
9726 EVT VT =
Op.getValueType();
9728 unsigned Depth =
Op.getConstantOperandVal(0);
9730 int Off = -XLenInBytes;
9731 SDValue FrameAddr = lowerFRAMEADDR(
Op, DAG);
9735 MachinePointerInfo());
9750 EVT VT =
Lo.getValueType();
9789 EVT VT =
Lo.getValueType();
9840 MVT VT =
Op.getSimpleValueType();
9845 return DAG.
getNode(RISCVISD::VMSET_VL,
DL, VT, VL);
9849 return DAG.
getNode(RISCVISD::VMCLR_VL,
DL, VT, VL);
9866 MVT VecVT =
Op.getSimpleValueType();
9868 "Unexpected SPLAT_VECTOR_PARTS lowering");
9874 MVT ContainerVT = VecVT;
9894 int64_t ExtTrueVal)
const {
9896 MVT VecVT =
Op.getSimpleValueType();
9899 assert(Src.getValueType().isVector() &&
9900 Src.getValueType().getVectorElementType() == MVT::i1);
9920 MVT XLenVT = Subtarget.getXLenVT();
9926 if (
Xor.getOpcode() == RISCVISD::VMXOR_VL) {
9938 SplatZero = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerVT,
9939 DAG.
getUNDEF(ContainerVT), SplatZero, VL);
9940 SplatTrueVal = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerVT,
9941 DAG.
getUNDEF(ContainerVT), SplatTrueVal, VL);
9943 DAG.
getNode(RISCVISD::VMERGE_VL,
DL, ContainerVT, CC, SplatTrueVal,
9944 SplatZero, DAG.
getUNDEF(ContainerVT), VL);
9954 bool IsVPTrunc =
Op.getOpcode() == ISD::VP_TRUNCATE;
9956 EVT MaskVT =
Op.getValueType();
9959 "Unexpected type for vector mask lowering");
9961 MVT VecVT = Src.getSimpleValueType();
9965 VL =
Op.getOperand(2);
9968 MVT ContainerVT = VecVT;
9974 MVT MaskContainerVT =
9981 std::tie(Mask, VL) =
9988 SplatOne = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerVT,
9989 DAG.
getUNDEF(ContainerVT), SplatOne, VL);
9990 SplatZero = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerVT,
9991 DAG.
getUNDEF(ContainerVT), SplatZero, VL);
9994 SDValue Trunc = DAG.
getNode(RISCVISD::AND_VL,
DL, ContainerVT, Src, SplatOne,
9995 DAG.
getUNDEF(ContainerVT), Mask, VL);
9996 Trunc = DAG.
getNode(RISCVISD::SETCC_VL,
DL, MaskContainerVT,
10006 unsigned Opc =
Op.getOpcode();
10007 bool IsVPTrunc =
Opc == ISD::VP_TRUNCATE;
10010 MVT VT =
Op.getSimpleValueType();
10012 assert(VT.
isVector() &&
"Unexpected type for vector truncate lowering");
10016 return lowerVectorMaskTruncLike(
Op, DAG);
10024 MVT SrcVT = Src.getSimpleValueType();
10029 "Unexpected vector truncate lowering");
10031 MVT ContainerVT = SrcVT;
10034 Mask =
Op.getOperand(1);
10035 VL =
Op.getOperand(2);
10048 std::tie(Mask, VL) =
10054 NewOpc = RISCVISD::TRUNCATE_VECTOR_VL_SSAT;
10056 NewOpc = RISCVISD::TRUNCATE_VECTOR_VL_USAT;
10058 NewOpc = RISCVISD::TRUNCATE_VECTOR_VL;
10064 }
while (SrcEltVT != DstEltVT);
10073RISCVTargetLowering::lowerStrictFPExtendOrRoundLike(
SDValue Op,
10078 MVT VT =
Op.getSimpleValueType();
10079 MVT SrcVT = Src.getSimpleValueType();
10080 MVT ContainerVT = VT;
10099 ? RISCVISD::STRICT_FP_EXTEND_VL
10100 : RISCVISD::STRICT_VFNCVT_ROD_VL;
10103 Chain, Src, Mask, VL);
10104 Chain = Src.getValue(1);
10108 ? RISCVISD::STRICT_FP_EXTEND_VL
10109 : RISCVISD::STRICT_FP_ROUND_VL;
10111 Chain, Src, Mask, VL);
10122RISCVTargetLowering::lowerVectorFPExtendOrRoundLike(
SDValue Op,
10125 Op.getOpcode() == ISD::VP_FP_ROUND ||
Op.getOpcode() == ISD::VP_FP_EXTEND;
10127 Op.getOpcode() == ISD::VP_FP_EXTEND ||
Op.getOpcode() == ISD::FP_EXTEND;
10132 MVT VT =
Op.getSimpleValueType();
10134 assert(VT.
isVector() &&
"Unexpected type for vector truncate lowering");
10137 MVT SrcVT = Src.getSimpleValueType();
10139 bool IsDirectExtend =
10147 bool IsDirectConv = IsDirectExtend || IsDirectTrunc;
10154 MVT ContainerVT = VT;
10157 Mask =
Op.getOperand(1);
10158 VL =
Op.getOperand(2);
10172 std::tie(Mask, VL) =
10175 unsigned ConvOpc = IsExtend ? RISCVISD::FP_EXTEND_VL : RISCVISD::FP_ROUND_VL;
10177 if (IsDirectConv) {
10178 Src = DAG.
getNode(ConvOpc,
DL, ContainerVT, Src, Mask, VL);
10184 unsigned InterConvOpc =
10185 IsExtend ? RISCVISD::FP_EXTEND_VL : RISCVISD::VFNCVT_ROD_VL;
10189 DAG.
getNode(InterConvOpc,
DL, InterVT, Src, Mask, VL);
10191 DAG.
getNode(ConvOpc,
DL, ContainerVT, IntermediateConv, Mask, VL);
10202static std::optional<MVT>
10208 const unsigned MinVLMAX = VectorBitsMin / EltSize;
10210 if (MaxIdx < MinVLMAX)
10212 else if (MaxIdx < MinVLMAX * 2)
10215 else if (MaxIdx < MinVLMAX * 4)
10220 return std::nullopt;
10228 return isUInt<5>(IdxC->getZExtValue());
10240 MVT VecVT =
Op.getSimpleValueType();
10241 MVT XLenVT = Subtarget.getXLenVT();
10256 if ((ValVT == MVT::f16 && !Subtarget.hasVInstructionsF16()) ||
10257 ValVT == MVT::bf16) {
10262 DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT, Val), Idx);
10266 MVT ContainerVT = VecVT;
10276 std::optional<unsigned> AlignedIdx;
10278 const unsigned OrigIdx = IdxC->getZExtValue();
10281 DL, DAG, Subtarget)) {
10282 ContainerVT = *ShrunkVT;
10290 if (
auto VLEN = Subtarget.getRealVLen(); VLEN && ContainerVT.
bitsGT(M1VT)) {
10293 unsigned RemIdx = OrigIdx % ElemsPerVReg;
10294 unsigned SubRegIdx = OrigIdx / ElemsPerVReg;
10297 ContainerVT = M1VT;
10304 bool IsLegalInsert = Subtarget.is64Bit() || Val.
getValueType() != MVT::i64;
10312 IsLegalInsert =
true;
10321 if (IsLegalInsert) {
10323 VecVT.
isFloatingPoint() ? RISCVISD::VFMV_S_F_VL : RISCVISD::VMV_S_X_VL;
10327 Vec = DAG.
getNode(
Opc,
DL, ContainerVT, Vec, Val, VL);
10337 if (Subtarget.hasVendorXRivosVisni() && VecVT.
isInteger() &&
10342 Vec = DAG.
getNode(RISCVISD::RI_VINSERT_VL,
DL, ContainerVT, Vec, Val, Idx,
10358 std::tie(ValLo, ValHi) = DAG.
SplitScalar(Val,
DL, MVT::i32, MVT::i32);
10359 MVT I32ContainerVT =
10369 ValInVec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32ContainerVT,
10370 Vec, Vec, ValLo, I32Mask, InsertI64VL);
10374 ValInVec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32ContainerVT,
10375 Tail, ValInVec, ValHi, I32Mask, InsertI64VL);
10377 ValInVec = DAG.
getBitcast(ContainerVT, ValInVec);
10388 ValInVec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32ContainerVT,
10390 DAG.
getUNDEF(I32ContainerVT), ValLo,
10391 I32Mask, InsertI64VL);
10392 ValInVec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32ContainerVT,
10393 DAG.
getUNDEF(I32ContainerVT), ValInVec, ValHi,
10394 I32Mask, InsertI64VL);
10396 ValInVec = DAG.
getBitcast(ContainerVT, ValInVec);
10409 Idx, Mask, InsertVL, Policy);
10427 EVT EltVT =
Op.getValueType();
10429 MVT XLenVT = Subtarget.getXLenVT();
10434 MVT ContainerVT = VecVT;
10441 DAG.
getNode(RISCVISD::VFIRST_VL,
DL, XLenVT, Vec, Mask, VL);
10448 if (NumElts >= 8) {
10450 unsigned WidenVecLen;
10453 unsigned MaxEEW = Subtarget.getELen();
10458 "the number of elements should be power of 2");
10462 ExtractBitIdx = Idx;
10464 WideEltVT = LargestEltVT;
10467 ExtractElementIdx = DAG.
getNode(
10476 Vec = DAG.
getNode(ISD::BITCAST,
DL, WideVT, Vec);
10478 Vec, ExtractElementIdx);
10493 if ((EltVT == MVT::f16 && !Subtarget.hasVInstructionsF16()) ||
10494 EltVT == MVT::bf16) {
10500 return DAG.
getNode(RISCVISD::FMV_H_X,
DL, EltVT, IntExtract);
10504 MVT ContainerVT = VecVT;
10514 const auto VLen = Subtarget.getRealVLen();
10516 IdxC && VLen && VecVT.
getSizeInBits().getKnownMinValue() > *VLen) {
10518 unsigned OrigIdx = IdxC->getZExtValue();
10521 unsigned RemIdx = OrigIdx % ElemsPerVReg;
10522 unsigned SubRegIdx = OrigIdx / ElemsPerVReg;
10523 unsigned ExtractIdx =
10527 ContainerVT = M1VT;
10532 std::optional<uint64_t> MaxIdx;
10536 MaxIdx = IdxC->getZExtValue();
10538 if (
auto SmallerVT =
10540 ContainerVT = *SmallerVT;
10547 if (Subtarget.hasVendorXRivosVisni() && EltVT.
isInteger() &&
10575 DAG.
getUNDEF(ContainerVT), Vec, Idx, Mask, VL);
10594 "Unexpected opcode");
10601 unsigned IntNo =
Op.getConstantOperandVal(HasChain ? 1 : 0);
10606 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo);
10607 if (!
II || !
II->hasScalarOperand())
10610 unsigned SplatOp =
II->ScalarOperand + 1 + HasChain;
10611 assert(SplatOp <
Op.getNumOperands());
10614 SDValue &ScalarOp = Operands[SplatOp];
10623 if (OpVT.
bitsLT(XLenVT)) {
10630 ScalarOp = DAG.
getNode(ExtOpc,
DL, XLenVT, ScalarOp);
10631 return DAG.
getNode(
Op->getOpcode(),
DL,
Op->getVTList(), Operands);
10640 assert(
II->ScalarOperand > 0 &&
"Unexpected splat operand!");
10641 MVT VT =
Op.getOperand(SplatOp - 1).getSimpleValueType();
10644 assert(XLenVT == MVT::i32 && OpVT == MVT::i64 &&
10651 return DAG.
getNode(
Op->getOpcode(),
DL,
Op->getVTList(), Operands);
10655 case Intrinsic::riscv_vslide1up:
10656 case Intrinsic::riscv_vslide1down:
10657 case Intrinsic::riscv_vslide1up_mask:
10658 case Intrinsic::riscv_vslide1down_mask: {
10660 unsigned NumOps =
Op.getNumOperands();
10661 bool IsMasked =
NumOps == 7;
10667 std::tie(ScalarLo, ScalarHi) =
10676 const auto [MinVLMAX, MaxVLMAX] =
10680 if (AVLInt <= MinVLMAX) {
10682 }
else if (AVLInt >= 2 * MaxVLMAX) {
10714 Passthru = DAG.
getBitcast(I32VT, Operands[1]);
10716 if (IntNo == Intrinsic::riscv_vslide1up ||
10717 IntNo == Intrinsic::riscv_vslide1up_mask) {
10718 Vec = DAG.
getNode(RISCVISD::VSLIDE1UP_VL,
DL, I32VT, Passthru, Vec,
10719 ScalarHi, I32Mask, I32VL);
10720 Vec = DAG.
getNode(RISCVISD::VSLIDE1UP_VL,
DL, I32VT, Passthru, Vec,
10721 ScalarLo, I32Mask, I32VL);
10723 Vec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32VT, Passthru, Vec,
10724 ScalarLo, I32Mask, I32VL);
10725 Vec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32VT, Passthru, Vec,
10726 ScalarHi, I32Mask, I32VL);
10736 SDValue MaskedOff = Operands[1];
10744 return DAG.
getNode(RISCVISD::VMERGE_VL,
DL, VT, Mask, Vec, MaskedOff,
10748 return DAG.
getNode(RISCVISD::VMERGE_VL,
DL, VT, Mask, Vec, MaskedOff,
10757 return DAG.
getNode(
Op->getOpcode(),
DL,
Op->getVTList(), Operands);
10775 const unsigned ElementWidth = 8;
10780 [[maybe_unused]]
unsigned MinVF =
10783 [[maybe_unused]]
unsigned VF =
N->getConstantOperandVal(2);
10787 bool Fractional = VF < LMul1VF;
10788 unsigned LMulVal = Fractional ? LMul1VF / VF : VF / LMul1VF;
10809 MVT ContainerVT = OpVT;
10817 SDValue Res = DAG.
getNode(RISCVISD::VFIRST_VL,
DL, XLenVT, Op0, Mask, VL);
10825 return DAG.
getSelect(
DL, XLenVT, Setcc, VL, Res);
10836 unsigned IntNo =
Op.getConstantOperandVal(HasChain ? 1 : 0);
10840 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo);
10841 if (!
II || !
II->hasScalarOperand())
10844 unsigned SplatOp =
II->ScalarOperand + 1;
10845 assert(SplatOp <
Op.getNumOperands());
10847 SDValue &ScalarOp = Operands[SplatOp];
10857 if (OpVT.
bitsLT(XLenVT)) {
10860 ScalarOp = DAG.
getNode(ExtOpc,
DL, XLenVT, ScalarOp);
10870 for (
SDValue &V : Operands) {
10871 EVT ValType = V.getValueType();
10872 if (ValType.isVector() && ValType.isFloatingPoint()) {
10875 ValType.getVectorElementCount());
10878 if (ValType.isFixedLengthVector()) {
10880 DAG, V.getSimpleValueType(), Subtarget);
10896 unsigned IntNo =
Op.getConstantOperandVal(0);
10898 MVT XLenVT = Subtarget.getXLenVT();
10903 case Intrinsic::riscv_tuple_insert: {
10908 return DAG.
getNode(RISCVISD::TUPLE_INSERT,
DL,
Op.getValueType(), Vec,
10911 case Intrinsic::riscv_tuple_extract: {
10915 return DAG.
getNode(RISCVISD::TUPLE_EXTRACT,
DL,
Op.getValueType(), Vec,
10918 case Intrinsic::thread_pointer: {
10922 case Intrinsic::riscv_orc_b:
10923 case Intrinsic::riscv_brev8:
10924 case Intrinsic::riscv_sha256sig0:
10925 case Intrinsic::riscv_sha256sig1:
10926 case Intrinsic::riscv_sha256sum0:
10927 case Intrinsic::riscv_sha256sum1:
10928 case Intrinsic::riscv_sm3p0:
10929 case Intrinsic::riscv_sm3p1: {
10932 case Intrinsic::riscv_orc_b:
Opc = RISCVISD::ORC_B;
break;
10933 case Intrinsic::riscv_brev8:
Opc = RISCVISD::BREV8;
break;
10934 case Intrinsic::riscv_sha256sig0:
Opc = RISCVISD::SHA256SIG0;
break;
10935 case Intrinsic::riscv_sha256sig1:
Opc = RISCVISD::SHA256SIG1;
break;
10936 case Intrinsic::riscv_sha256sum0:
Opc = RISCVISD::SHA256SUM0;
break;
10937 case Intrinsic::riscv_sha256sum1:
Opc = RISCVISD::SHA256SUM1;
break;
10938 case Intrinsic::riscv_sm3p0:
Opc = RISCVISD::SM3P0;
break;
10939 case Intrinsic::riscv_sm3p1:
Opc = RISCVISD::SM3P1;
break;
10944 case Intrinsic::riscv_sm4ks:
10945 case Intrinsic::riscv_sm4ed: {
10947 IntNo == Intrinsic::riscv_sm4ks ? RISCVISD::SM4KS : RISCVISD::SM4ED;
10952 case Intrinsic::riscv_zip:
10953 case Intrinsic::riscv_unzip: {
10955 IntNo == Intrinsic::riscv_zip ? RISCVISD::ZIP : RISCVISD::UNZIP;
10958 case Intrinsic::riscv_mopr:
10959 return DAG.
getNode(RISCVISD::MOP_R,
DL, XLenVT,
Op.getOperand(1),
10962 case Intrinsic::riscv_moprr: {
10963 return DAG.
getNode(RISCVISD::MOP_RR,
DL, XLenVT,
Op.getOperand(1),
10964 Op.getOperand(2),
Op.getOperand(3));
10966 case Intrinsic::riscv_clmul:
10967 return DAG.
getNode(RISCVISD::CLMUL,
DL, XLenVT,
Op.getOperand(1),
10969 case Intrinsic::riscv_clmulh:
10970 case Intrinsic::riscv_clmulr: {
10972 IntNo == Intrinsic::riscv_clmulh ? RISCVISD::CLMULH : RISCVISD::CLMULR;
10975 case Intrinsic::experimental_get_vector_length:
10977 case Intrinsic::experimental_cttz_elts:
10979 case Intrinsic::riscv_vmv_x_s: {
10983 case Intrinsic::riscv_vfmv_f_s:
10985 case Intrinsic::riscv_vmv_v_x:
10987 Op.getOperand(3),
Op.getSimpleValueType(),
DL, DAG,
10989 case Intrinsic::riscv_vfmv_v_f:
10990 return DAG.
getNode(RISCVISD::VFMV_V_F_VL,
DL,
Op.getValueType(),
10991 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
10992 case Intrinsic::riscv_vmv_s_x: {
10995 if (
Scalar.getValueType().bitsLE(XLenVT)) {
10997 return DAG.
getNode(RISCVISD::VMV_S_X_VL,
DL,
Op.getValueType(),
10998 Op.getOperand(1), Scalar,
Op.getOperand(3));
11001 assert(
Scalar.getValueType() == MVT::i64 &&
"Unexpected scalar VT!");
11018 MVT VT =
Op.getSimpleValueType();
11023 if (
Op.getOperand(1).isUndef())
11024 return SplattedVal;
11033 DAG.
getNode(RISCVISD::SETCC_VL,
DL, MaskVT,
11036 return DAG.
getNode(RISCVISD::VMERGE_VL,
DL, VT, SelectCond, SplattedVal,
11039 case Intrinsic::riscv_vfmv_s_f:
11040 return DAG.
getNode(RISCVISD::VFMV_S_F_VL,
DL,
Op.getSimpleValueType(),
11041 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
11043 case Intrinsic::riscv_vaesdf_vv:
11044 case Intrinsic::riscv_vaesdf_vs:
11045 case Intrinsic::riscv_vaesdm_vv:
11046 case Intrinsic::riscv_vaesdm_vs:
11047 case Intrinsic::riscv_vaesef_vv:
11048 case Intrinsic::riscv_vaesef_vs:
11049 case Intrinsic::riscv_vaesem_vv:
11050 case Intrinsic::riscv_vaesem_vs:
11051 case Intrinsic::riscv_vaeskf1:
11052 case Intrinsic::riscv_vaeskf2:
11053 case Intrinsic::riscv_vaesz_vs:
11054 case Intrinsic::riscv_vsm4k:
11055 case Intrinsic::riscv_vsm4r_vv:
11056 case Intrinsic::riscv_vsm4r_vs: {
11057 if (!
isValidEGW(4,
Op.getSimpleValueType(), Subtarget) ||
11058 !
isValidEGW(4,
Op->getOperand(1).getSimpleValueType(), Subtarget) ||
11059 !
isValidEGW(4,
Op->getOperand(2).getSimpleValueType(), Subtarget))
11064 case Intrinsic::riscv_vsm3c:
11065 case Intrinsic::riscv_vsm3me: {
11066 if (!
isValidEGW(8,
Op.getSimpleValueType(), Subtarget) ||
11067 !
isValidEGW(8,
Op->getOperand(1).getSimpleValueType(), Subtarget))
11072 case Intrinsic::riscv_vsha2ch:
11073 case Intrinsic::riscv_vsha2cl:
11074 case Intrinsic::riscv_vsha2ms: {
11075 if (
Op->getSimpleValueType(0).getScalarSizeInBits() == 64 &&
11076 !Subtarget.hasStdExtZvknhb())
11078 if (!
isValidEGW(4,
Op.getSimpleValueType(), Subtarget) ||
11079 !
isValidEGW(4,
Op->getOperand(1).getSimpleValueType(), Subtarget) ||
11080 !
isValidEGW(4,
Op->getOperand(2).getSimpleValueType(), Subtarget))
11084 case Intrinsic::riscv_sf_vc_v_x:
11085 case Intrinsic::riscv_sf_vc_v_i:
11086 case Intrinsic::riscv_sf_vc_v_xv:
11087 case Intrinsic::riscv_sf_vc_v_iv:
11088 case Intrinsic::riscv_sf_vc_v_vv:
11089 case Intrinsic::riscv_sf_vc_v_fv:
11090 case Intrinsic::riscv_sf_vc_v_xvv:
11091 case Intrinsic::riscv_sf_vc_v_ivv:
11092 case Intrinsic::riscv_sf_vc_v_vvv:
11093 case Intrinsic::riscv_sf_vc_v_fvv:
11094 case Intrinsic::riscv_sf_vc_v_xvw:
11095 case Intrinsic::riscv_sf_vc_v_ivw:
11096 case Intrinsic::riscv_sf_vc_v_vvw:
11097 case Intrinsic::riscv_sf_vc_v_fvw: {
11098 MVT VT =
Op.getSimpleValueType();
11135 MVT VT =
Op.getSimpleValueType();
11139 if (VT.isFloatingPoint()) {
11141 VT.getVectorElementCount());
11144 if (VT.isFixedLengthVector())
11154 if (VT.isFixedLengthVector())
11156 if (VT.isFloatingPoint())
11179 case Intrinsic::riscv_seg2_load_mask:
11180 case Intrinsic::riscv_seg3_load_mask:
11181 case Intrinsic::riscv_seg4_load_mask:
11182 case Intrinsic::riscv_seg5_load_mask:
11183 case Intrinsic::riscv_seg6_load_mask:
11184 case Intrinsic::riscv_seg7_load_mask:
11185 case Intrinsic::riscv_seg8_load_mask:
11188 case Intrinsic::riscv_sseg2_load_mask:
11189 case Intrinsic::riscv_sseg3_load_mask:
11190 case Intrinsic::riscv_sseg4_load_mask:
11191 case Intrinsic::riscv_sseg5_load_mask:
11192 case Intrinsic::riscv_sseg6_load_mask:
11193 case Intrinsic::riscv_sseg7_load_mask:
11194 case Intrinsic::riscv_sseg8_load_mask:
11202 Intrinsic::riscv_vlseg2_mask, Intrinsic::riscv_vlseg3_mask,
11203 Intrinsic::riscv_vlseg4_mask, Intrinsic::riscv_vlseg5_mask,
11204 Intrinsic::riscv_vlseg6_mask, Intrinsic::riscv_vlseg7_mask,
11205 Intrinsic::riscv_vlseg8_mask};
11207 Intrinsic::riscv_vlsseg2_mask, Intrinsic::riscv_vlsseg3_mask,
11208 Intrinsic::riscv_vlsseg4_mask, Intrinsic::riscv_vlsseg5_mask,
11209 Intrinsic::riscv_vlsseg6_mask, Intrinsic::riscv_vlsseg7_mask,
11210 Intrinsic::riscv_vlsseg8_mask};
11213 unsigned NF =
Op->getNumValues() - 1;
11214 assert(NF >= 2 && NF <= 8 &&
"Unexpected seg number");
11216 MVT VT =
Op->getSimpleValueType(0);
11224 SDValue VL =
Op.getOperand(
Op.getNumOperands() - 1);
11225 SDValue Mask =
Op.getOperand(
Op.getNumOperands() - 2);
11226 MVT MaskVT = Mask.getSimpleValueType();
11227 MVT MaskContainerVT =
11232 IsStrided ? VlssegInts[NF - 2] : VlsegInts[NF - 2],
DL, XLenVT);
11248 Ops.insert(std::next(
Ops.begin(), 4),
Op.getOperand(3));
11252 Load->getMemoryVT(), Load->getMemOperand());
11254 for (
unsigned int RetIdx = 0; RetIdx < NF; RetIdx++) {
11256 Result.getValue(0),
11260 Results.push_back(Result.getValue(1));
11266 unsigned IntNo =
Op.getConstantOperandVal(1);
11270 case Intrinsic::riscv_seg2_load_mask:
11271 case Intrinsic::riscv_seg3_load_mask:
11272 case Intrinsic::riscv_seg4_load_mask:
11273 case Intrinsic::riscv_seg5_load_mask:
11274 case Intrinsic::riscv_seg6_load_mask:
11275 case Intrinsic::riscv_seg7_load_mask:
11276 case Intrinsic::riscv_seg8_load_mask:
11277 case Intrinsic::riscv_sseg2_load_mask:
11278 case Intrinsic::riscv_sseg3_load_mask:
11279 case Intrinsic::riscv_sseg4_load_mask:
11280 case Intrinsic::riscv_sseg5_load_mask:
11281 case Intrinsic::riscv_sseg6_load_mask:
11282 case Intrinsic::riscv_sseg7_load_mask:
11283 case Intrinsic::riscv_sseg8_load_mask:
11286 case Intrinsic::riscv_sf_vc_v_x_se:
11288 case Intrinsic::riscv_sf_vc_v_i_se:
11290 case Intrinsic::riscv_sf_vc_v_xv_se:
11292 case Intrinsic::riscv_sf_vc_v_iv_se:
11294 case Intrinsic::riscv_sf_vc_v_vv_se:
11296 case Intrinsic::riscv_sf_vc_v_fv_se:
11298 case Intrinsic::riscv_sf_vc_v_xvv_se:
11300 case Intrinsic::riscv_sf_vc_v_ivv_se:
11302 case Intrinsic::riscv_sf_vc_v_vvv_se:
11304 case Intrinsic::riscv_sf_vc_v_fvv_se:
11306 case Intrinsic::riscv_sf_vc_v_xvw_se:
11308 case Intrinsic::riscv_sf_vc_v_ivw_se:
11310 case Intrinsic::riscv_sf_vc_v_vvw_se:
11312 case Intrinsic::riscv_sf_vc_v_fvw_se:
11325 case Intrinsic::riscv_seg2_store_mask:
11326 case Intrinsic::riscv_seg3_store_mask:
11327 case Intrinsic::riscv_seg4_store_mask:
11328 case Intrinsic::riscv_seg5_store_mask:
11329 case Intrinsic::riscv_seg6_store_mask:
11330 case Intrinsic::riscv_seg7_store_mask:
11331 case Intrinsic::riscv_seg8_store_mask:
11334 case Intrinsic::riscv_sseg2_store_mask:
11335 case Intrinsic::riscv_sseg3_store_mask:
11336 case Intrinsic::riscv_sseg4_store_mask:
11337 case Intrinsic::riscv_sseg5_store_mask:
11338 case Intrinsic::riscv_sseg6_store_mask:
11339 case Intrinsic::riscv_sseg7_store_mask:
11340 case Intrinsic::riscv_sseg8_store_mask:
11349 Intrinsic::riscv_vsseg2_mask, Intrinsic::riscv_vsseg3_mask,
11350 Intrinsic::riscv_vsseg4_mask, Intrinsic::riscv_vsseg5_mask,
11351 Intrinsic::riscv_vsseg6_mask, Intrinsic::riscv_vsseg7_mask,
11352 Intrinsic::riscv_vsseg8_mask};
11354 Intrinsic::riscv_vssseg2_mask, Intrinsic::riscv_vssseg3_mask,
11355 Intrinsic::riscv_vssseg4_mask, Intrinsic::riscv_vssseg5_mask,
11356 Intrinsic::riscv_vssseg6_mask, Intrinsic::riscv_vssseg7_mask,
11357 Intrinsic::riscv_vssseg8_mask};
11361 unsigned NF =
Op->getNumOperands() - (IsStrided ? 6 : 5);
11362 assert(NF >= 2 && NF <= 8 &&
"Unexpected seg number");
11364 MVT VT =
Op->getOperand(2).getSimpleValueType();
11370 SDValue VL =
Op.getOperand(
Op.getNumOperands() - 1);
11371 SDValue Mask =
Op.getOperand(
Op.getNumOperands() - 2);
11372 MVT MaskVT = Mask.getSimpleValueType();
11373 MVT MaskContainerVT =
11378 IsStrided ? VsssegInts[NF - 2] : VssegInts[NF - 2],
DL, XLenVT);
11384 for (
unsigned i = 0; i < NF; i++)
11386 RISCVISD::TUPLE_INSERT,
DL, VecTupTy, StoredVal,
11392 FixedIntrinsic->getChain(),
11401 Ops.insert(std::next(
Ops.begin(), 4),
11402 Op.getOperand(
Op.getNumOperands() - 3));
11406 FixedIntrinsic->getMemoryVT(), FixedIntrinsic->getMemOperand());
11411 unsigned IntNo =
Op.getConstantOperandVal(1);
11415 case Intrinsic::riscv_seg2_store_mask:
11416 case Intrinsic::riscv_seg3_store_mask:
11417 case Intrinsic::riscv_seg4_store_mask:
11418 case Intrinsic::riscv_seg5_store_mask:
11419 case Intrinsic::riscv_seg6_store_mask:
11420 case Intrinsic::riscv_seg7_store_mask:
11421 case Intrinsic::riscv_seg8_store_mask:
11422 case Intrinsic::riscv_sseg2_store_mask:
11423 case Intrinsic::riscv_sseg3_store_mask:
11424 case Intrinsic::riscv_sseg4_store_mask:
11425 case Intrinsic::riscv_sseg5_store_mask:
11426 case Intrinsic::riscv_sseg6_store_mask:
11427 case Intrinsic::riscv_sseg7_store_mask:
11428 case Intrinsic::riscv_sseg8_store_mask:
11431 case Intrinsic::riscv_sf_vc_xv_se:
11433 case Intrinsic::riscv_sf_vc_iv_se:
11435 case Intrinsic::riscv_sf_vc_vv_se:
11437 case Intrinsic::riscv_sf_vc_fv_se:
11439 case Intrinsic::riscv_sf_vc_xvv_se:
11441 case Intrinsic::riscv_sf_vc_ivv_se:
11443 case Intrinsic::riscv_sf_vc_vvv_se:
11445 case Intrinsic::riscv_sf_vc_fvv_se:
11447 case Intrinsic::riscv_sf_vc_xvw_se:
11449 case Intrinsic::riscv_sf_vc_ivw_se:
11451 case Intrinsic::riscv_sf_vc_vvw_se:
11453 case Intrinsic::riscv_sf_vc_fvw_se:
11461 switch (ISDOpcode) {
11464 case ISD::VP_REDUCE_ADD:
11465 case ISD::VECREDUCE_ADD:
11466 return RISCVISD::VECREDUCE_ADD_VL;
11467 case ISD::VP_REDUCE_UMAX:
11468 case ISD::VECREDUCE_UMAX:
11469 return RISCVISD::VECREDUCE_UMAX_VL;
11470 case ISD::VP_REDUCE_SMAX:
11471 case ISD::VECREDUCE_SMAX:
11472 return RISCVISD::VECREDUCE_SMAX_VL;
11473 case ISD::VP_REDUCE_UMIN:
11474 case ISD::VECREDUCE_UMIN:
11475 return RISCVISD::VECREDUCE_UMIN_VL;
11476 case ISD::VP_REDUCE_SMIN:
11477 case ISD::VECREDUCE_SMIN:
11478 return RISCVISD::VECREDUCE_SMIN_VL;
11479 case ISD::VP_REDUCE_AND:
11480 case ISD::VECREDUCE_AND:
11481 return RISCVISD::VECREDUCE_AND_VL;
11482 case ISD::VP_REDUCE_OR:
11483 case ISD::VECREDUCE_OR:
11484 return RISCVISD::VECREDUCE_OR_VL;
11485 case ISD::VP_REDUCE_XOR:
11486 case ISD::VECREDUCE_XOR:
11487 return RISCVISD::VECREDUCE_XOR_VL;
11488 case ISD::VP_REDUCE_FADD:
11489 return RISCVISD::VECREDUCE_FADD_VL;
11490 case ISD::VP_REDUCE_SEQ_FADD:
11491 return RISCVISD::VECREDUCE_SEQ_FADD_VL;
11492 case ISD::VP_REDUCE_FMAX:
11493 case ISD::VP_REDUCE_FMAXIMUM:
11494 return RISCVISD::VECREDUCE_FMAX_VL;
11495 case ISD::VP_REDUCE_FMIN:
11496 case ISD::VP_REDUCE_FMINIMUM:
11497 return RISCVISD::VECREDUCE_FMIN_VL;
11506 SDValue Vec =
Op.getOperand(IsVP ? 1 : 0);
11508 assert((
Op.getOpcode() == ISD::VECREDUCE_AND ||
11509 Op.getOpcode() == ISD::VECREDUCE_OR ||
11510 Op.getOpcode() == ISD::VECREDUCE_XOR ||
11511 Op.getOpcode() == ISD::VP_REDUCE_AND ||
11512 Op.getOpcode() == ISD::VP_REDUCE_OR ||
11513 Op.getOpcode() == ISD::VP_REDUCE_XOR) &&
11514 "Unexpected reduction lowering");
11516 MVT XLenVT = Subtarget.getXLenVT();
11518 MVT ContainerVT = VecVT;
11526 Mask =
Op.getOperand(2);
11527 VL =
Op.getOperand(3);
11529 std::tie(Mask, VL) =
11534 switch (
Op.getOpcode()) {
11537 case ISD::VECREDUCE_AND:
11538 case ISD::VP_REDUCE_AND: {
11542 Vec = DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Vec, TrueMask, VL);
11545 Vec = DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, Vec, Mask, VL);
11549 case ISD::VECREDUCE_OR:
11550 case ISD::VP_REDUCE_OR:
11552 Vec = DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, Vec, Mask, VL);
11555 case ISD::VECREDUCE_XOR:
11556 case ISD::VP_REDUCE_XOR: {
11559 Vec = DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, Vec, Mask, VL);
11580 return DAG.
getNode(BaseOpc,
DL,
Op.getValueType(), SetCC,
Op.getOperand(0));
11586 return (RegisterAVL && RegisterAVL->getReg() == RISCV::X0) ||
11587 (ImmAVL && ImmAVL->getZExtValue() >= 1);
11603 auto InnerVT = VecVT.
bitsLE(M1VT) ? VecVT : M1VT;
11607 auto InnerVL = NonZeroAVL ? VL : DAG.
getConstant(1,
DL, XLenVT);
11610 if (M1VT != InnerVT)
11615 SDValue Ops[] = {PassThru, Vec, InitialValue, Mask, VL, Policy};
11633 VecEVT =
Lo.getValueType();
11646 MVT ContainerVT = VecVT;
11665 Mask, VL,
DL, DAG, Subtarget);
11671static std::tuple<unsigned, SDValue, SDValue>
11675 auto Flags =
Op->getFlags();
11676 unsigned Opcode =
Op.getOpcode();
11680 case ISD::VECREDUCE_FADD: {
11684 return std::make_tuple(RISCVISD::VECREDUCE_FADD_VL,
Op.getOperand(0), Zero);
11686 case ISD::VECREDUCE_SEQ_FADD:
11687 return std::make_tuple(RISCVISD::VECREDUCE_SEQ_FADD_VL,
Op.getOperand(1),
11689 case ISD::VECREDUCE_FMINIMUM:
11690 case ISD::VECREDUCE_FMAXIMUM:
11691 case ISD::VECREDUCE_FMIN:
11692 case ISD::VECREDUCE_FMAX: {
11695 (Opcode == ISD::VECREDUCE_FMIN || Opcode == ISD::VECREDUCE_FMINIMUM)
11696 ? RISCVISD::VECREDUCE_FMIN_VL
11697 : RISCVISD::VECREDUCE_FMAX_VL;
11698 return std::make_tuple(RVVOpc,
Op.getOperand(0), Front);
11706 MVT VecEltVT =
Op.getSimpleValueType();
11708 unsigned RVVOpcode;
11709 SDValue VectorVal, ScalarVal;
11710 std::tie(RVVOpcode, VectorVal, ScalarVal) =
11714 MVT ContainerVT = VecVT;
11720 MVT ResVT =
Op.getSimpleValueType();
11723 VL,
DL, DAG, Subtarget);
11724 if (
Op.getOpcode() != ISD::VECREDUCE_FMINIMUM &&
11725 Op.getOpcode() != ISD::VECREDUCE_FMAXIMUM)
11728 if (
Op->getFlags().hasNoNaNs())
11734 {VectorVal, VectorVal, DAG.getCondCode(ISD::SETNE),
11735 DAG.getUNDEF(Mask.getValueType()), Mask, VL});
11736 MVT XLenVT = Subtarget.getXLenVT();
11737 SDValue CPop = DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, IsNan, Mask, VL);
11741 DL, ResVT, NoNaNs, Res,
11748 unsigned Opc =
Op.getOpcode();
11752 MVT XLenVT = Subtarget.getXLenVT();
11771 Vec, Mask, VL,
DL, DAG, Subtarget);
11772 if ((
Opc != ISD::VP_REDUCE_FMINIMUM &&
Opc != ISD::VP_REDUCE_FMAXIMUM) ||
11773 Op->getFlags().hasNoNaNs())
11780 RISCVISD::SETCC_VL,
DL, PredVT,
11782 SDValue VCPop = DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, IsNaN, Mask, VL);
11790 DL, ResVT, NoNaNs, Res,
11802 MVT XLenVT = Subtarget.getXLenVT();
11803 unsigned OrigIdx =
Op.getConstantOperandVal(2);
11804 const RISCVRegisterInfo *
TRI = Subtarget.getRegisterInfo();
11806 if (OrigIdx == 0 && Vec.
isUndef())
11817 assert(OrigIdx % 8 == 0 &&
"Invalid index");
11820 "Unexpected mask vector lowering");
11850 const auto VLen = Subtarget.getRealVLen();
11852 MVT ContainerVT = VecVT;
11874 if (OrigIdx == 0) {
11876 DAG.
getNode(RISCVISD::VMV_V_V_VL,
DL, ContainerVT, Vec, SubVec, VL);
11879 SubVec =
getVSlideup(DAG, Subtarget,
DL, ContainerVT, Vec, SubVec,
11880 SlideupAmt, Mask, VL, Policy);
11888 MVT ContainerVecVT = VecVT;
11894 MVT ContainerSubVecVT = SubVecVT;
11900 unsigned SubRegIdx;
11901 ElementCount RemIdx;
11910 ContainerVecVT, ContainerSubVecVT, OrigIdx / Vscale,
TRI);
11911 SubRegIdx = Decompose.first;
11913 (OrigIdx % Vscale));
11917 ContainerVecVT, ContainerSubVecVT, OrigIdx,
TRI);
11918 SubRegIdx = Decompose.first;
11924 Subtarget.expandVScale(SubVecVT.
getSizeInBits()).getKnownMinValue()));
11925 bool ExactlyVecRegSized =
11927 .isKnownMultipleOf(Subtarget.expandVScale(VecRegSize));
11942 if (RemIdx.
isZero() && (ExactlyVecRegSized || Vec.
isUndef())) {
11946 if (SubRegIdx == RISCV::NoSubRegister) {
11968 MVT InterSubVT = ContainerVecVT;
11969 SDValue AlignedExtract = Vec;
11991 if (Subtarget.expandVScale(EndIndex) ==
11998 SubVec = DAG.
getNode(RISCVISD::VMV_V_V_VL,
DL, InterSubVT, AlignedExtract,
12006 SubVec =
getVSlideup(DAG, Subtarget,
DL, InterSubVT, AlignedExtract, SubVec,
12007 SlideupAmt, Mask, VL, Policy);
12012 if (ContainerVecVT.
bitsGT(InterSubVT))
12020 return DAG.
getBitcast(
Op.getSimpleValueType(), SubVec);
12026 MVT SubVecVT =
Op.getSimpleValueType();
12030 MVT XLenVT = Subtarget.getXLenVT();
12031 unsigned OrigIdx =
Op.getConstantOperandVal(1);
12032 const RISCVRegisterInfo *
TRI = Subtarget.getRegisterInfo();
12047 assert(OrigIdx % 8 == 0 &&
"Invalid index");
12050 "Unexpected mask vector lowering");
12076 const auto VLen = Subtarget.getRealVLen();
12084 MVT ContainerVT = VecVT;
12092 if (
auto ShrunkVT =
12094 ContainerVT = *ShrunkVT;
12106 DAG.
getUNDEF(ContainerVT), Vec, SlidedownAmt, Mask, VL);
12117 MVT ContainerSubVecVT = SubVecVT;
12121 unsigned SubRegIdx;
12122 ElementCount RemIdx;
12131 VecVT, ContainerSubVecVT, OrigIdx / Vscale,
TRI);
12132 SubRegIdx = Decompose.first;
12134 (OrigIdx % Vscale));
12138 VecVT, ContainerSubVecVT, OrigIdx,
TRI);
12139 SubRegIdx = Decompose.first;
12166 MVT InterSubVT = VecVT;
12171 assert(SubRegIdx != RISCV::NoSubRegister);
12190 Vec, SlidedownAmt, Mask, VL);
12198 return DAG.
getBitcast(
Op.getSimpleValueType(), Slidedown);
12205 MVT VT =
N.getSimpleValueType();
12209 assert(
Op.getSimpleValueType() == VT &&
12210 "Operands and result must be same type");
12214 unsigned NumVals =
N->getNumValues();
12217 NumVals,
N.getValueType().changeVectorElementType(MVT::i8)));
12220 for (
unsigned I = 0;
I < NumVals;
I++) {
12226 if (TruncVals.
size() > 1)
12228 return TruncVals.
front();
12234 MVT VecVT =
Op.getSimpleValueType();
12236 const unsigned Factor =
Op->getNumValues();
12247 for (
unsigned i = 0U; i < Factor; ++i)
12256 for (
unsigned i = 0U; i < Factor; ++i)
12266 for (
unsigned i = 0; i != Factor; ++i) {
12269 Ops[i * 2 + 1] = OpHi;
12280 for (
unsigned i = 0; i != Factor; ++i)
12287 if (Subtarget.hasVendorXRivosVizip() && Factor == 2) {
12288 MVT VT =
Op->getSimpleValueType(0);
12313 lowerVZIP(RISCVISD::RI_VUNZIP2A_VL, V1, V2,
DL, DAG, Subtarget);
12315 lowerVZIP(RISCVISD::RI_VUNZIP2B_VL, V1, V2,
DL, DAG, Subtarget);
12348 EvenSplat = DAG.
getBitcast(MVT::nxv64i1, EvenSplat);
12352 OddSplat = DAG.
getBitcast(MVT::nxv64i1, OddSplat);
12357 EvenMask, DAG.
getUNDEF(ConcatVT));
12369 MVT XLenVT = Subtarget.getXLenVT();
12391 Intrinsic::riscv_vlseg2_mask, Intrinsic::riscv_vlseg3_mask,
12392 Intrinsic::riscv_vlseg4_mask, Intrinsic::riscv_vlseg5_mask,
12393 Intrinsic::riscv_vlseg6_mask, Intrinsic::riscv_vlseg7_mask,
12394 Intrinsic::riscv_vlseg8_mask};
12418 for (
unsigned i = 0U; i < Factor; ++i)
12419 Res[i] = DAG.
getNode(RISCVISD::TUPLE_EXTRACT,
DL, VecVT, Load,
12428 MVT VecVT =
Op.getSimpleValueType();
12441 for (
unsigned i = 0U; i < Factor; ++i)
12449 for (
unsigned i = 0U; i < Factor; ++i)
12455 MVT XLenVT = Subtarget.getXLenVT();
12462 for (
unsigned i = 0; i != Factor; ++i) {
12465 Ops[i + Factor] = OpHi;
12476 for (
unsigned i = 0; i != Factor; ++i) {
12477 unsigned IdxLo = 2 * i;
12478 unsigned IdxHi = 2 * i + 1;
12480 Res[IdxLo / Factor].getValue(IdxLo % Factor),
12481 Res[IdxHi / Factor].getValue(IdxHi % Factor));
12499 EVT PtrVT =
StackPtr.getValueType();
12505 Intrinsic::riscv_vsseg2_mask, Intrinsic::riscv_vsseg3_mask,
12506 Intrinsic::riscv_vsseg4_mask, Intrinsic::riscv_vsseg5_mask,
12507 Intrinsic::riscv_vsseg6_mask, Intrinsic::riscv_vsseg7_mask,
12508 Intrinsic::riscv_vsseg8_mask,
12516 for (
unsigned i = 0; i < Factor; i++)
12518 DAG.
getNode(RISCVISD::TUPLE_INSERT,
DL, VecTupTy, StoredVal,
12541 for (
unsigned i = 0; i != Factor; ++i) {
12545 Loads[i] = DAG.
getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
12553 if (Subtarget.hasVendorXRivosVizip() && !
Op.getOperand(0).isUndef() &&
12554 !
Op.getOperand(1).isUndef()) {
12574 Op.getOperand(0),
Op.getOperand(1));
12598 DAG.
getNode(RISCVISD::ADD_VL,
DL, IdxVT, Idx, VLMax, Idx, OddMask, VL);
12603 Interleaved = DAG.
getNode(RISCVISD::VRGATHEREI16_VV_VL,
DL, ConcatVT,
12620 MVT VT =
Op.getSimpleValueType();
12622 MVT XLenVT = Subtarget.getXLenVT();
12625 uint64_t StepValImm =
Op.getConstantOperandVal(0);
12626 if (StepValImm != 1) {
12635 VL, VT,
DL, DAG, Subtarget);
12650 MVT VecVT =
Op.getSimpleValueType();
12659 MVT ContainerVT = VecVT;
12666 MVT XLenVT = Subtarget.getXLenVT();
12712 unsigned VectorBitsMax = Subtarget.getRealMaxVLen();
12713 unsigned MaxVLMAX =
12718 unsigned GatherOpc = RISCVISD::VRGATHER_VV_VL;
12723 if (MaxVLMAX > 256 && EltSize == 8) {
12739 GatherOpc = RISCVISD::VRGATHEREI16_VV_VL;
12747 GatherOpc = RISCVISD::VRGATHEREI16_VV_VL;
12772 DAG.
getUNDEF(ContainerVT), Mask, VL);
12783 MVT XLenVT = Subtarget.getXLenVT();
12784 MVT VecVT =
Op.getSimpleValueType();
12789 SDValue DownOffset, UpOffset;
12790 if (ImmValue >= 0) {
12805 DAG, Subtarget,
DL, VecVT, DAG.
getUNDEF(VecVT), V1, DownOffset, TrueMask,
12806 Subtarget.hasVLDependentLatency() ? UpOffset
12808 return getVSlideup(DAG, Subtarget,
DL, VecVT, SlideDown, V2, UpOffset,
12814RISCVTargetLowering::lowerFixedLengthVectorLoadToRVV(
SDValue Op,
12820 Load->getMemoryVT(),
12821 *
Load->getMemOperand()) &&
12822 "Expecting a correctly-aligned load");
12824 MVT VT =
Op.getSimpleValueType();
12825 MVT XLenVT = Subtarget.getXLenVT();
12830 const auto [MinVLMAX, MaxVLMAX] =
12834 MachineMemOperand *MMO =
Load->getMemOperand();
12847 IsMaskOp ? Intrinsic::riscv_vlm : Intrinsic::riscv_vle,
DL, XLenVT);
12851 Ops.push_back(
Load->getBasePtr());
12853 SDVTList VTs = DAG.
getVTList({ContainerVT, MVT::Other});
12856 Load->getMemoryVT(),
Load->getMemOperand());
12863RISCVTargetLowering::lowerFixedLengthVectorStoreToRVV(
SDValue Op,
12869 Store->getMemoryVT(),
12870 *
Store->getMemOperand()) &&
12871 "Expecting a correctly-aligned store");
12875 MVT XLenVT = Subtarget.getXLenVT();
12891 const auto [MinVLMAX, MaxVLMAX] =
12895 MachineMemOperand *MMO =
Store->getMemOperand();
12905 IsMaskOp ? Intrinsic::riscv_vsm : Intrinsic::riscv_vse,
DL, XLenVT);
12908 {Store->getChain(), IntID, NewValue, Store->getBasePtr(), VL},
12909 Store->getMemoryVT(),
Store->getMemOperand());
12915 MVT VT =
Op.getSimpleValueType();
12918 EVT MemVT = MemSD->getMemoryVT();
12919 MachineMemOperand *MMO = MemSD->getMemOperand();
12920 SDValue Chain = MemSD->getChain();
12924 bool IsExpandingLoad =
false;
12926 Mask = VPLoad->getMask();
12928 VL = VPLoad->getVectorLength();
12931 Mask = MLoad->getMask();
12932 PassThru = MLoad->getPassThru();
12933 IsExpandingLoad = MLoad->isExpandingLoad();
12938 MVT XLenVT = Subtarget.getXLenVT();
12940 MVT ContainerVT = VT;
12954 if (!IsUnmasked && IsExpandingLoad) {
12957 DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, Mask,
12961 unsigned IntID = IsUnmasked || IsExpandingLoad ? Intrinsic::riscv_vle
12962 : Intrinsic::riscv_vle_mask;
12964 if (IntID == Intrinsic::riscv_vle)
12967 Ops.push_back(PassThru);
12968 Ops.push_back(BasePtr);
12969 if (IntID == Intrinsic::riscv_vle_mask)
12970 Ops.push_back(Mask);
12972 if (IntID == Intrinsic::riscv_vle_mask)
12975 SDVTList VTs = DAG.
getVTList({ContainerVT, MVT::Other});
12979 Chain =
Result.getValue(1);
12981 MVT IndexVT = ContainerVT;
12986 bool UseVRGATHEREI16 =
false;
12994 UseVRGATHEREI16 =
true;
13000 DAG.
getUNDEF(IndexVT), Mask, ExpandingVL);
13002 DAG.
getNode(UseVRGATHEREI16 ? RISCVISD::VRGATHEREI16_VV_VL
13003 : RISCVISD::VRGATHER_VV_VL,
13004 DL, ContainerVT, Result, Iota, PassThru, Mask, ExpandingVL);
13015 MVT VT =
Op->getSimpleValueType(0);
13018 EVT MemVT = VPLoadFF->getMemoryVT();
13019 MachineMemOperand *MMO = VPLoadFF->getMemOperand();
13020 SDValue Chain = VPLoadFF->getChain();
13024 SDValue VL = VPLoadFF->getVectorLength();
13026 MVT XLenVT = Subtarget.getXLenVT();
13028 MVT ContainerVT = VT;
13035 unsigned IntID = Intrinsic::riscv_vleff_mask;
13045 SDVTList VTs = DAG.
getVTList({ContainerVT,
Op->getValueType(1), MVT::Other});
13050 Chain =
Result.getValue(2);
13063 EVT MemVT = MemSD->getMemoryVT();
13064 MachineMemOperand *MMO = MemSD->getMemOperand();
13065 SDValue Chain = MemSD->getChain();
13069 bool IsCompressingStore =
false;
13071 Val = VPStore->getValue();
13072 Mask = VPStore->getMask();
13073 VL = VPStore->getVectorLength();
13076 Val = MStore->getValue();
13077 Mask = MStore->getMask();
13078 IsCompressingStore = MStore->isCompressingStore();
13085 MVT XLenVT = Subtarget.getXLenVT();
13087 MVT ContainerVT = VT;
13092 if (!IsUnmasked || IsCompressingStore) {
13101 if (IsCompressingStore) {
13104 DAG.
getUNDEF(ContainerVT), Val, Mask, VL);
13106 DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, Mask,
13111 IsUnmasked ? Intrinsic::riscv_vse : Intrinsic::riscv_vse_mask;
13113 Ops.push_back(Val);
13114 Ops.push_back(BasePtr);
13116 Ops.push_back(Mask);
13131 MVT XLenVT = Subtarget.getXLenVT();
13132 MVT ContainerVT = VT;
13145 Passthru, Val, Mask, VL);
13155 unsigned Opc =
Op.getOpcode();
13162 MVT VT =
Op.getSimpleValueType();
13170 SDVTList VTList =
Op->getVTList();
13195 MVT ContainerInVT = InVT;
13213 RISCVISD::STRICT_FSETCC_VL,
DL, DAG.
getVTList(MaskVT, MVT::Other),
13214 {Chain, Op1, Op1, DAG.getCondCode(ISD::SETOEQ), DAG.getUNDEF(MaskVT),
13217 RISCVISD::STRICT_FSETCC_VL,
DL, DAG.
getVTList(MaskVT, MVT::Other),
13218 {Chain, Op2, Op2, DAG.getCondCode(ISD::SETOEQ), DAG.getUNDEF(MaskVT),
13221 DAG.
getNode(RISCVISD::VMAND_VL,
DL, MaskVT, OrderMask1, OrderMask2, VL);
13224 Res = DAG.
getNode(RISCVISD::STRICT_FSETCCS_VL,
DL,
13226 {Chain, Op1, Op2, CC, Mask, Mask, VL});
13229 : RISCVISD::STRICT_FSETCCS_VL;
13231 {Chain, Op1, Op2, CC, DAG.getUNDEF(MaskVT), Mask, VL});
13244 MVT VT =
Op.getSimpleValueType();
13248 "Unexpected type for ISD::ABS");
13250 MVT ContainerVT = VT;
13257 if (
Op->getOpcode() == ISD::VP_ABS) {
13258 Mask =
Op->getOperand(1);
13262 VL =
Op->getOperand(2);
13267 RISCVISD::VMV_V_X_VL,
DL, ContainerVT, DAG.
getUNDEF(ContainerVT),
13270 DAG.
getUNDEF(ContainerVT), Mask, VL);
13272 DAG.
getUNDEF(ContainerVT), Mask, VL);
13281 const auto &TSInfo =
13285 bool HasPassthruOp = TSInfo.hasPassthruOp(NewOpc);
13286 bool HasMask = TSInfo.hasMaskOp(NewOpc);
13288 MVT VT =
Op.getSimpleValueType();
13293 for (
const SDValue &V :
Op->op_values()) {
13297 if (!
V.getValueType().isVector()) {
13303 assert(useRVVForFixedLengthVectorVT(
V.getSimpleValueType()) &&
13304 "Only fixed length vectors are supported!");
13306 V.getSimpleValueType().getVectorElementType());
13315 Ops.push_back(Mask);
13320 if (
Op->isStrictFPOpcode()) {
13339 const auto &TSInfo =
13343 bool HasPassthruOp = TSInfo.hasPassthruOp(RISCVISDOpc);
13346 MVT VT =
Op.getSimpleValueType();
13349 MVT ContainerVT = VT;
13358 if (HasPassthruOp) {
13361 if (*MaskIdx ==
OpIdx.index())
13365 if (
Op.getOpcode() == ISD::VP_MERGE) {
13367 Ops.push_back(
Ops.back());
13369 assert(
Op.getOpcode() == ISD::VP_SELECT);
13376 if (RISCVISDOpc == RISCVISD::VFCVT_RM_X_F_VL &&
13379 Subtarget.getXLenVT()));
13381 if (!
V.getValueType().isFixedLengthVector()) {
13386 MVT OpVT =
V.getSimpleValueType();
13388 assert(useRVVForFixedLengthVectorVT(OpVT) &&
13389 "Only fixed length vectors are supported!");
13404 MVT VT =
Op.getSimpleValueType();
13410 MVT ContainerVT = VT;
13417 MVT XLenVT = Subtarget.getXLenVT();
13420 DAG.
getUNDEF(ContainerVT), Zero, VL);
13423 Op.getOpcode() == ISD::VP_ZERO_EXTEND ? 1 : -1,
DL, XLenVT);
13425 DAG.
getUNDEF(ContainerVT), SplatValue, VL);
13428 ZeroSplat, DAG.
getUNDEF(ContainerVT), VL);
13437 MVT VT =
Op.getSimpleValueType();
13445 MVT ContainerVT = VT;
13453 SDValue AllOneMask = DAG.
getNode(RISCVISD::VMSET_VL,
DL, ContainerVT, VL);
13455 switch (Condition) {
13460 Result = DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Op1, Op2, VL);
13465 DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Op1, Op2, VL);
13467 DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Temp, AllOneMask, VL);
13475 DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Op1, AllOneMask, VL);
13476 Result = DAG.
getNode(RISCVISD::VMAND_VL,
DL, ContainerVT, Temp, Op2, VL);
13484 DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Op2, AllOneMask, VL);
13485 Result = DAG.
getNode(RISCVISD::VMAND_VL,
DL, ContainerVT, Op1, Temp, VL);
13493 DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Op1, AllOneMask, VL);
13494 Result = DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Temp, Op2, VL);
13502 DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Op2, AllOneMask, VL);
13503 Result = DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Temp, Op1, VL);
13523 MVT DstVT =
Op.getSimpleValueType();
13524 MVT SrcVT = Src.getSimpleValueType();
13537 if (DstEltSize >= SrcEltSize) {
13541 unsigned RISCVISDExtOpc = RISCVISDOpc == RISCVISD::SINT_TO_FP_VL
13542 ? RISCVISD::VSEXT_VL
13543 : RISCVISD::VZEXT_VL;
13546 if (SrcEltSize == 1) {
13548 MVT XLenVT = Subtarget.getXLenVT();
13553 RISCVISDExtOpc == RISCVISD::VZEXT_VL ? 1 : -1,
DL, XLenVT);
13556 Src = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, IntVT, Src, OneSplat,
13557 ZeroSplat, DAG.
getUNDEF(IntVT), VL);
13558 }
else if (DstEltSize > (2 * SrcEltSize)) {
13562 Src = DAG.
getNode(RISCVISDExtOpc,
DL, IntVT, Src, Mask, VL);
13568 "Wrong input/output vector types");
13571 if (DstEltSize > (2 * SrcEltSize)) {
13576 DAG.
getNode(RISCVISD::FP_EXTEND_VL,
DL, InterimFVT, Src, Mask, VL);
13587 MVT InterimFVT = DstVT;
13588 if (SrcEltSize > (2 * DstEltSize)) {
13589 assert(SrcEltSize == (4 * DstEltSize) &&
"Unexpected types!");
13596 if (InterimFVT != DstVT) {
13598 Result = DAG.
getNode(RISCVISD::FP_ROUND_VL,
DL, DstVT, Src, Mask, VL);
13602 "Wrong input/output vector types");
13606 if (DstEltSize == 1) {
13609 assert(SrcEltSize >= 16 &&
"Unexpected FP type!");
13616 MVT XLenVT = Subtarget.getXLenVT();
13618 SplatZero = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, InterimIVT,
13619 DAG.
getUNDEF(InterimIVT), SplatZero, VL);
13629 while (InterimIVT != DstVT) {
13641 MVT VT =
Op.getSimpleValueType();
13650 MVT VT =
Op.getSimpleValueType();
13651 MVT XLenVT = Subtarget.getXLenVT();
13664 MVT ContainerVT = VT;
13684 TrueVal = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, PromotedVT, TrueVal, SplatOne,
13685 SplatZero, DAG.
getUNDEF(PromotedVT), VL);
13688 SplatOne, SplatZero, DAG.
getUNDEF(PromotedVT), VLMax);
13692 TrueVal, FalseVal, FalseVal, VL);
13697 RISCVISD::SETCC_VL,
DL, ContainerVT,
13707RISCVTargetLowering::lowerVPSpliceExperimental(
SDValue Op,
13709 using namespace SDPatternMatch;
13720 const MVT XLenVT = Subtarget.getXLenVT();
13721 MVT VT =
Op.getSimpleValueType();
13722 MVT ContainerVT = VT;
13732 if (IsMaskVector) {
13742 Op1 = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, ContainerVT, Op1, SplatOneOp1,
13743 SplatZeroOp1, DAG.
getUNDEF(ContainerVT), EVL1);
13751 Op2 = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, ContainerVT, Op2, SplatOneOp2,
13752 SplatZeroOp2, DAG.
getUNDEF(ContainerVT), EVL2);
13755 auto getVectorFirstEle = [](
SDValue Vec) {
13768 if (
auto FirstEle = getVectorFirstEle(
Op->getOperand(0))) {
13771 if ((EltVT == MVT::f16 && !Subtarget.hasVInstructionsF16()) ||
13772 EltVT == MVT::bf16) {
13780 : RISCVISD::VSLIDE1UP_VL,
13781 DL, ContainerVT, DAG.
getUNDEF(ContainerVT), Op2,
13782 FirstEle, Mask, EVL2);
13792 SDValue DownOffset, UpOffset;
13793 if (ImmValue >= 0) {
13807 DAG.
getUNDEF(ContainerVT), Op1, DownOffset, Mask,
13808 Subtarget.hasVLDependentLatency() ? UpOffset : EVL2);
13812 if (IsMaskVector) {
13816 {Result, DAG.getConstant(0, DL, ContainerVT),
13817 DAG.getCondCode(ISD::SETNE), DAG.getUNDEF(getMaskTypeFor(ContainerVT)),
13832 MVT VT =
Op.getSimpleValueType();
13834 MVT ContainerVT = VT;
13845 DAG.
getNode(
C->isZero() ? RISCVISD::VMCLR_VL : RISCVISD::VMSET_VL,
DL,
13868RISCVTargetLowering::lowerVPReverseExperimental(
SDValue Op,
13871 MVT VT =
Op.getSimpleValueType();
13872 MVT XLenVT = Subtarget.getXLenVT();
13878 MVT ContainerVT = VT;
13886 MVT GatherVT = ContainerVT;
13890 if (IsMaskVector) {
13900 Op1 = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, IndicesVT, Op1, SplatOne,
13901 SplatZero, DAG.
getUNDEF(IndicesVT), EVL);
13906 unsigned VectorBitsMax = Subtarget.getRealMaxVLen();
13907 unsigned MaxVLMAX =
13910 unsigned GatherOpc = RISCVISD::VRGATHER_VV_VL;
13916 if (MaxVLMAX > 256 && EltSize == 8) {
13944 DAG.
getUNDEF(GatherVT), Result, Diff, Mask, EVL);
13946 if (IsMaskVector) {
13949 DAG.
getNode(RISCVISD::SETCC_VL,
DL, ContainerVT,
13962 GatherOpc = RISCVISD::VRGATHEREI16_VV_VL;
13969 DAG.
getUNDEF(IndicesVT), VecLen, EVL);
13970 SDValue VRSUB = DAG.
getNode(RISCVISD::SUB_VL,
DL, IndicesVT, VecLenSplat, VID,
13971 DAG.
getUNDEF(IndicesVT), Mask, EVL);
13973 DAG.
getUNDEF(GatherVT), Mask, EVL);
13975 if (IsMaskVector) {
13978 RISCVISD::SETCC_VL,
DL, ContainerVT,
13990 MVT VT =
Op.getSimpleValueType();
13992 return lowerVPOp(
Op, DAG);
13999 MVT ContainerVT = VT;
14017 MVT XLenVT = Subtarget.getXLenVT();
14018 MVT VT =
Op.getSimpleValueType();
14019 MVT ContainerVT = VT;
14023 SDVTList VTs = DAG.
getVTList({ContainerVT, MVT::Other});
14031 : Intrinsic::riscv_vlse_mask,
14034 DAG.
getUNDEF(ContainerVT), VPNode->getBasePtr(),
14035 VPNode->getStride()};
14041 Ops.push_back(Mask);
14043 Ops.push_back(VPNode->getVectorLength());
14047 Ops.push_back(Policy);
14052 VPNode->getMemoryVT(), VPNode->getMemOperand());
14064 MVT XLenVT = Subtarget.getXLenVT();
14067 SDValue StoreVal = VPNode->getValue();
14069 MVT ContainerVT = VT;
14080 : Intrinsic::riscv_vsse_mask,
14083 VPNode->getBasePtr(), VPNode->getStride()};
14089 Ops.push_back(Mask);
14091 Ops.push_back(VPNode->getVectorLength());
14094 Ops, VPNode->getMemoryVT(),
14095 VPNode->getMemOperand());
14107 MVT VT =
Op.getSimpleValueType();
14110 EVT MemVT = MemSD->getMemoryVT();
14111 MachineMemOperand *MMO = MemSD->getMemOperand();
14112 SDValue Chain = MemSD->getChain();
14119 Index = VPGN->getIndex();
14120 Mask = VPGN->getMask();
14122 VL = VPGN->getVectorLength();
14128 Index = MGN->getIndex();
14129 Mask = MGN->getMask();
14130 PassThru = MGN->getPassThru();
14134 MVT IndexVT =
Index.getSimpleValueType();
14135 MVT XLenVT = Subtarget.getXLenVT();
14138 "Unexpected VTs!");
14139 assert(
BasePtr.getSimpleValueType() == XLenVT &&
"Unexpected pointer type");
14142 "Unexpected extending MGATHER/VP_GATHER");
14148 MVT ContainerVT = VT;
14172 IsUnmasked ? Intrinsic::riscv_vluxei : Intrinsic::riscv_vluxei_mask;
14177 Ops.push_back(PassThru);
14178 Ops.push_back(BasePtr);
14179 Ops.push_back(Index);
14181 Ops.push_back(Mask);
14186 SDVTList VTs = DAG.
getVTList({ContainerVT, MVT::Other});
14189 Chain =
Result.getValue(1);
14207 EVT MemVT = MemSD->getMemoryVT();
14208 MachineMemOperand *MMO = MemSD->getMemOperand();
14209 SDValue Chain = MemSD->getChain();
14212 [[maybe_unused]]
bool IsTruncatingStore =
false;
14216 Index = VPSN->getIndex();
14217 Mask = VPSN->getMask();
14218 Val = VPSN->getValue();
14219 VL = VPSN->getVectorLength();
14221 IsTruncatingStore =
false;
14225 Index = MSN->getIndex();
14226 Mask = MSN->getMask();
14227 Val = MSN->getValue();
14228 IsTruncatingStore = MSN->isTruncatingStore();
14232 MVT IndexVT =
Index.getSimpleValueType();
14233 MVT XLenVT = Subtarget.getXLenVT();
14236 "Unexpected VTs!");
14237 assert(
BasePtr.getSimpleValueType() == XLenVT &&
"Unexpected pointer type");
14240 assert(!IsTruncatingStore &&
"Unexpected truncating MSCATTER/VP_SCATTER");
14246 MVT ContainerVT = VT;
14270 IsUnmasked ? Intrinsic::riscv_vsoxei : Intrinsic::riscv_vsoxei_mask;
14272 Ops.push_back(Val);
14273 Ops.push_back(BasePtr);
14274 Ops.push_back(Index);
14276 Ops.push_back(Mask);
14285 const MVT XLenVT = Subtarget.getXLenVT();
14289 SDVTList VTs = DAG.
getVTList(XLenVT, MVT::Other);
14296 static const int Table =
14315 const MVT XLenVT = Subtarget.getXLenVT();
14325 static const unsigned Table =
14340 return DAG.
getNode(RISCVISD::WRITE_CSR,
DL, MVT::Other, Chain, SysRegNo,
14346 const MVT XLenVT = Subtarget.getXLenVT();
14350 SDVTList VTs = DAG.
getVTList(XLenVT, MVT::Other);
14351 return DAG.
getNode(RISCVISD::READ_CSR,
DL, VTs, Chain, SysRegNo);
14356 const MVT XLenVT = Subtarget.getXLenVT();
14363 return DAG.
getNode(RISCVISD::WRITE_CSR,
DL, MVT::Other, Chain, SysRegNo,
14369 const MVT XLenVT = Subtarget.getXLenVT();
14375 return DAG.
getNode(RISCVISD::WRITE_CSR,
DL, MVT::Other, Chain, SysRegNo,
14389 SDValue Result = DAG.
getNode(RISCVISD::READ_CSR,
DL, VTs, Chain, SysRegNo);
14390 Chain = Result.getValue(1);
14396 const MVT XLenVT = Subtarget.getXLenVT();
14406 Chain = DAG.
getNode(RISCVISD::CLEAR_CSR,
DL, MVT::Other, Chain, SysRegNo,
14408 return DAG.
getNode(RISCVISD::SET_CSR,
DL, MVT::Other, Chain, SysRegNo,
14414 const MVT XLenVT = Subtarget.getXLenVT();
14421 return DAG.
getNode(RISCVISD::CLEAR_CSR,
DL, MVT::Other, Chain, SysRegNo,
14429 bool isRISCV64 = Subtarget.is64Bit();
14443 return RISCVISD::SLLW;
14445 return RISCVISD::SRAW;
14447 return RISCVISD::SRLW;
14449 return RISCVISD::DIVW;
14451 return RISCVISD::DIVUW;
14453 return RISCVISD::REMUW;
14455 return RISCVISD::ROLW;
14457 return RISCVISD::RORW;
14493 switch (
N->getOpcode()) {
14495 llvm_unreachable(
"Don't know how to custom type legalize this operation!");
14500 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
14501 "Unexpected custom legalisation");
14502 bool IsStrict =
N->isStrictFPOpcode();
14505 SDValue Op0 = IsStrict ?
N->getOperand(1) :
N->getOperand(0);
14514 !Subtarget.hasStdExtZfhOrZhinx()) {
14519 unsigned Opc = IsSigned ? RISCVISD::STRICT_FCVT_W_RV64
14520 : RISCVISD::STRICT_FCVT_WU_RV64;
14523 Opc,
DL, VTs, Chain, Op0,
14532 !Subtarget.hasStdExtZfhOrZhinx()) ||
14534 Op0 = DAG.
getNode(ISD::FP_EXTEND,
DL, MVT::f32, Op0);
14536 unsigned Opc = IsSigned ? RISCVISD::FCVT_W_RV64 : RISCVISD::FCVT_WU_RV64;
14557 std::tie(Result, Chain) =
14558 makeLibCall(DAG, LC,
N->getValueType(0), Op0, CallOptions,
DL, Chain);
14564 case ISD::LROUND: {
14573 if (Op0.
getValueType() == MVT::f16 && !Subtarget.hasStdExtZfhOrZhinx())
14574 Op0 = DAG.
getNode(ISD::FP_EXTEND,
DL, MVT::f32, Op0);
14577 DAG.
getNode(RISCVISD::FCVT_W_RV64,
DL, MVT::i64, Op0,
14585 RTLIB::Libcall LC =
14586 Op0.
getValueType() == MVT::f64 ? RTLIB::LROUND_F64 : RTLIB::LROUND_F32;
14595 case ISD::READCYCLECOUNTER:
14596 case ISD::READSTEADYCOUNTER: {
14597 assert(!Subtarget.is64Bit() &&
"READCYCLECOUNTER/READSTEADYCOUNTER only "
14598 "has custom type legalization on riscv32");
14600 SDValue LoCounter, HiCounter;
14601 MVT XLenVT = Subtarget.getXLenVT();
14602 if (
N->getOpcode() == ISD::READCYCLECOUNTER) {
14611 N->getOperand(0), LoCounter, HiCounter);
14626 if (
N->getValueType(0) == MVT::i64) {
14627 assert(Subtarget.hasStdExtZilsd() && !Subtarget.is64Bit() &&
14628 "Unexpected custom legalisation");
14630 if (!Subtarget.enableUnalignedScalarMem() && Ld->
getAlign() < 8)
14635 RISCVISD::LD_RV32,
DL,
14636 DAG.
getVTList({MVT::i32, MVT::i32, MVT::Other}),
14637 {Ld->getChain(), Ld->getBasePtr()}, MVT::i64, Ld->
getMemOperand());
14641 Results.append({Pair, Result.getValue(2)});
14645 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
14646 "Unexpected custom legalisation");
14657 unsigned Size =
N->getSimpleValueType(0).getSizeInBits();
14658 unsigned XLen = Subtarget.getXLen();
14661 assert(
Size == (XLen * 2) &&
"Unexpected custom legalisation");
14669 if (LHSIsU == RHSIsU)
14673 MVT XLenVT = Subtarget.getXLenVT();
14686 if (RHSIsU && LHSIsS && !RHSIsS)
14687 Results.push_back(MakeMULPair(LHS, RHS));
14688 else if (LHSIsU && RHSIsS && !LHSIsS)
14689 Results.push_back(MakeMULPair(RHS, LHS));
14697 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
14698 "Unexpected custom legalisation");
14704 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
14705 "Unexpected custom legalisation");
14708 if (
N->getOpcode() ==
ISD::SHL && Subtarget.hasStdExtZbs() &&
14733 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
14734 "Unexpected custom legalisation");
14735 assert((Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb() ||
14736 Subtarget.hasVendorXTHeadBb()) &&
14737 "Unexpected custom legalization");
14739 !(Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()))
14747 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
14748 "Unexpected custom legalisation");
14756 if (IsCTZ && !Subtarget.hasStdExtZbb()) {
14757 assert(Subtarget.hasStdExtP());
14773 unsigned Opc = IsCTZ ? RISCVISD::CTZW : RISCVISD::CLZW;
14781 MVT VT =
N->getSimpleValueType(0);
14782 assert((VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) &&
14783 Subtarget.is64Bit() && Subtarget.hasStdExtM() &&
14784 "Unexpected custom legalisation");
14796 if (VT != MVT::i32)
14804 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
14805 "Unexpected custom legalisation");
14826 EVT OType =
N->getValueType(1);
14838 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
14839 "Unexpected custom legalisation");
14856 Overflow = DAG.
getSetCC(
DL,
N->getValueType(1), Res,
14860 Overflow = DAG.
getSetCC(
DL,
N->getValueType(1),
N->getOperand(0),
14867 Overflow = DAG.
getSetCC(
DL,
N->getValueType(1), Res, LHS,
14877 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
14878 !Subtarget.hasStdExtZbb() &&
"Unexpected custom legalisation");
14886 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
14887 "Unexpected custom legalisation");
14892 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
14893 "Unexpected custom legalisation");
14895 if (Subtarget.hasStdExtP()) {
14903 if (Subtarget.hasStdExtZbb()) {
14936 case ISD::BITCAST: {
14937 EVT VT =
N->getValueType(0);
14941 MVT XLenVT = Subtarget.getXLenVT();
14942 if (VT == MVT::i16 &&
14943 ((Op0VT == MVT::f16 && Subtarget.hasStdExtZfhminOrZhinxmin()) ||
14944 (Op0VT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()))) {
14947 }
else if (VT == MVT::i32 && Op0VT == MVT::f32 && Subtarget.is64Bit() &&
14948 Subtarget.hasStdExtFOrZfinx()) {
14950 DAG.
getNode(RISCVISD::FMV_X_ANYEXTW_RV64,
DL, MVT::i64, Op0);
14952 }
else if (VT == MVT::i64 && Op0VT == MVT::f64 && !Subtarget.is64Bit() &&
14953 Subtarget.hasStdExtDOrZdinx()) {
14955 DAG.
getVTList(MVT::i32, MVT::i32), Op0);
14974 assert(
N->getValueType(0) == MVT::i8 && Subtarget.hasStdExtZbkb() &&
14975 "Unexpected custom legalisation");
14976 MVT XLenVT = Subtarget.getXLenVT();
14984 case RISCVISD::BREV8:
14985 case RISCVISD::ORC_B: {
14986 MVT VT =
N->getSimpleValueType(0);
14987 MVT XLenVT = Subtarget.getXLenVT();
14988 assert((VT == MVT::i16 || (VT == MVT::i32 && Subtarget.is64Bit())) &&
14989 "Unexpected custom legalisation");
14990 assert(((
N->getOpcode() == RISCVISD::BREV8 && Subtarget.hasStdExtZbkb()) ||
14991 (
N->getOpcode() == RISCVISD::ORC_B && Subtarget.hasStdExtZbb())) &&
14992 "Unexpected extension");
15018 assert(!Subtarget.is64Bit() &&
N->getValueType(0) == MVT::i64 &&
15020 "Unexpected EXTRACT_VECTOR_ELT legalization");
15023 MVT ContainerVT = VecVT;
15029 MVT XLenVT = Subtarget.getXLenVT();
15038 DAG.
getUNDEF(ContainerVT), Vec, Idx, Mask, VL);
15050 DAG.
getNode(RISCVISD::SRL_VL,
DL, ContainerVT, Vec, ThirtyTwoV,
15051 DAG.
getUNDEF(ContainerVT), Mask, VL);
15059 unsigned IntNo =
N->getConstantOperandVal(0);
15063 "Don't know how to custom type legalize this intrinsic!");
15064 case Intrinsic::experimental_get_vector_length: {
15069 case Intrinsic::experimental_cttz_elts: {
15075 case Intrinsic::riscv_orc_b:
15076 case Intrinsic::riscv_brev8:
15077 case Intrinsic::riscv_sha256sig0:
15078 case Intrinsic::riscv_sha256sig1:
15079 case Intrinsic::riscv_sha256sum0:
15080 case Intrinsic::riscv_sha256sum1:
15081 case Intrinsic::riscv_sm3p0:
15082 case Intrinsic::riscv_sm3p1: {
15083 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
15087 case Intrinsic::riscv_orc_b:
Opc = RISCVISD::ORC_B;
break;
15088 case Intrinsic::riscv_brev8:
Opc = RISCVISD::BREV8;
break;
15089 case Intrinsic::riscv_sha256sig0:
Opc = RISCVISD::SHA256SIG0;
break;
15090 case Intrinsic::riscv_sha256sig1:
Opc = RISCVISD::SHA256SIG1;
break;
15091 case Intrinsic::riscv_sha256sum0:
Opc = RISCVISD::SHA256SUM0;
break;
15092 case Intrinsic::riscv_sha256sum1:
Opc = RISCVISD::SHA256SUM1;
break;
15093 case Intrinsic::riscv_sm3p0:
Opc = RISCVISD::SM3P0;
break;
15094 case Intrinsic::riscv_sm3p1:
Opc = RISCVISD::SM3P1;
break;
15103 case Intrinsic::riscv_sm4ks:
15104 case Intrinsic::riscv_sm4ed: {
15106 IntNo == Intrinsic::riscv_sm4ks ? RISCVISD::SM4KS : RISCVISD::SM4ED;
15112 DAG.
getNode(
Opc,
DL, MVT::i64, NewOp0, NewOp1,
N->getOperand(3));
15116 case Intrinsic::riscv_mopr: {
15117 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
15122 RISCVISD::MOP_R,
DL, MVT::i64, NewOp,
15127 case Intrinsic::riscv_moprr: {
15128 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
15135 RISCVISD::MOP_RR,
DL, MVT::i64, NewOp0, NewOp1,
15140 case Intrinsic::riscv_clmul: {
15141 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
15152 case Intrinsic::riscv_clmulh:
15153 case Intrinsic::riscv_clmulr: {
15154 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
15174 unsigned Opc = IntNo == Intrinsic::riscv_clmulh ? RISCVISD::CLMULH
15175 : RISCVISD::CLMULR;
15182 case Intrinsic::riscv_vmv_x_s: {
15183 EVT VT =
N->getValueType(0);
15184 MVT XLenVT = Subtarget.getXLenVT();
15185 if (VT.
bitsLT(XLenVT)) {
15188 Subtarget.getXLenVT(),
N->getOperand(1));
15193 assert(VT == MVT::i64 && !Subtarget.is64Bit() &&
15194 "Unexpected custom legalization");
15210 SDValue LShr32 = DAG.
getNode(RISCVISD::SRL_VL,
DL, VecVT, Vec, ThirtyTwoV,
15221 case ISD::VECREDUCE_ADD:
15222 case ISD::VECREDUCE_AND:
15223 case ISD::VECREDUCE_OR:
15224 case ISD::VECREDUCE_XOR:
15225 case ISD::VECREDUCE_SMAX:
15226 case ISD::VECREDUCE_UMAX:
15227 case ISD::VECREDUCE_SMIN:
15228 case ISD::VECREDUCE_UMIN:
15232 case ISD::VP_REDUCE_ADD:
15233 case ISD::VP_REDUCE_AND:
15234 case ISD::VP_REDUCE_OR:
15235 case ISD::VP_REDUCE_XOR:
15236 case ISD::VP_REDUCE_SMAX:
15237 case ISD::VP_REDUCE_UMAX:
15238 case ISD::VP_REDUCE_SMIN:
15239 case ISD::VP_REDUCE_UMIN:
15260 return ISD::VECREDUCE_ADD;
15262 return ISD::VECREDUCE_UMAX;
15264 return ISD::VECREDUCE_SMAX;
15266 return ISD::VECREDUCE_UMIN;
15268 return ISD::VECREDUCE_SMIN;
15270 return ISD::VECREDUCE_AND;
15272 return ISD::VECREDUCE_OR;
15274 return ISD::VECREDUCE_XOR;
15277 return ISD::VECREDUCE_FADD;
15279 return ISD::VECREDUCE_FMAX;
15281 return ISD::VECREDUCE_FMIN;
15307 const EVT VT =
N->getValueType(0);
15308 const unsigned Opc =
N->getOpcode();
15318 if (!
N->getFlags().hasAllowReassociation())
15329 "Inconsistent mappings");
15333 if (!
LHS.hasOneUse() || !
RHS.hasOneUse())
15361 if (0 == std::min(LHSIdx, RHSIdx) && 1 == std::max(LHSIdx, RHSIdx)) {
15364 return DAG.
getNode(ReduceOpc,
DL, VT, Vec,
N->getFlags());
15371 if (
LHS.getOpcode() != ReduceOpc)
15385 return DAG.
getNode(ReduceOpc,
DL, VT, Vec,
15386 ReduceVec->
getFlags() &
N->getFlags());
15396 auto BinOpToRVVReduce = [](
unsigned Opc) {
15401 return RISCVISD::VECREDUCE_ADD_VL;
15403 return RISCVISD::VECREDUCE_UMAX_VL;
15405 return RISCVISD::VECREDUCE_SMAX_VL;
15407 return RISCVISD::VECREDUCE_UMIN_VL;
15409 return RISCVISD::VECREDUCE_SMIN_VL;
15411 return RISCVISD::VECREDUCE_AND_VL;
15413 return RISCVISD::VECREDUCE_OR_VL;
15415 return RISCVISD::VECREDUCE_XOR_VL;
15417 return RISCVISD::VECREDUCE_FADD_VL;
15419 return RISCVISD::VECREDUCE_FMAX_VL;
15421 return RISCVISD::VECREDUCE_FMIN_VL;
15425 auto IsReduction = [&BinOpToRVVReduce](
SDValue V,
unsigned Opc) {
15428 V.getOperand(0).getOpcode() == BinOpToRVVReduce(
Opc);
15431 unsigned Opc =
N->getOpcode();
15432 unsigned ReduceIdx;
15433 if (IsReduction(
N->getOperand(0),
Opc))
15435 else if (IsReduction(
N->getOperand(1),
Opc))
15441 if (
Opc ==
ISD::FADD && !
N->getFlags().hasAllowReassociation())
15444 SDValue Extract =
N->getOperand(ReduceIdx);
15457 if (ScalarV.
getOpcode() != RISCVISD::VFMV_S_F_VL &&
15458 ScalarV.
getOpcode() != RISCVISD::VMV_S_X_VL &&
15459 ScalarV.
getOpcode() != RISCVISD::VMV_V_X_VL)
15476 SDValue NewStart =
N->getOperand(1 - ReduceIdx);
15509 EVT VT =
N->getValueType(0);
15525 int64_t C0 = N0C->getSExtValue();
15526 int64_t C1 = N1C->getSExtValue();
15527 if (C0 <= 0 || C1 <= 0)
15530 int64_t Diff = std::abs(C0 - C1);
15536 int64_t Bits = std::min(C0, C1);
15568 if (VShift.
slt(1) || VShift.
sgt(3))
15572 EVT VT =
N->getValueType(0);
15592 EVT VT =
N->getValueType(0);
15620 EVT VT =
N->getValueType(0);
15641 Slct.
getOpcode() != RISCVISD::SELECT_CC) ||
15649 bool SwapSelectOps;
15650 unsigned OpOffset = Slct.
getOpcode() == RISCVISD::SELECT_CC ? 2 : 0;
15655 SwapSelectOps =
false;
15656 NonConstantVal = FalseVal;
15658 SwapSelectOps =
true;
15659 NonConstantVal = TrueVal;
15665 FalseVal = DAG.
getNode(
N->getOpcode(),
SDLoc(
N), VT, OtherOp, NonConstantVal);
15670 if (Slct.
getOpcode() == RISCVISD::SELECT_CC)
15713 EVT VT =
N->getValueType(0);
15728 if (!N0C->hasOneUse())
15730 int64_t C0 = N0C->getSExtValue();
15731 int64_t C1 = N1C->getSExtValue();
15733 if (C0 == -1 || C0 == 0 || C0 == 1 ||
isInt<12>(C1))
15740 }
else if ((C1 / C0 + 1) != 0 &&
isInt<12>(C1 / C0 + 1) &&
15744 }
else if ((C1 / C0 - 1) != 0 &&
isInt<12>(C1 / C0 - 1) &&
15772 EVT VT =
N->getValueType(0);
15803 unsigned OuterExtend =
15807 OuterExtend,
SDLoc(
N), VT,
15815 EVT VT =
N->getValueType(0);
15865 EVT VT =
N->getValueType(0);
15875 APInt ImmValMinus1 = N0C->getAPIntValue() - 1;
15885 if (!isIntEqualitySetCC(CCVal) || !SetCCOpVT.
isInteger())
15908 if (!Subtarget.hasStdExtZbb())
15911 EVT VT =
N->getValueType(0);
15913 if (VT != Subtarget.
getXLenVT() && VT != MVT::i32 && VT != MVT::i16)
15925 unsigned ShiftedAmount = 8 - ShAmtCLeft->getZExtValue();
15927 if (ShiftedAmount >= 8)
15931 SDValue RightShiftOperand = N1;
15933 if (ShiftedAmount != 0) {
15937 if (!ShAmtCRight || ShAmtCRight->getZExtValue() != ShiftedAmount)
15946 if (LeftShiftOperand != RightShiftOperand)
15950 Mask <<= ShiftedAmount;
15956 return DAG.
getNode(RISCVISD::ORC_B,
SDLoc(
N), VT, LeftShiftOperand);
15964 EVT VT =
N->getValueType(0);
15996 bool IsAnd =
N->getOpcode() ==
ISD::AND;
16020 EVT VT =
N->getValueType(0);
16044 EVT VT =
N->getValueType(0);
16071 if (CondLHS != True)
16078 if (!CondRHSC || CondRHSC->
getAPIntValue() != (1ULL << ScalarBits))
16090 if (!FalseRHSC || !FalseRHSC->
isZero())
16110 EVT VT =
N->getValueType(0);
16117 if (Subtarget.
is64Bit() && Subtarget.hasStdExtZbs() && VT == MVT::i1 &&
16160 EVT VT =
N->getValueType(0);
16179 EVT WideVT =
X.getValueType();
16206 auto IsEqualCompZero = [](
SDValue &V) ->
bool {
16215 if (!IsEqualCompZero(N0) || !N0.
hasOneUse())
16217 if (!IsEqualCompZero(N0) || !N0.
hasOneUse())
16224 unsigned CzeroOpcode =
16226 ? RISCVISD::CZERO_EQZ
16227 : RISCVISD::CZERO_NEZ;
16229 EVT VT =
N->getValueType(0);
16241 if (N0.
getOpcode() != ISD::ATOMIC_LOAD)
16256 if (Mask != ExpectedMask)
16282 if (Subtarget.
is64Bit() && Subtarget.hasStdExtZbs() &&
16322 if (N0.
getOpcode() != RISCVISD::CZERO_EQZ ||
16323 N1.
getOpcode() != RISCVISD::CZERO_NEZ ||
16341 EVT VT =
N->getValueType(0);
16359 if (!Subtarget.hasVendorXqcibm())
16371 if (
N->getValueType(0) != MVT::i32)
16373 unsigned Width, ShAmt;
16390 return DAG.
getNode(RISCVISD::QC_INSB,
DL, MVT::i32,
Ops);
16395 if (!Subtarget.hasVendorXqcibm())
16405 unsigned ShAmt, Width;
16409 if (
N->getValueType(0) != MVT::i32)
16414 if (Width == 1 && Subtarget.hasStdExtZbs())
16426 return DAG.
getNode(RISCVISD::QC_INSB,
DL, MVT::i32,
Ops);
16434 if (!Subtarget.hasVendorXqcibm())
16440 APInt MaskImm, OrImm;
16459 unsigned ShAmt, Width;
16472 return DAG.
getNode(RISCVISD::QC_INSB,
DL, MVT::i32,
Ops);
16514 if (Subtarget.
is64Bit() && Subtarget.hasStdExtZbs() &&
16529 if (N0.
getOpcode() == RISCVISD::SLLW &&
16533 return DAG.
getNode(RISCVISD::ROLW,
DL, MVT::i64,
16544 const APInt &Imm = ConstN00->getAPIntValue();
16545 if ((Imm + 1).isSignedIntN(12))
16569 EVT VT =
N->getValueType(0);
16578 bool IsAdd = (
E & 3) == 1;
16579 E -= IsAdd ? 1 : -1;
16583 Result = DAG.
getNode(AddSubOp,
DL, VT, Result, ShiftVal);
16593 uint64_t MulAmtLowBit = MulAmt & (-MulAmt);
16598 ShiftAmt1 = MulAmt + MulAmtLowBit;
16601 ShiftAmt1 = MulAmt - MulAmtLowBit;
16605 EVT VT =
N->getValueType(0);
16615 unsigned ShY,
bool AddX,
unsigned Shift) {
16617 EVT VT =
N->getValueType(0);
16629 ShlAdd = DAG.
getNode(RISCVISD::SHL_ADD,
DL, VT, ShlAdd,
16639 uint64_t MulAmt,
unsigned Shift) {
16666 assert(ShX != 0 &&
"MulAmt=4,6,10 handled before");
16678 EVT VT =
N->getValueType(0);
16687 bool ShouldExpandMul =
16689 !Subtarget.hasStdExtZmmul();
16690 if (!ShouldExpandMul)
16720 if (Shift >= 1 && Shift <= 3 &&
isPowerOf2_64(MulAmt & (MulAmt - 1))) {
16725 return DAG.
getNode(RISCVISD::SHL_ADD,
DL, VT,
X,
16732 if (MulAmt > 2 &&
isPowerOf2_64((MulAmt - 1) & (MulAmt - 2))) {
16734 if (ScaleShift >= 1 && ScaleShift < 4) {
16766 if (!Subtarget.hasStdExtZmmul())
16776 EVT VT =
N->getValueType(0);
16783 if (
N->getOperand(0).getOpcode() !=
ISD::AND ||
16784 N->getOperand(0).getOperand(0).getOpcode() !=
ISD::SRL)
16797 if (!V1.
isMask(HalfSize) || V2 != (1ULL | 1ULL << HalfSize) ||
16798 V3 != (HalfSize - 1))
16808 return DAG.
getNode(ISD::BITCAST,
DL, VT, Sra);
16814 EVT VT =
N->getValueType(0);
16822 unsigned AddSubOpc;
16828 auto IsAddSubWith1 = [&](
SDValue V) ->
bool {
16829 AddSubOpc = V->getOpcode();
16841 if (IsAddSubWith1(N0)) {
16843 return DAG.
getNode(AddSubOpc,
DL, VT, N1, MulVal);
16846 if (IsAddSubWith1(N1)) {
16848 return DAG.
getNode(AddSubOpc,
DL, VT, N0, MulVal);
16863 if (isIndexTypeSigned(IndexType))
16866 if (!
N->hasOneUse())
16869 EVT VT =
N.getValueType();
16908 EVT SrcVT = Src.getValueType();
16912 NewElen = std::max(NewElen, 8U);
16939 EVT OpVT =
X.getValueType();
16947 if (OpSize <= Subtarget.
getXLen() ||
16953 auto IsVectorBitCastCheap = [](
SDValue X) {
16956 X.getOpcode() == ISD::LOAD;
16958 if (!IsVectorBitCastCheap(
X) || !IsVectorBitCastCheap(
Y))
16962 Attribute::NoImplicitFloat))
16969 unsigned VecSize = OpSize / 8;
16981 DAG.
getNode(ISD::VP_REDUCE_OR,
DL, XLenVT,
16994 EVT VT =
N->getValueType(0);
16999 if (!isIntEqualitySetCC(
Cond))
17024 if (OpVT == MVT::i64 &&
isUInt<32>(AndRHSInt) &&
17028 if (NewC >= -2048 && NewC <= 2048) {
17034 return DAG.
getSetCC(dl, VT, Shift,
17044 if (OpVT != MVT::i64 || !Subtarget.
is64Bit())
17064 const APInt &C1 = N1C->getAPIntValue();
17082 EVT VT =
N->getValueType(0);
17084 unsigned Opc = Src.getOpcode();
17089 if (
Opc == RISCVISD::FMV_X_ANYEXTH && SrcVT.
bitsGE(MVT::i16) &&
17090 Subtarget.hasStdExtZfhmin())
17091 return DAG.
getNode(RISCVISD::FMV_X_SIGNEXTH,
DL, VT, Src.getOperand(0));
17097 return DAG.
getNode(RISCVISD::SLLW,
DL, VT, Src.getOperand(0),
17098 Src.getOperand(1));
17117struct CombineResult;
17119enum ExtKind : uint8_t {
17151struct NodeExtensionHelper {
17160 bool SupportsFPExt;
17162 bool SupportsBF16Ext;
17165 bool EnforceOneUse;
17175 case RISCVISD::VSEXT_VL:
17176 case RISCVISD::VZEXT_VL:
17177 case RISCVISD::FP_EXTEND_VL:
17180 return OrigOperand;
17186 return OrigOperand.
getOpcode() == RISCVISD::VMV_V_X_VL ||
17191 unsigned getExtOpc(ExtKind SupportsExt)
const {
17192 switch (SupportsExt) {
17193 case ExtKind::SExt:
17194 return RISCVISD::VSEXT_VL;
17195 case ExtKind::ZExt:
17196 return RISCVISD::VZEXT_VL;
17197 case ExtKind::FPExt:
17198 case ExtKind::BF16Ext:
17199 return RISCVISD::FP_EXTEND_VL;
17207 SDValue getOrCreateExtendedOp(SDNode *Root, SelectionDAG &DAG,
17208 const RISCVSubtarget &Subtarget,
17209 std::optional<ExtKind> SupportsExt)
const {
17210 if (!SupportsExt.has_value())
17211 return OrigOperand;
17213 MVT NarrowVT = getNarrowType(Root, *SupportsExt);
17217 if (
Source.getValueType() == NarrowVT)
17220 unsigned ExtOpc = getExtOpc(*SupportsExt);
17223 SDLoc
DL(OrigOperand);
17224 auto [
Mask, VL] = getMaskAndVL(Root, DAG, Subtarget);
17228 case RISCVISD::VSEXT_VL:
17229 case RISCVISD::VZEXT_VL:
17230 case RISCVISD::FP_EXTEND_VL:
17231 return DAG.
getNode(ExtOpc,
DL, NarrowVT, Source, Mask, VL);
17234 case RISCVISD::VMV_V_X_VL:
17235 return DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, NarrowVT,
17237 case RISCVISD::VFMV_V_F_VL:
17239 assert(
Source.getOpcode() == ISD::FP_EXTEND &&
"Unexpected source");
17242 return DAG.
getNode(RISCVISD::VFMV_V_F_VL,
DL, NarrowVT,
17243 DAG.
getUNDEF(NarrowVT), Source, VL);
17256 static MVT getNarrowType(
const SDNode *Root, ExtKind SupportsExt) {
17262 MVT EltVT = SupportsExt == ExtKind::BF16Ext ? MVT::bf16
17263 : SupportsExt == ExtKind::FPExt
17265 : MVT::getIntegerVT(NarrowSize);
17267 assert((
int)NarrowSize >= (SupportsExt == ExtKind::FPExt ? 16 : 8) &&
17268 "Trying to extend something we can't represent");
17275 static unsigned getSExtOpcode(
unsigned Opcode) {
17278 case RISCVISD::ADD_VL:
17279 case RISCVISD::VWADD_W_VL:
17280 case RISCVISD::VWADDU_W_VL:
17282 case RISCVISD::OR_VL:
17283 return RISCVISD::VWADD_VL;
17285 case RISCVISD::SUB_VL:
17286 case RISCVISD::VWSUB_W_VL:
17287 case RISCVISD::VWSUBU_W_VL:
17288 return RISCVISD::VWSUB_VL;
17290 case RISCVISD::MUL_VL:
17291 return RISCVISD::VWMUL_VL;
17299 static unsigned getZExtOpcode(
unsigned Opcode) {
17302 case RISCVISD::ADD_VL:
17303 case RISCVISD::VWADD_W_VL:
17304 case RISCVISD::VWADDU_W_VL:
17306 case RISCVISD::OR_VL:
17307 return RISCVISD::VWADDU_VL;
17309 case RISCVISD::SUB_VL:
17310 case RISCVISD::VWSUB_W_VL:
17311 case RISCVISD::VWSUBU_W_VL:
17312 return RISCVISD::VWSUBU_VL;
17314 case RISCVISD::MUL_VL:
17315 return RISCVISD::VWMULU_VL;
17317 case RISCVISD::SHL_VL:
17318 return RISCVISD::VWSLL_VL;
17326 static unsigned getFPExtOpcode(
unsigned Opcode) {
17328 case RISCVISD::FADD_VL:
17329 case RISCVISD::VFWADD_W_VL:
17330 return RISCVISD::VFWADD_VL;
17331 case RISCVISD::FSUB_VL:
17332 case RISCVISD::VFWSUB_W_VL:
17333 return RISCVISD::VFWSUB_VL;
17334 case RISCVISD::FMUL_VL:
17335 return RISCVISD::VFWMUL_VL;
17336 case RISCVISD::VFMADD_VL:
17337 return RISCVISD::VFWMADD_VL;
17338 case RISCVISD::VFMSUB_VL:
17339 return RISCVISD::VFWMSUB_VL;
17340 case RISCVISD::VFNMADD_VL:
17341 return RISCVISD::VFWNMADD_VL;
17342 case RISCVISD::VFNMSUB_VL:
17343 return RISCVISD::VFWNMSUB_VL;
17351 static unsigned getSUOpcode(
unsigned Opcode) {
17353 "SU is only supported for MUL");
17354 return RISCVISD::VWMULSU_VL;
17359 static unsigned getWOpcode(
unsigned Opcode, ExtKind SupportsExt) {
17362 case RISCVISD::ADD_VL:
17364 case RISCVISD::OR_VL:
17365 return SupportsExt == ExtKind::SExt ? RISCVISD::VWADD_W_VL
17366 : RISCVISD::VWADDU_W_VL;
17368 case RISCVISD::SUB_VL:
17369 return SupportsExt == ExtKind::SExt ? RISCVISD::VWSUB_W_VL
17370 : RISCVISD::VWSUBU_W_VL;
17371 case RISCVISD::FADD_VL:
17372 return RISCVISD::VFWADD_W_VL;
17373 case RISCVISD::FSUB_VL:
17374 return RISCVISD::VFWSUB_W_VL;
17380 using CombineToTry = std::function<std::optional<CombineResult>(
17381 SDNode * ,
const NodeExtensionHelper & ,
17382 const NodeExtensionHelper & , SelectionDAG &,
17383 const RISCVSubtarget &)>;
17386 bool needToPromoteOtherUsers()
const {
return EnforceOneUse; }
17388 void fillUpExtensionSupportForSplat(SDNode *Root, SelectionDAG &DAG,
17389 const RISCVSubtarget &Subtarget) {
17394 "Unexpected Opcode");
17407 unsigned ScalarBits =
Op.getValueSizeInBits();
17409 if (ScalarBits < EltBits) {
17411 assert(
Opc == RISCVISD::VMV_V_X_VL && EltBits == 64 && ScalarBits == 32 &&
17412 !Subtarget.
is64Bit() &&
"Unexpected splat");
17414 SupportsSExt =
true;
17418 SupportsZExt =
true;
17420 EnforceOneUse =
false;
17424 unsigned NarrowSize = EltBits / 2;
17427 if (NarrowSize < 8)
17431 SupportsSExt =
true;
17435 SupportsZExt =
true;
17437 EnforceOneUse =
false;
17440 bool isSupportedFPExtend(MVT NarrowEltVT,
const RISCVSubtarget &Subtarget) {
17441 return (NarrowEltVT == MVT::f32 ||
17445 bool isSupportedBF16Extend(MVT NarrowEltVT,
const RISCVSubtarget &Subtarget) {
17446 return NarrowEltVT == MVT::bf16 && Subtarget.hasStdExtZvfbfwma();
17451 void fillUpExtensionSupport(SDNode *Root, SelectionDAG &DAG,
17452 const RISCVSubtarget &Subtarget) {
17453 SupportsZExt =
false;
17454 SupportsSExt =
false;
17455 SupportsFPExt =
false;
17456 SupportsBF16Ext =
false;
17457 EnforceOneUse =
true;
17479 case RISCVISD::VZEXT_VL:
17480 SupportsZExt =
true;
17482 case RISCVISD::VSEXT_VL:
17483 SupportsSExt =
true;
17485 case RISCVISD::FP_EXTEND_VL: {
17488 if (isSupportedFPExtend(NarrowEltVT, Subtarget))
17489 SupportsFPExt =
true;
17490 if (isSupportedBF16Extend(NarrowEltVT, Subtarget))
17491 SupportsBF16Ext =
true;
17496 case RISCVISD::VMV_V_X_VL:
17497 fillUpExtensionSupportForSplat(Root, DAG, Subtarget);
17499 case RISCVISD::VFMV_V_F_VL: {
17506 if (
Op.getOpcode() != ISD::FP_EXTEND)
17510 unsigned ScalarBits =
Op.getOperand(0).getValueSizeInBits();
17511 if (NarrowSize != ScalarBits)
17514 if (isSupportedFPExtend(
Op.getOperand(0).getSimpleValueType(), Subtarget))
17515 SupportsFPExt =
true;
17516 if (isSupportedBF16Extend(
Op.getOperand(0).getSimpleValueType(),
17518 SupportsBF16Ext =
true;
17527 static bool isSupportedRoot(
const SDNode *Root,
17528 const RISCVSubtarget &Subtarget) {
17540 case RISCVISD::ADD_VL:
17541 case RISCVISD::MUL_VL:
17542 case RISCVISD::VWADD_W_VL:
17543 case RISCVISD::VWADDU_W_VL:
17544 case RISCVISD::SUB_VL:
17545 case RISCVISD::VWSUB_W_VL:
17546 case RISCVISD::VWSUBU_W_VL:
17548 case RISCVISD::FADD_VL:
17549 case RISCVISD::FSUB_VL:
17550 case RISCVISD::FMUL_VL:
17551 case RISCVISD::VFWADD_W_VL:
17552 case RISCVISD::VFWSUB_W_VL:
17554 case RISCVISD::OR_VL:
17558 Subtarget.hasStdExtZvbb();
17559 case RISCVISD::SHL_VL:
17560 return Subtarget.hasStdExtZvbb();
17561 case RISCVISD::VFMADD_VL:
17562 case RISCVISD::VFNMSUB_VL:
17563 case RISCVISD::VFNMADD_VL:
17564 case RISCVISD::VFMSUB_VL:
17572 NodeExtensionHelper(SDNode *Root,
unsigned OperandIdx, SelectionDAG &DAG,
17573 const RISCVSubtarget &Subtarget) {
17574 assert(isSupportedRoot(Root, Subtarget) &&
17575 "Trying to build an helper with an "
17576 "unsupported root");
17577 assert(OperandIdx < 2 &&
"Requesting something else than LHS or RHS");
17587 case RISCVISD::VWADD_W_VL:
17588 case RISCVISD::VWADDU_W_VL:
17589 case RISCVISD::VWSUB_W_VL:
17590 case RISCVISD::VWSUBU_W_VL:
17591 case RISCVISD::VFWADD_W_VL:
17592 case RISCVISD::VFWSUB_W_VL:
17594 if (OperandIdx == 1)
17598 fillUpExtensionSupport(Root, DAG, Subtarget);
17604 static std::pair<SDValue, SDValue>
17605 getMaskAndVL(
const SDNode *Root, SelectionDAG &DAG,
17606 const RISCVSubtarget &Subtarget) {
17607 assert(isSupportedRoot(Root, Subtarget) &&
"Unexpected root");
17626 switch (
N->getOpcode()) {
17630 case RISCVISD::ADD_VL:
17631 case RISCVISD::MUL_VL:
17632 case RISCVISD::OR_VL:
17633 case RISCVISD::FADD_VL:
17634 case RISCVISD::FMUL_VL:
17635 case RISCVISD::VFMADD_VL:
17636 case RISCVISD::VFNMSUB_VL:
17637 case RISCVISD::VFNMADD_VL:
17638 case RISCVISD::VFMSUB_VL:
17640 case RISCVISD::VWADD_W_VL:
17641 case RISCVISD::VWADDU_W_VL:
17643 case RISCVISD::SUB_VL:
17644 case RISCVISD::VWSUB_W_VL:
17645 case RISCVISD::VWSUBU_W_VL:
17646 case RISCVISD::VFWADD_W_VL:
17647 case RISCVISD::FSUB_VL:
17648 case RISCVISD::VFWSUB_W_VL:
17650 case RISCVISD::SHL_VL:
17669struct CombineResult {
17671 unsigned TargetOpcode;
17673 std::optional<ExtKind> LHSExt;
17674 std::optional<ExtKind> RHSExt;
17678 NodeExtensionHelper
LHS;
17680 NodeExtensionHelper
RHS;
17682 CombineResult(
unsigned TargetOpcode, SDNode *Root,
17683 const NodeExtensionHelper &
LHS, std::optional<ExtKind> LHSExt,
17684 const NodeExtensionHelper &
RHS, std::optional<ExtKind> RHSExt)
17685 : TargetOpcode(TargetOpcode), LHSExt(LHSExt), RHSExt(RHSExt), Root(Root),
17691 SDValue materialize(SelectionDAG &DAG,
17692 const RISCVSubtarget &Subtarget)
const {
17694 std::tie(Mask, VL) =
17695 NodeExtensionHelper::getMaskAndVL(Root, DAG, Subtarget);
17709 LHS.getOrCreateExtendedOp(Root, DAG, Subtarget, LHSExt),
17710 RHS.getOrCreateExtendedOp(Root, DAG, Subtarget, RHSExt),
17711 Passthru, Mask, VL);
17725static std::optional<CombineResult>
17726canFoldToVWWithSameExtensionImpl(
SDNode *Root,
const NodeExtensionHelper &
LHS,
17727 const NodeExtensionHelper &
RHS,
17730 if ((AllowExtMask & ExtKind::ZExt) &&
LHS.SupportsZExt &&
RHS.SupportsZExt)
17731 return CombineResult(NodeExtensionHelper::getZExtOpcode(Root->
getOpcode()),
17732 Root,
LHS, {ExtKind::ZExt},
RHS,
17734 if ((AllowExtMask & ExtKind::SExt) &&
LHS.SupportsSExt &&
RHS.SupportsSExt)
17735 return CombineResult(NodeExtensionHelper::getSExtOpcode(Root->
getOpcode()),
17736 Root,
LHS, {ExtKind::SExt},
RHS,
17738 if ((AllowExtMask & ExtKind::FPExt) &&
LHS.SupportsFPExt &&
RHS.SupportsFPExt)
17739 return CombineResult(NodeExtensionHelper::getFPExtOpcode(Root->
getOpcode()),
17740 Root,
LHS, {ExtKind::FPExt},
RHS,
17742 if ((AllowExtMask & ExtKind::BF16Ext) &&
LHS.SupportsBF16Ext &&
17743 RHS.SupportsBF16Ext)
17744 return CombineResult(NodeExtensionHelper::getFPExtOpcode(Root->
getOpcode()),
17745 Root,
LHS, {ExtKind::BF16Ext},
RHS,
17746 {ExtKind::BF16Ext});
17747 return std::nullopt;
17756static std::optional<CombineResult>
17757canFoldToVWWithSameExtension(
SDNode *Root,
const NodeExtensionHelper &
LHS,
17760 return canFoldToVWWithSameExtensionImpl(
17761 Root,
LHS,
RHS, ExtKind::ZExt | ExtKind::SExt | ExtKind::FPExt, DAG,
17769static std::optional<CombineResult>
17770canFoldToVWWithSameExtZEXT(
SDNode *Root,
const NodeExtensionHelper &
LHS,
17773 return canFoldToVWWithSameExtensionImpl(Root,
LHS,
RHS, ExtKind::ZExt, DAG,
17781static std::optional<CombineResult>
17782canFoldToVWWithSameExtBF16(
SDNode *Root,
const NodeExtensionHelper &
LHS,
17785 return canFoldToVWWithSameExtensionImpl(Root,
LHS,
RHS, ExtKind::BF16Ext, DAG,
17793static std::optional<CombineResult>
17794canFoldToVW_W(
SDNode *Root,
const NodeExtensionHelper &
LHS,
17797 if (
RHS.SupportsFPExt)
17798 return CombineResult(
17799 NodeExtensionHelper::getWOpcode(Root->
getOpcode(), ExtKind::FPExt),
17800 Root,
LHS, std::nullopt,
RHS, {ExtKind::FPExt});
17807 return CombineResult(
17808 NodeExtensionHelper::getWOpcode(Root->
getOpcode(), ExtKind::ZExt), Root,
17809 LHS, std::nullopt,
RHS, {ExtKind::ZExt});
17811 return CombineResult(
17812 NodeExtensionHelper::getWOpcode(Root->
getOpcode(), ExtKind::SExt), Root,
17813 LHS, std::nullopt,
RHS, {ExtKind::SExt});
17814 return std::nullopt;
17821static std::optional<CombineResult>
17822canFoldToVWWithSEXT(
SDNode *Root,
const NodeExtensionHelper &
LHS,
17825 if (
LHS.SupportsSExt)
17826 return CombineResult(NodeExtensionHelper::getSExtOpcode(Root->
getOpcode()),
17827 Root,
LHS, {ExtKind::SExt},
RHS,
17829 return std::nullopt;
17836static std::optional<CombineResult>
17837canFoldToVWWithZEXT(
SDNode *Root,
const NodeExtensionHelper &
LHS,
17840 if (
LHS.SupportsZExt)
17841 return CombineResult(NodeExtensionHelper::getZExtOpcode(Root->
getOpcode()),
17842 Root,
LHS, {ExtKind::ZExt},
RHS,
17844 return std::nullopt;
17851static std::optional<CombineResult>
17852canFoldToVWWithFPEXT(
SDNode *Root,
const NodeExtensionHelper &
LHS,
17855 if (
LHS.SupportsFPExt)
17856 return CombineResult(NodeExtensionHelper::getFPExtOpcode(Root->
getOpcode()),
17857 Root,
LHS, {ExtKind::FPExt},
RHS,
17859 return std::nullopt;
17866static std::optional<CombineResult>
17867canFoldToVW_SU(
SDNode *Root,
const NodeExtensionHelper &
LHS,
17871 if (!
LHS.SupportsSExt || !
RHS.SupportsZExt)
17872 return std::nullopt;
17873 return CombineResult(NodeExtensionHelper::getSUOpcode(Root->
getOpcode()),
17874 Root,
LHS, {ExtKind::SExt},
RHS,
17879NodeExtensionHelper::getSupportedFoldings(
const SDNode *Root) {
17885 case RISCVISD::ADD_VL:
17886 case RISCVISD::SUB_VL:
17887 case RISCVISD::OR_VL:
17888 case RISCVISD::FADD_VL:
17889 case RISCVISD::FSUB_VL:
17891 Strategies.
push_back(canFoldToVWWithSameExtension);
17895 case RISCVISD::FMUL_VL:
17896 case RISCVISD::VFMADD_VL:
17897 case RISCVISD::VFMSUB_VL:
17898 case RISCVISD::VFNMADD_VL:
17899 case RISCVISD::VFNMSUB_VL:
17900 Strategies.
push_back(canFoldToVWWithSameExtension);
17901 if (Root->
getOpcode() == RISCVISD::VFMADD_VL)
17902 Strategies.
push_back(canFoldToVWWithSameExtBF16);
17905 case RISCVISD::MUL_VL:
17907 Strategies.
push_back(canFoldToVWWithSameExtension);
17912 case RISCVISD::SHL_VL:
17914 Strategies.
push_back(canFoldToVWWithSameExtZEXT);
17916 case RISCVISD::VWADD_W_VL:
17917 case RISCVISD::VWSUB_W_VL:
17919 Strategies.
push_back(canFoldToVWWithSEXT);
17921 case RISCVISD::VWADDU_W_VL:
17922 case RISCVISD::VWSUBU_W_VL:
17924 Strategies.
push_back(canFoldToVWWithZEXT);
17926 case RISCVISD::VFWADD_W_VL:
17927 case RISCVISD::VFWSUB_W_VL:
17929 Strategies.
push_back(canFoldToVWWithFPEXT);
17940 assert(
N->getOpcode() == RISCVISD::ADD_VL);
17943 SDValue Passthru =
N->getOperand(2);
17977 if (!NodeExtensionHelper::isSupportedRoot(
N, Subtarget))
17984 Inserted.insert(
N);
17987 while (!Worklist.
empty()) {
17990 NodeExtensionHelper
LHS(Root, 0, DAG, Subtarget);
17991 NodeExtensionHelper
RHS(Root, 1, DAG, Subtarget);
17992 auto AppendUsersIfNeeded =
17993 [&Worklist, &Subtarget, &Inserted,
17994 &ExtensionsToRemove](
const NodeExtensionHelper &
Op) {
17995 if (
Op.needToPromoteOtherUsers()) {
17997 ExtensionsToRemove.
insert(
Op.OrigOperand.getNode());
18000 if (!NodeExtensionHelper::isSupportedRoot(TheUser, Subtarget))
18005 if (Inserted.insert(TheUser).second)
18018 NodeExtensionHelper::getSupportedFoldings(Root);
18020 assert(!FoldingStrategies.
empty() &&
"Nothing to be folded");
18021 bool Matched =
false;
18022 for (
int Attempt = 0;
18023 (Attempt != 1 + NodeExtensionHelper::isCommutative(Root)) && !Matched;
18026 for (NodeExtensionHelper::CombineToTry FoldingStrategy :
18027 FoldingStrategies) {
18028 std::optional<CombineResult> Res =
18029 FoldingStrategy(Root,
LHS,
RHS, DAG, Subtarget);
18033 if (!Res->LHSExt.has_value() &&
18034 ExtensionsToRemove.
contains(
LHS.OrigOperand.getNode()))
18036 if (!Res->RHSExt.has_value() &&
18037 ExtensionsToRemove.
contains(
RHS.OrigOperand.getNode()))
18045 if (Res->LHSExt.has_value())
18046 if (!AppendUsersIfNeeded(
LHS))
18048 if (Res->RHSExt.has_value())
18049 if (!AppendUsersIfNeeded(
RHS))
18061 SDValue InputRootReplacement;
18068 for (CombineResult Res : CombinesToApply) {
18069 SDValue NewValue = Res.materialize(DAG, Subtarget);
18070 if (!InputRootReplacement) {
18072 "First element is expected to be the current node");
18073 InputRootReplacement = NewValue;
18078 for (std::pair<SDValue, SDValue> OldNewValues : ValuesToReplace) {
18082 return InputRootReplacement;
18089 unsigned Opc =
N->getOpcode();
18090 assert(
Opc == RISCVISD::VWADD_W_VL ||
Opc == RISCVISD::VWADDU_W_VL ||
18091 Opc == RISCVISD::VWSUB_W_VL ||
Opc == RISCVISD::VWSUBU_W_VL);
18094 SDValue MergeOp =
N->getOperand(1);
18095 unsigned MergeOpc = MergeOp.
getOpcode();
18097 if (MergeOpc != RISCVISD::VMERGE_VL && MergeOpc !=
ISD::VSELECT)
18106 SDValue Passthru =
N->getOperand(2);
18112 if (Mask.getOpcode() != RISCVISD::VMSET_VL)
18120 Z = Z.getOperand(1);
18126 {Y, X, Y, MergeOp->getOperand(0), N->getOperand(4)},
18133 [[maybe_unused]]
unsigned Opc =
N->getOpcode();
18134 assert(
Opc == RISCVISD::VWADD_W_VL ||
Opc == RISCVISD::VWADDU_W_VL ||
18135 Opc == RISCVISD::VWSUB_W_VL ||
Opc == RISCVISD::VWSUBU_W_VL);
18162 EVT NewMemVT = (MemVT == MVT::i32) ? MVT::i64 : MVT::i128;
18167 if (LSNode1->
getOpcode() == ISD::LOAD) {
18170 if (MemVT == MVT::i32)
18171 Opcode = (Ext ==
ISD::ZEXTLOAD) ? RISCVISD::TH_LWUD : RISCVISD::TH_LWD;
18173 Opcode = RISCVISD::TH_LDD;
18176 Opcode,
SDLoc(LSNode1), DAG.
getVTList({XLenVT, XLenVT, MVT::Other}),
18177 {LSNode1->getChain(), BasePtr,
18178 DAG.getConstant(Imm, SDLoc(LSNode1), XLenVT)},
18189 unsigned Opcode = (MemVT == MVT::i32) ? RISCVISD::TH_SWD : RISCVISD::TH_SDD;
18193 {LSNode1->getChain(), LSNode1->getOperand(1), LSNode2->getOperand(1),
18194 BasePtr, DAG.getConstant(Imm, SDLoc(LSNode1), XLenVT)},
18211 if (!Subtarget.hasVendorXTHeadMemPair())
18216 unsigned OpNum = LSNode1->
getOpcode() == ISD::LOAD ? 1 : 2;
18223 auto ExtractBaseAndOffset = [](
SDValue Ptr) -> std::pair<SDValue, uint64_t> {
18226 return {
Ptr->getOperand(0), C1->getZExtValue()};
18230 auto [Base1, Offset1] = ExtractBaseAndOffset(LSNode1->
getOperand(OpNum));
18251 auto [Base2, Offset2] = ExtractBaseAndOffset(LSNode2->
getOperand(OpNum));
18254 if (Base1 != Base2)
18258 bool Valid =
false;
18259 if (MemVT == MVT::i32) {
18263 }
else if (MemVT == MVT::i64) {
18299 if (Src->isStrictFPOpcode())
18307 if (Src.getValueType() == MVT::f16 && !Subtarget.hasStdExtZfh())
18317 EVT VT =
N->getValueType(0);
18320 MVT SrcVT = Src.getSimpleValueType();
18321 MVT SrcContainerVT = SrcVT;
18349 IsSigned ? RISCVISD::VFCVT_RTZ_X_F_VL : RISCVISD::VFCVT_RTZ_XU_F_VL;
18350 FpToInt = DAG.
getNode(
Opc,
DL, ContainerVT, XVal, Mask, VL);
18353 IsSigned ? RISCVISD::VFCVT_RM_X_F_VL : RISCVISD::VFCVT_RM_XU_F_VL;
18354 FpToInt = DAG.
getNode(
Opc,
DL, ContainerVT, XVal, Mask,
18367 if (VT != MVT::i32 && VT != XLenVT)
18372 Opc = IsSigned ? RISCVISD::FCVT_X : RISCVISD::FCVT_XU;
18374 Opc = IsSigned ? RISCVISD::FCVT_W_RV64 : RISCVISD::FCVT_WU_RV64;
18397 EVT DstVT =
N->getValueType(0);
18398 if (DstVT != XLenVT)
18404 if (Src->isStrictFPOpcode())
18412 if (Src.getValueType() == MVT::f16 && !Subtarget.hasStdExtZfh())
18424 if (SatVT == DstVT)
18425 Opc = IsSigned ? RISCVISD::FCVT_X : RISCVISD::FCVT_XU;
18426 else if (DstVT == MVT::i64 && SatVT == MVT::i32)
18427 Opc = IsSigned ? RISCVISD::FCVT_W_RV64 : RISCVISD::FCVT_WU_RV64;
18432 Src = Src.getOperand(0);
18440 if (
Opc == RISCVISD::FCVT_WU_RV64)
18453 assert(Subtarget.hasStdExtZbkb() &&
"Unexpected extension");
18459 EVT VT =
N->getValueType(0);
18465 return DAG.
getNode(RISCVISD::BREV8,
DL, VT, Src.getOperand(0));
18478 EVT LoadVT = VPLoad->getValueType(0);
18482 N->getOperand(2) != VPLoad->getVectorLength() ||
18483 !
N->getOperand(0).hasOneUse())
18490 SDValue LoadMask = VPLoad->getMask();
18495 if (LoadMask.
getOpcode() != ISD::EXPERIMENTAL_VP_REVERSE ||
18497 LoadMask.
getOperand(2) != VPLoad->getVectorLength())
18505 SDValue NumElem = VPLoad->getVectorLength();
18506 uint64_t ElemWidthByte = VPLoad->getValueType(0).getScalarSizeInBits() / 8;
18518 PtrInfo, VPLoad->getMemOperand()->getFlags(),
18522 LoadVT,
DL, VPLoad->getChain(),
Base, Stride, LoadMask,
18523 VPLoad->getVectorLength(), MMO, VPLoad->isExpandingLoad());
18537 if (VPStore->getValue().getOpcode() != ISD::EXPERIMENTAL_VP_REVERSE)
18540 SDValue VPReverse = VPStore->getValue();
18546 VPStore->getVectorLength() != VPReverse.
getOperand(2) ||
18550 SDValue StoreMask = VPStore->getMask();
18555 if (StoreMask.
getOpcode() != ISD::EXPERIMENTAL_VP_REVERSE ||
18557 StoreMask.
getOperand(2) != VPStore->getVectorLength())
18565 SDValue NumElem = VPStore->getVectorLength();
18579 PtrInfo, VPStore->getMemOperand()->getFlags(),
18584 VPStore->getOffset(), Stride, StoreMask, VPStore->getVectorLength(),
18585 VPStore->getMemoryVT(), MMO, VPStore->getAddressingMode(),
18586 VPStore->isTruncatingStore(), VPStore->isCompressingStore());
18598 EVT VT =
N->getValueType(0);
18610 if (In.getOpcode() != ISD::VP_SRL || In.getOperand(2) != Mask ||
18611 In.getOperand(3) != VL)
18620 if (
LHS.getOpcode() != ISD::VP_ADD ||
LHS.getOperand(2) != Mask ||
18621 LHS.getOperand(3) != VL)
18628 if (V.getOpcode() != ISD::VP_ADD || V.getOperand(2) != Mask ||
18629 V.getOperand(3) != VL)
18632 Operands[0] =
Other;
18641 if (!FindAdd(LHS0, LHS1) && !FindAdd(LHS1, LHS0))
18648 if (
I == std::end(Operands))
18655 if (
Op.getOpcode() != ISD::VP_ZERO_EXTEND ||
Op.getOperand(1) != Mask ||
18656 Op.getOperand(2) != VL)
18666 Operands[0].getOperand(0), Mask, VL);
18668 Operands[1].getOperand(0), Mask, VL);
18672 return DAG.
getNode(RISCVISD::AVGCEILU_VL,
DL, VT,
18673 {NewOp0, NewOp1, DAG.
getUNDEF(VT), Mask, VL});
18685 case RISCVISD::VFMADD_VL: Opcode = RISCVISD::VFNMSUB_VL;
break;
18686 case RISCVISD::VFNMSUB_VL: Opcode = RISCVISD::VFMADD_VL;
break;
18687 case RISCVISD::VFNMADD_VL: Opcode = RISCVISD::VFMSUB_VL;
break;
18688 case RISCVISD::VFMSUB_VL: Opcode = RISCVISD::VFNMADD_VL;
break;
18689 case RISCVISD::STRICT_VFMADD_VL: Opcode = RISCVISD::STRICT_VFNMSUB_VL;
break;
18690 case RISCVISD::STRICT_VFNMSUB_VL: Opcode = RISCVISD::STRICT_VFMADD_VL;
break;
18691 case RISCVISD::STRICT_VFNMADD_VL: Opcode = RISCVISD::STRICT_VFMSUB_VL;
break;
18692 case RISCVISD::STRICT_VFMSUB_VL: Opcode = RISCVISD::STRICT_VFNMADD_VL;
break;
18702 case RISCVISD::VFMADD_VL: Opcode = RISCVISD::VFMSUB_VL;
break;
18703 case RISCVISD::VFMSUB_VL: Opcode = RISCVISD::VFMADD_VL;
break;
18704 case RISCVISD::VFNMADD_VL: Opcode = RISCVISD::VFNMSUB_VL;
break;
18705 case RISCVISD::VFNMSUB_VL: Opcode = RISCVISD::VFNMADD_VL;
break;
18706 case RISCVISD::STRICT_VFMADD_VL: Opcode = RISCVISD::STRICT_VFMSUB_VL;
break;
18707 case RISCVISD::STRICT_VFMSUB_VL: Opcode = RISCVISD::STRICT_VFMADD_VL;
break;
18708 case RISCVISD::STRICT_VFNMADD_VL: Opcode = RISCVISD::STRICT_VFNMSUB_VL;
break;
18709 case RISCVISD::STRICT_VFNMSUB_VL: Opcode = RISCVISD::STRICT_VFNMADD_VL;
break;
18722 unsigned Offset = IsStrict ? 1 : 0;
18729 auto invertIfNegative = [&Mask, &VL](
SDValue &V) {
18730 if (V.getOpcode() == RISCVISD::FNEG_VL && V.getOperand(1) == Mask &&
18731 V.getOperand(2) == VL) {
18733 V = V.getOperand(0);
18740 bool NegA = invertIfNegative(
A);
18741 bool NegB = invertIfNegative(
B);
18742 bool NegC = invertIfNegative(
C);
18745 if (!NegA && !NegB && !NegC)
18751 {N->getOperand(0), A, B, C, Mask, VL});
18775 EVT VT =
N->getValueType(0);
18782 uint64_t ShAmt =
N->getConstantOperandVal(1);
18795 if (LShAmt < ExtSize) {
18808 if (ShAmt > 32 || VT != MVT::i64)
18838 U->getConstantOperandVal(1) > 32)
18893 if (!
Cond.hasOneUse())
18912 EVT VT =
Cond.getValueType();
18957 LHS =
LHS.getOperand(0);
18967 LHS.getOperand(0).getValueType() == Subtarget.
getXLenVT()) {
18975 RHS =
LHS.getOperand(1);
18976 LHS =
LHS.getOperand(0);
18985 auto isXorImmediate = [](
const SDValue &
Op) ->
bool {
18987 return isInt<12>(XorCnst->getSExtValue());
18991 auto singleBitOp = [&DAG](
const SDValue &VarOp,
18992 const SDValue &ConstOp) ->
bool {
18995 return (XorCnst->getSExtValue() == 1) &&
19000 auto onlyUsedBySelectOrBR = [](
const SDValue &
Op) ->
bool {
19001 for (
const SDNode *UserNode :
Op->users()) {
19002 const unsigned Opcode = UserNode->getOpcode();
19003 if (Opcode != RISCVISD::SELECT_CC && Opcode != RISCVISD::BR_CC)
19008 auto isFoldableXorEq = [isXorImmediate, singleBitOp, onlyUsedBySelectOrBR](
19011 (!isXorImmediate(
LHS.getOperand(1)) ||
19012 singleBitOp(
LHS.getOperand(0),
LHS.getOperand(1)) ||
19013 onlyUsedBySelectOrBR(
LHS));
19016 if (isFoldableXorEq(
LHS,
RHS)) {
19017 RHS =
LHS.getOperand(1);
19018 LHS =
LHS.getOperand(0);
19044 if (Subtarget.hasVendorXAndesPerf()) {
19054 ShAmt =
LHS.getValueSizeInBits() - 1 - ShAmt;
19097 bool Commutative =
true;
19098 unsigned Opc = TrueVal.getOpcode();
19108 Commutative =
false;
19118 if (!TrueVal.hasOneUse())
19122 if (FalseVal == TrueVal.getOperand(0))
19124 else if (Commutative && FalseVal == TrueVal.getOperand(1))
19129 EVT VT =
N->getValueType(0);
19131 SDValue OtherOp = TrueVal.getOperand(1 - OpToFold);
19137 assert(IdentityOperand &&
"No identity operand!");
19142 DAG.
getSelect(
DL, OtherOpVT,
N->getOperand(0), OtherOp, IdentityOperand);
19143 return DAG.
getNode(TrueVal.getOpcode(),
DL, VT, FalseVal, NewSel);
19164 CountZeroes =
N->getOperand(2);
19165 ValOnZero =
N->getOperand(1);
19167 CountZeroes =
N->getOperand(1);
19168 ValOnZero =
N->getOperand(2);
19187 if (
Cond->getOperand(0) != CountZeroesArgument)
19206 CountZeroes, BitWidthMinusOne);
19216 EVT VT =
N->getValueType(0);
19217 EVT CondVT =
Cond.getValueType();
19225 (Subtarget.
hasCZEROLike() || Subtarget.hasVendorXTHeadCondMov())) {
19231 const APInt &MaskVal =
LHS.getConstantOperandAPInt(1);
19242 if (!TrueVal.hasOneUse() || !FalseVal.hasOneUse())
19246 if (TrueVal.getOpcode() ==
ISD::SUB && FalseVal.getOpcode() ==
ISD::ADD) {
19254 SDValue A = FalseVal.getOperand(0);
19255 SDValue B = FalseVal.getOperand(1);
19257 return ((TrueVal.getOperand(0) ==
A && TrueVal.getOperand(1) ==
B) ||
19258 (TrueVal.getOperand(1) ==
A && TrueVal.getOperand(0) ==
B));
19266 EVT VT =
N->getValueType(0);
19268 SDValue TrueVal =
N->getOperand(1);
19269 SDValue FalseVal =
N->getOperand(2);
19299 SDValue TrueVal =
N->getOperand(1);
19300 SDValue FalseVal =
N->getOperand(2);
19315 EVT VT =
N->getValueType(0);
19322 const unsigned Opcode =
N->op_begin()->getNode()->getOpcode();
19337 if (
Op.isUndef()) {
19350 if (
Op.getOpcode() != Opcode || !
Op.hasOneUse())
19359 if (
Op.getOperand(0).getValueType() !=
Op.getOperand(1).getValueType())
19383 EVT AVT =
A.getValueType();
19384 EVT BVT =
B.getValueType();
19414 if (AOpt || BOpt) {
19432 EVT OpVT =
A.getValueType();
19440 IsSigned ? ISD::PARTIAL_REDUCE_SMLA : ISD::PARTIAL_REDUCE_UMLA;
19454 EVT OpVT =
A.getOperand(0).getValueType();
19456 OpVT !=
B.getOperand(0).getValueType() ||
19462 Opc = ISD::PARTIAL_REDUCE_SMLA;
19465 Opc = ISD::PARTIAL_REDUCE_UMLA;
19468 Opc = ISD::PARTIAL_REDUCE_SUMLA;
19471 Opc = ISD::PARTIAL_REDUCE_SUMLA;
19485 if (!Subtarget.hasStdExtZvqdotq())
19489 EVT VT =
N->getValueType(0);
19492 return DAG.
getNode(ISD::VECREDUCE_ADD,
DL, VT, V);
19514 const unsigned InVecOpcode = InVec->
getOpcode();
19531 InVecLHS, InValLHS, EltNo);
19533 InVecRHS, InValRHS, EltNo);
19545 unsigned Elt = IndexC->getZExtValue();
19551 unsigned NewIdx = Elt % ConcatNumElts;
19553 unsigned ConcatOpIdx = Elt / ConcatNumElts;
19558 ConcatOps[ConcatOpIdx] = ConcatOp;
19570 EVT VT =
N->getValueType(0);
19582 !
SDValue(BaseLd, 0).hasOneUse())
19585 EVT BaseLdVT = BaseLd->getValueType(0);
19593 if (!Ld || !Ld->isSimple() || !
Op.hasOneUse() ||
19595 Ld->getValueType(0) != BaseLdVT)
19604 using PtrDiff = std::pair<std::variant<int64_t, SDValue>,
bool>;
19606 LoadSDNode *Ld2) -> std::optional<PtrDiff> {
19611 if (BIO1.equalBaseIndex(BIO2, DAG))
19616 SDValue P2 = Ld2->getBasePtr();
19619 if (P1.getOpcode() ==
ISD::ADD && P1.getOperand(0) == P2)
19620 return {{P1.getOperand(1),
true}};
19622 return std::nullopt;
19626 auto BaseDiff = GetPtrDiff(Lds[0], Lds[1]);
19631 for (
auto *It = Lds.
begin() + 1; It != Lds.
end() - 1; It++)
19632 if (GetPtrDiff(*It, *std::next(It)) != BaseDiff)
19640 unsigned WideScalarBitWidth =
19653 auto [StrideVariant, MustNegateStride] = *BaseDiff;
19655 std::holds_alternative<SDValue>(StrideVariant)
19656 ? std::get<SDValue>(StrideVariant)
19659 if (MustNegateStride)
19668 ConstStride && ConstStride->getSExtValue() >= 0)
19672 ConstStride->getSExtValue() * (
N->getNumOperands() - 1);
19678 BaseLd->getPointerInfo(), BaseLd->getMemOperand()->getFlags(), MemSize,
19682 WideVecVT,
DL, BaseLd->getChain(), BaseLd->getBasePtr(), Stride,
19696 EVT VT =
N->getValueType(0);
19713 for (
int MaskIndex : Mask) {
19714 bool SelectMaskVal = (MaskIndex < (int)NumElts);
19717 assert(MaskVals.
size() == NumElts &&
"Unexpected select-like shuffle");
19754 if (
N->getValueType(0).isFixedLengthVector())
19757 SDValue Addend =
N->getOperand(0);
19760 if (
N->getOpcode() == RISCVISD::ADD_VL) {
19761 SDValue AddPassthruOp =
N->getOperand(2);
19762 if (!AddPassthruOp.
isUndef())
19766 auto IsVWMulOpc = [](
unsigned Opc) {
19768 case RISCVISD::VWMUL_VL:
19769 case RISCVISD::VWMULU_VL:
19770 case RISCVISD::VWMULSU_VL:
19785 if (!MulPassthruOp.
isUndef())
19795 return std::make_pair(
N->getOperand(3),
N->getOperand(4));
19796 }(
N, DAG, Subtarget);
19801 if (AddMask != MulMask || AddVL != MulVL)
19804 const auto &TSInfo =
19806 unsigned Opc = TSInfo.getMAccOpcode(MulOp.
getOpcode());
19809 EVT VT =
N->getValueType(0);
19820 if (!
N->getValueType(0).isVector())
19823 SDValue Addend =
N->getOperand(0);
19826 if (
N->getOpcode() == RISCVISD::ADD_VL) {
19827 SDValue AddPassthruOp =
N->getOperand(2);
19828 if (!AddPassthruOp.
isUndef())
19832 auto IsVqdotqOpc = [](
unsigned Opc) {
19834 case RISCVISD::VQDOT_VL:
19835 case RISCVISD::VQDOTU_VL:
19836 case RISCVISD::VQDOTSU_VL:
19856 return std::make_pair(
N->getOperand(3),
N->getOperand(4));
19857 }(
N, DAG, Subtarget);
19860 if (AddVL != MulVL)
19863 if (AddMask.getOpcode() != RISCVISD::VMSET_VL ||
19864 AddMask.getOperand(0) != MulVL)
19869 EVT VT =
N->getValueType(0);
19870 Addend = DAG.
getNode(RISCVISD::ADD_VL,
DL, VT, Addend, AccumOp,
19871 DAG.
getUNDEF(VT), AddMask, AddVL);
19889 const EVT IndexVT = Index.getValueType();
19893 if (!isIndexTypeSigned(IndexType))
19925 assert(ShuffleMask.empty());
19927 for (
unsigned i = 0; i < Index->getNumOperands(); i++) {
19930 if (Index->getOperand(i)->isUndef())
19932 uint64_t C = Index->getConstantOperandVal(i);
19933 if (
C % ElementSize != 0)
19935 C =
C / ElementSize;
19938 ShuffleMask.push_back(
C);
19939 ActiveLanes.
set(
C);
19941 return ActiveLanes.
all();
19959 if (NumElems % 2 != 0)
19963 const unsigned WiderElementSize = ElementSize * 2;
19964 if (WiderElementSize > ST.getELen()/8)
19967 if (!ST.enableUnalignedVectorMem() && BaseAlign < WiderElementSize)
19970 for (
unsigned i = 0; i < Index->getNumOperands(); i++) {
19973 if (Index->getOperand(i)->isUndef())
19977 uint64_t C = Index->getConstantOperandVal(i);
19979 if (
C % WiderElementSize != 0)
19984 if (
C !=
Last + ElementSize)
20003 if (!IsVLMAX || Mask.getOpcode() != RISCVISD::VMSET_VL ||
20004 Mask.getOperand(0) != VL)
20007 auto IsTruncNode = [&](
SDValue V) {
20008 return V.getOpcode() == RISCVISD::TRUNCATE_VECTOR_VL &&
20009 V.getOperand(1) == Mask && V.getOperand(2) == VL;
20016 while (IsTruncNode(
Op)) {
20017 if (!
Op.hasOneUse())
20019 Op =
Op.getOperand(0);
20052 assert(
N->getOpcode() == RISCVISD::TRUNCATE_VECTOR_VL);
20054 MVT VT =
N->getSimpleValueType(0);
20059 auto MatchMinMax = [&VL, &Mask](
SDValue V,
unsigned Opc,
unsigned OpcVL,
20061 if (V.getOpcode() !=
Opc &&
20062 !(V.getOpcode() == OpcVL && V.getOperand(2).isUndef() &&
20063 V.getOperand(3) == Mask && V.getOperand(4) == VL))
20071 Op.getOperand(1).getValueType().isFixedLengthVector() &&
20073 Op.getOperand(1).getOperand(0).getValueType() ==
Op.getValueType() &&
20075 Op =
Op.getOperand(1).getOperand(0);
20078 return V.getOperand(0);
20080 if (
Op.getOpcode() == RISCVISD::VMV_V_X_VL &&
Op.getOperand(0).isUndef() &&
20081 Op.getOperand(2) == VL) {
20084 Op1->getAPIntValue().sextOrTrunc(
Op.getScalarValueSizeInBits());
20094 auto DetectUSatPattern = [&](
SDValue V) {
20106 MatchMinMax(SMinOp,
ISD::SMAX, RISCVISD::SMAX_VL, LoC))
20115 MatchMinMax(SMaxOp,
ISD::SMIN, RISCVISD::SMIN_VL, HiC))
20118 return DAG.
getNode(RISCVISD::SMAX_VL,
DL, V.getValueType(), SMinOp,
20119 V.getOperand(1), DAG.
getUNDEF(V.getValueType()),
20125 auto DetectSSatPattern = [&](
SDValue V) {
20127 unsigned NumSrcBits = V.getScalarValueSizeInBits();
20134 MatchMinMax(SMinOp,
ISD::SMAX, RISCVISD::SMAX_VL, LoC))
20135 if (HiC == SignedMax && LoC == SignedMin)
20140 MatchMinMax(SMaxOp,
ISD::SMIN, RISCVISD::SMIN_VL, HiC))
20141 if (HiC == SignedMax && LoC == SignedMin)
20150 while (Src.getOpcode() == RISCVISD::TRUNCATE_VECTOR_VL &&
20151 Src.getOperand(1) == Mask && Src.getOperand(2) == VL &&
20153 Src = Src.getOperand(0);
20157 if ((Val = DetectUSatPattern(Src)))
20158 ClipOpc = RISCVISD::TRUNCATE_VECTOR_VL_USAT;
20159 else if ((Val = DetectSSatPattern(Src)))
20160 ClipOpc = RISCVISD::TRUNCATE_VECTOR_VL_SSAT;
20169 Val = DAG.
getNode(ClipOpc,
DL, ValVT, Val, Mask, VL);
20170 }
while (ValVT != VT);
20188 unsigned Opc =
N->getOpcode();
20190 "Unexpected opcode");
20191 EVT VT =
N->getValueType(0);
20200 Src = Src.getOperand(0);
20202 if (Src.getOpcode() != ISD::BITCAST)
20204 Src = Src.getOperand(0);
20205 }
else if (
Opc == ISD::VECREDUCE_ADD) {
20208 Src = Src.getOperand(0);
20211 EVT SrcEVT = Src.getValueType();
20226 if (
Opc == ISD::VECREDUCE_ADD) {
20233 VectorBitsMax, EltSize, MinSize);
20238 MVT ContainerVT = SrcMVT;
20266 if (!
LHS.hasOneUse())
20269 switch (
LHS.getOpcode()) {
20271 case RISCVISD::VSEXT_VL:
20272 Opcode = RISCVISD::VWMULSU_VL;
20275 case RISCVISD::VZEXT_VL:
20276 Opcode = RISCVISD::VWMULU_VL;
20287 else if (
RHS.getOpcode() == RISCVISD::VMV_V_X_VL &&
20289 ShAmtInt =
RHS.getConstantOperandVal(1);
20302 if (ShAmtInt >= NarrowBits)
20304 MVT VT =
N->getSimpleValueType(0);
20311 switch (
N->getOpcode()) {
20316 case RISCVISD::SHL_VL:
20317 Passthru =
N->getOperand(2);
20318 Mask =
N->getOperand(3);
20319 VL =
N->getOperand(4);
20324 return DAG.
getNode(Opcode,
DL, VT, NarrowOp,
20326 Passthru, Mask, VL);
20332 const MVT XLenVT = Subtarget.getXLenVT();
20338 auto SimplifyDemandedLowBitsHelper = [&](
unsigned OpNo,
unsigned LowBits) {
20349 switch (
N->getOpcode()) {
20352 case RISCVISD::SplitF64: {
20356 if (Op0->
getOpcode() == RISCVISD::BuildPairF64)
20369 APInt V =
C->getValueAPF().bitcastToAPInt();
20398 case RISCVISD::SLLW:
20399 case RISCVISD::SRAW:
20400 case RISCVISD::SRLW:
20401 case RISCVISD::RORW:
20402 case RISCVISD::ROLW: {
20404 if (SimplifyDemandedLowBitsHelper(0, 32) ||
20405 SimplifyDemandedLowBitsHelper(1, 5))
20410 case RISCVISD::ABSW:
20411 case RISCVISD::CLZW:
20412 case RISCVISD::CTZW: {
20414 if (SimplifyDemandedLowBitsHelper(0, 32))
20418 case RISCVISD::FMV_W_X_RV64: {
20423 if (Op0.
getOpcode() == RISCVISD::FMV_X_ANYEXTW_RV64)
20427 case RISCVISD::FMV_X_ANYEXTH:
20428 case RISCVISD::FMV_X_ANYEXTW_RV64: {
20431 MVT VT =
N->getSimpleValueType(0);
20442 if ((
N->getOpcode() == RISCVISD::FMV_X_ANYEXTW_RV64 &&
20443 Op0->
getOpcode() == RISCVISD::FMV_W_X_RV64) ||
20444 (
N->getOpcode() == RISCVISD::FMV_X_ANYEXTH &&
20445 Op0->
getOpcode() == RISCVISD::FMV_H_X)) {
20447 "Unexpected value type!");
20457 LN0->getBasePtr(), IVT, LN0->getMemOperand());
20470 unsigned FPBits =
N->getOpcode() == RISCVISD::FMV_X_ANYEXTW_RV64 ? 32 : 16;
20481 EVT VT =
N->getValueType(0);
20530 EVT VT =
N->getValueType(0);
20547 if (!
C || !
C->getValueAPF().isExactlyValue(+1.0))
20562 case ISD::FMINNUM: {
20577 if (
N->getValueType(0) == MVT::i64 && Subtarget.is64Bit()) {
20582 Src.getOperand(0));
20587 Src.getOperand(0), Src.getOperand(1));
20595 case RISCVISD::TRUNCATE_VECTOR_VL:
20599 case ISD::VP_TRUNCATE:
20607 case RISCVISD::CZERO_EQZ:
20608 case RISCVISD::CZERO_NEZ: {
20612 unsigned Opc =
N->getOpcode();
20615 if (
Opc == RISCVISD::CZERO_EQZ && Val ==
Cond)
20619 Opc == RISCVISD::CZERO_EQZ ? RISCVISD::CZERO_NEZ : RISCVISD::CZERO_EQZ;
20627 return DAG.
getNode(InvOpc,
SDLoc(
N),
N->getValueType(0), Val, NewCond);
20637 N->getValueType(0), Val,
Cond.getOperand(0));
20641 case RISCVISD::SELECT_CC: {
20648 SDValue FalseV =
N->getOperand(4);
20650 EVT VT =
N->getValueType(0);
20653 if (TrueV == FalseV)
20684 return DAG.
getNode(RISCVISD::SELECT_CC,
DL,
N->getValueType(0),
20685 {LHS, RHS, CC, TrueV, FalseV});
20687 if (!Subtarget.hasConditionalMoveFusion()) {
20744 case RISCVISD::BR_CC: {
20751 return DAG.
getNode(RISCVISD::BR_CC,
DL,
N->getValueType(0),
20752 N->getOperand(0), LHS, RHS, CC,
N->getOperand(4));
20765 EVT VT =
N->getValueType(0);
20777 if (In2.
getOpcode() != ISD::FP_EXTEND &&
20786 DAG.
getNode(ISD::FNEG,
DL, VT, NewFPExtRound));
20788 case ISD::MGATHER: {
20790 const EVT VT =
N->getValueType(0);
20791 SDValue Index = MGN->getIndex();
20792 SDValue ScaleOp = MGN->getScale();
20794 assert(!MGN->isIndexScaled() &&
20795 "Scaled gather/scatter should not be formed");
20800 N->getVTList(), MGN->getMemoryVT(),
DL,
20801 {MGN->getChain(), MGN->getPassThru(), MGN->getMask(),
20802 MGN->getBasePtr(), Index, ScaleOp},
20803 MGN->getMemOperand(), IndexType, MGN->getExtensionType());
20807 N->getVTList(), MGN->getMemoryVT(),
DL,
20808 {MGN->getChain(), MGN->getPassThru(), MGN->getMask(),
20809 MGN->getBasePtr(), Index, ScaleOp},
20810 MGN->getMemOperand(), IndexType, MGN->getExtensionType());
20816 if (std::optional<VIDSequence> SimpleVID =
20818 SimpleVID && SimpleVID->StepDenominator == 1) {
20819 const int64_t StepNumerator = SimpleVID->StepNumerator;
20820 const int64_t Addend = SimpleVID->Addend;
20827 assert(MGN->getBasePtr()->getValueType(0) == PtrVT);
20835 VT,
DL, MGN->getChain(), BasePtr,
20837 EVL, MGN->getMemOperand());
20839 MGN->getPassThru());
20849 MGN->getBasePtr(), DAG.
getUNDEF(XLenVT),
20851 MGN->getMemoryVT(), MGN->getMemOperand(),
20860 MGN->getMemOperand()->getBaseAlign(), Subtarget)) {
20862 for (
unsigned i = 0; i < Index->getNumOperands(); i += 2)
20863 NewIndices.
push_back(Index.getOperand(i));
20864 EVT IndexVT = Index.getValueType()
20871 assert(EltCnt.isKnownEven() &&
"Splitting vector, but not in half!");
20873 EltCnt.divideCoefficientBy(2));
20876 EltCnt.divideCoefficientBy(2));
20881 {MGN->getChain(), Passthru, Mask, MGN->getBasePtr(),
20889 case ISD::MSCATTER:{
20891 SDValue Index = MSN->getIndex();
20892 SDValue ScaleOp = MSN->getScale();
20894 assert(!MSN->isIndexScaled() &&
20895 "Scaled gather/scatter should not be formed");
20900 N->getVTList(), MSN->getMemoryVT(),
DL,
20901 {MSN->getChain(), MSN->getValue(), MSN->getMask(), MSN->getBasePtr(),
20903 MSN->getMemOperand(), IndexType, MSN->isTruncatingStore());
20907 N->getVTList(), MSN->getMemoryVT(),
DL,
20908 {MSN->getChain(), MSN->getValue(), MSN->getMask(), MSN->getBasePtr(),
20910 MSN->getMemOperand(), IndexType, MSN->isTruncatingStore());
20912 EVT VT = MSN->getValue()->getValueType(0);
20914 if (!MSN->isTruncatingStore() &&
20918 return DAG.
getMaskedStore(MSN->getChain(),
DL, Shuffle, MSN->getBasePtr(),
20919 DAG.
getUNDEF(XLenVT), MSN->getMask(),
20920 MSN->getMemoryVT(), MSN->getMemOperand(),
20925 case ISD::VP_GATHER: {
20927 SDValue Index = VPGN->getIndex();
20928 SDValue ScaleOp = VPGN->getScale();
20930 assert(!VPGN->isIndexScaled() &&
20931 "Scaled gather/scatter should not be formed");
20936 {VPGN->getChain(), VPGN->getBasePtr(), Index,
20937 ScaleOp, VPGN->getMask(),
20938 VPGN->getVectorLength()},
20939 VPGN->getMemOperand(), IndexType);
20943 {VPGN->getChain(), VPGN->getBasePtr(), Index,
20944 ScaleOp, VPGN->getMask(),
20945 VPGN->getVectorLength()},
20946 VPGN->getMemOperand(), IndexType);
20950 case ISD::VP_SCATTER: {
20952 SDValue Index = VPSN->getIndex();
20953 SDValue ScaleOp = VPSN->getScale();
20955 assert(!VPSN->isIndexScaled() &&
20956 "Scaled gather/scatter should not be formed");
20961 {VPSN->getChain(), VPSN->getValue(),
20962 VPSN->getBasePtr(), Index, ScaleOp,
20963 VPSN->getMask(), VPSN->getVectorLength()},
20964 VPSN->getMemOperand(), IndexType);
20968 {VPSN->getChain(), VPSN->getValue(),
20969 VPSN->getBasePtr(), Index, ScaleOp,
20970 VPSN->getMask(), VPSN->getVectorLength()},
20971 VPSN->getMemOperand(), IndexType);
20974 case RISCVISD::SHL_VL:
20978 case RISCVISD::SRA_VL:
20979 case RISCVISD::SRL_VL: {
20981 if (ShAmt.
getOpcode() == RISCVISD::SPLAT_VECTOR_SPLIT_I64_VL) {
20985 EVT VT =
N->getValueType(0);
20988 return DAG.
getNode(
N->getOpcode(),
DL, VT,
N->getOperand(0), ShAmt,
20989 N->getOperand(2),
N->getOperand(3),
N->getOperand(4));
21004 if (ShAmt.
getOpcode() == RISCVISD::SPLAT_VECTOR_SPLIT_I64_VL) {
21007 EVT VT =
N->getValueType(0);
21010 DAG.
getRegister(RISCV::X0, Subtarget.getXLenVT()));
21011 return DAG.
getNode(
N->getOpcode(),
DL, VT,
N->getOperand(0), ShAmt);
21015 case RISCVISD::ADD_VL:
21023 case RISCVISD::VWADD_W_VL:
21024 case RISCVISD::VWADDU_W_VL:
21025 case RISCVISD::VWSUB_W_VL:
21026 case RISCVISD::VWSUBU_W_VL:
21028 case RISCVISD::OR_VL:
21029 case RISCVISD::SUB_VL:
21030 case RISCVISD::MUL_VL:
21032 case RISCVISD::VFMADD_VL:
21033 case RISCVISD::VFNMADD_VL:
21034 case RISCVISD::VFMSUB_VL:
21035 case RISCVISD::VFNMSUB_VL:
21036 case RISCVISD::STRICT_VFMADD_VL:
21037 case RISCVISD::STRICT_VFNMADD_VL:
21038 case RISCVISD::STRICT_VFMSUB_VL:
21039 case RISCVISD::STRICT_VFNMSUB_VL:
21041 case RISCVISD::FADD_VL:
21042 case RISCVISD::FSUB_VL:
21043 case RISCVISD::FMUL_VL:
21044 case RISCVISD::VFWADD_W_VL:
21045 case RISCVISD::VFWSUB_W_VL:
21053 if (
N->getOpcode() != ISD::STORE)
21057 SDValue Chain = Store->getChain();
21058 EVT MemVT = Store->getMemoryVT();
21059 SDValue Val = Store->getValue();
21062 bool IsScalarizable =
21064 Store->isSimple() &&
21094 NewVT, *Store->getMemOperand())) {
21096 return DAG.
getStore(Chain,
DL, NewV, Store->getBasePtr(),
21097 Store->getPointerInfo(), Store->getBaseAlign(),
21098 Store->getMemOperand()->getFlags());
21108 L->hasNUsesOfValue(1, 0) && L->hasNUsesOfValue(1, 1) &&
21110 L->getMemoryVT() == MemVT) {
21113 NewVT, *Store->getMemOperand()) &&
21115 NewVT, *L->getMemOperand())) {
21117 L->getPointerInfo(), L->getBaseAlign(),
21118 L->getMemOperand()->getFlags());
21119 return DAG.
getStore(Chain,
DL, NewL, Store->getBasePtr(),
21120 Store->getPointerInfo(), Store->getBaseAlign(),
21121 Store->getMemOperand()->getFlags());
21128 if ((Val.
getOpcode() == RISCVISD::VMV_X_S ||
21134 MVT VecVT = Src.getSimpleValueType();
21141 Store->getChain(),
DL, Src, Store->getBasePtr(), Store->getOffset(),
21144 Store->getMemOperand(), Store->getAddressingMode(),
21145 Store->isTruncatingStore(),
false);
21152 EVT VT =
N->getValueType(0);
21177 case RISCVISD::VFMV_V_F_VL: {
21178 const MVT VT =
N->getSimpleValueType(0);
21179 SDValue Passthru =
N->getOperand(0);
21180 SDValue Scalar =
N->getOperand(1);
21185 return DAG.
getNode(RISCVISD::VFMV_S_F_VL,
DL, VT, Passthru, Scalar, VL);
21188 case RISCVISD::VMV_V_X_VL: {
21189 const MVT VT =
N->getSimpleValueType(0);
21190 SDValue Passthru =
N->getOperand(0);
21191 SDValue Scalar =
N->getOperand(1);
21196 unsigned ScalarSize = Scalar.getValueSizeInBits();
21198 if (ScalarSize > EltWidth && Passthru.
isUndef())
21199 if (SimplifyDemandedLowBitsHelper(1, EltWidth))
21206 (!Const || Const->isZero() ||
21207 !Const->getAPIntValue().sextOrTrunc(EltWidth).isSignedIntN(5)))
21208 return DAG.
getNode(RISCVISD::VMV_S_X_VL,
DL, VT, Passthru, Scalar, VL);
21212 case RISCVISD::VFMV_S_F_VL: {
21217 if (
N->getOperand(0).isUndef() &&
21220 Src.getOperand(0).getValueType().isScalableVector()) {
21221 EVT VT =
N->getValueType(0);
21241 case RISCVISD::VMV_S_X_VL: {
21242 const MVT VT =
N->getSimpleValueType(0);
21243 SDValue Passthru =
N->getOperand(0);
21244 SDValue Scalar =
N->getOperand(1);
21250 unsigned ScalarSize = Scalar.getValueSizeInBits();
21252 if (ScalarSize > EltWidth && SimplifyDemandedLowBitsHelper(1, EltWidth))
21255 if (Scalar.getOpcode() == RISCVISD::VMV_X_S && Passthru.
isUndef() &&
21256 Scalar.getOperand(0).getValueType() ==
N->getValueType(0))
21257 return Scalar.getOperand(0);
21264 DAG.
getNode(
N->getOpcode(),
DL, M1VT, M1Passthru, Scalar, VL);
21273 Const && !Const->isZero() &&
isInt<5>(Const->getSExtValue()) &&
21275 return DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, VT, Passthru, Scalar, VL);
21279 case RISCVISD::VMV_X_S: {
21281 MVT VecVT =
N->getOperand(0).getSimpleValueType();
21283 if (M1VT.
bitsLT(VecVT)) {
21285 return DAG.
getNode(RISCVISD::VMV_X_S,
DL,
N->getSimpleValueType(0), Vec);
21293 unsigned IntNo =
N->getConstantOperandVal(IntOpNo);
21298 case Intrinsic::riscv_vcpop:
21299 case Intrinsic::riscv_vcpop_mask:
21300 case Intrinsic::riscv_vfirst:
21301 case Intrinsic::riscv_vfirst_mask: {
21303 if (IntNo == Intrinsic::riscv_vcpop_mask ||
21304 IntNo == Intrinsic::riscv_vfirst_mask)
21305 VL =
N->getOperand(3);
21310 EVT VT =
N->getValueType(0);
21311 if (IntNo == Intrinsic::riscv_vfirst ||
21312 IntNo == Intrinsic::riscv_vfirst_mask)
21316 case Intrinsic::riscv_vsseg2_mask:
21317 case Intrinsic::riscv_vsseg3_mask:
21318 case Intrinsic::riscv_vsseg4_mask:
21319 case Intrinsic::riscv_vsseg5_mask:
21320 case Intrinsic::riscv_vsseg6_mask:
21321 case Intrinsic::riscv_vsseg7_mask:
21322 case Intrinsic::riscv_vsseg8_mask: {
21324 unsigned NF = Tuple.getValueType().getRISCVVectorTupleNumFields();
21326 if (Subtarget.hasOptimizedSegmentLoadStore(NF) || !Tuple.hasOneUse() ||
21327 Tuple.getOpcode() != RISCVISD::TUPLE_INSERT ||
21328 !Tuple.getOperand(0).isUndef())
21336 "Type mismatch without bitcast?");
21337 unsigned Stride = SEW / 8 * NF;
21338 unsigned Offset = SEW / 8 * Idx;
21365 case ISD::EXPERIMENTAL_VP_REVERSE:
21367 case ISD::VP_STORE:
21369 case ISD::BITCAST: {
21370 assert(Subtarget.useRVVForFixedLengthVectors());
21372 EVT VT =
N->getValueType(0);
21383 for (
unsigned i = 0; i < NF; ++i)
21384 Result = DAG.
getNode(RISCVISD::TUPLE_INSERT,
DL, VT, Result,
Splat,
21390 if ((SrcVT == MVT::v1i1 || SrcVT == MVT::v2i1 || SrcVT == MVT::v4i1) &&
21403 case ISD::VECREDUCE_ADD:
21411 case RISCVISD::VRGATHER_VX_VL: {
21414 EVT VT =
N->getValueType(0);
21417 SDValue Passthru =
N->getOperand(2);
21424 Src = Src.getOperand(1);
21426 switch (Src.getOpcode()) {
21429 case RISCVISD::VMV_V_X_VL:
21430 case RISCVISD::VFMV_V_F_VL:
21438 case RISCVISD::VMV_S_X_VL:
21439 case RISCVISD::VFMV_S_F_VL:
21455 case RISCVISD::TUPLE_EXTRACT: {
21456 EVT VT =
N->getValueType(0);
21458 unsigned Idx =
N->getConstantOperandVal(1);
21463 switch (Tuple.getConstantOperandVal(1)) {
21466 case Intrinsic::riscv_vlseg2_mask:
21467 case Intrinsic::riscv_vlseg3_mask:
21468 case Intrinsic::riscv_vlseg4_mask:
21469 case Intrinsic::riscv_vlseg5_mask:
21470 case Intrinsic::riscv_vlseg6_mask:
21471 case Intrinsic::riscv_vlseg7_mask:
21472 case Intrinsic::riscv_vlseg8_mask:
21473 NF = Tuple.getValueType().getRISCVVectorTupleNumFields();
21477 if (!NF || Subtarget.hasOptimizedSegmentLoadStore(NF))
21482 "Type mismatch without bitcast?");
21483 unsigned Stride = SEW / 8 * NF;
21484 unsigned Offset = SEW / 8 * Idx;
21487 Tuple.getOperand(0),