43#include "llvm/IR/IntrinsicsRISCV.h"
57#define DEBUG_TYPE "riscv-lower"
63 cl::desc(
"Give the maximum size (in number of nodes) of the web of "
64 "instructions that we will consider for VW expansion"),
69 cl::desc(
"Allow the formation of VW_W operations (e.g., "
70 "VWADD_W) with splat constants"),
75 cl::desc(
"Set the minimum number of repetitions of a divisor to allow "
76 "transformation to multiplications by the reciprocal"),
81 cl::desc(
"Give the maximum number of instructions that we will "
82 "use for creating a floating-point immediate value"),
87 cl::desc(
"Swap add and addi in cases where the add may "
88 "be combined with a shift"),
107 !Subtarget.hasStdExtF()) {
108 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
109 "doesn't support the F instruction set extension (ignoring "
113 !Subtarget.hasStdExtD()) {
114 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
115 "doesn't support the D instruction set extension (ignoring "
134 MVT XLenVT = Subtarget.getXLenVT();
139 if (Subtarget.hasStdExtZfhmin())
141 if (Subtarget.hasStdExtZfbfmin() || Subtarget.hasVendorXAndesBFHCvt())
143 if (Subtarget.hasStdExtF())
145 if (Subtarget.hasStdExtD())
147 if (Subtarget.hasStdExtZhinxmin())
149 if (Subtarget.hasStdExtZfinx())
151 if (Subtarget.hasStdExtZdinx()) {
152 if (Subtarget.is64Bit())
159 MVT::nxv1i1, MVT::nxv2i1, MVT::nxv4i1, MVT::nxv8i1,
160 MVT::nxv16i1, MVT::nxv32i1, MVT::nxv64i1};
162 MVT::nxv1i8, MVT::nxv2i8, MVT::nxv4i8, MVT::nxv8i8, MVT::nxv16i8,
163 MVT::nxv32i8, MVT::nxv64i8, MVT::nxv1i16, MVT::nxv2i16, MVT::nxv4i16,
164 MVT::nxv8i16, MVT::nxv16i16, MVT::nxv32i16, MVT::nxv1i32, MVT::nxv2i32,
165 MVT::nxv4i32, MVT::nxv8i32, MVT::nxv16i32, MVT::nxv1i64, MVT::nxv2i64,
166 MVT::nxv4i64, MVT::nxv8i64};
168 MVT::nxv1f16, MVT::nxv2f16, MVT::nxv4f16,
169 MVT::nxv8f16, MVT::nxv16f16, MVT::nxv32f16};
171 MVT::nxv1bf16, MVT::nxv2bf16, MVT::nxv4bf16,
172 MVT::nxv8bf16, MVT::nxv16bf16, MVT::nxv32bf16};
174 MVT::nxv1f32, MVT::nxv2f32, MVT::nxv4f32, MVT::nxv8f32, MVT::nxv16f32};
176 MVT::nxv1f64, MVT::nxv2f64, MVT::nxv4f64, MVT::nxv8f64};
178 MVT::riscv_nxv1i8x2, MVT::riscv_nxv1i8x3, MVT::riscv_nxv1i8x4,
179 MVT::riscv_nxv1i8x5, MVT::riscv_nxv1i8x6, MVT::riscv_nxv1i8x7,
180 MVT::riscv_nxv1i8x8, MVT::riscv_nxv2i8x2, MVT::riscv_nxv2i8x3,
181 MVT::riscv_nxv2i8x4, MVT::riscv_nxv2i8x5, MVT::riscv_nxv2i8x6,
182 MVT::riscv_nxv2i8x7, MVT::riscv_nxv2i8x8, MVT::riscv_nxv4i8x2,
183 MVT::riscv_nxv4i8x3, MVT::riscv_nxv4i8x4, MVT::riscv_nxv4i8x5,
184 MVT::riscv_nxv4i8x6, MVT::riscv_nxv4i8x7, MVT::riscv_nxv4i8x8,
185 MVT::riscv_nxv8i8x2, MVT::riscv_nxv8i8x3, MVT::riscv_nxv8i8x4,
186 MVT::riscv_nxv8i8x5, MVT::riscv_nxv8i8x6, MVT::riscv_nxv8i8x7,
187 MVT::riscv_nxv8i8x8, MVT::riscv_nxv16i8x2, MVT::riscv_nxv16i8x3,
188 MVT::riscv_nxv16i8x4, MVT::riscv_nxv32i8x2};
190 if (Subtarget.hasVInstructions()) {
191 auto addRegClassForRVV = [
this](
MVT VT) {
195 if (VT.getVectorMinNumElements() < MinElts)
198 unsigned Size = VT.getSizeInBits().getKnownMinValue();
201 RC = &RISCV::VRRegClass;
203 RC = &RISCV::VRM2RegClass;
205 RC = &RISCV::VRM4RegClass;
207 RC = &RISCV::VRM8RegClass;
214 for (
MVT VT : BoolVecVTs)
215 addRegClassForRVV(VT);
216 for (
MVT VT : IntVecVTs) {
217 if (VT.getVectorElementType() == MVT::i64 &&
218 !Subtarget.hasVInstructionsI64())
220 addRegClassForRVV(VT);
223 if (Subtarget.hasVInstructionsF16Minimal() ||
224 Subtarget.hasVendorXAndesVPackFPH())
225 for (
MVT VT : F16VecVTs)
226 addRegClassForRVV(VT);
228 if (Subtarget.hasVInstructionsBF16Minimal() ||
229 Subtarget.hasVendorXAndesVBFHCvt())
230 for (
MVT VT : BF16VecVTs)
231 addRegClassForRVV(VT);
233 if (Subtarget.hasVInstructionsF32())
234 for (
MVT VT : F32VecVTs)
235 addRegClassForRVV(VT);
237 if (Subtarget.hasVInstructionsF64())
238 for (
MVT VT : F64VecVTs)
239 addRegClassForRVV(VT);
241 if (Subtarget.useRVVForFixedLengthVectors()) {
242 auto addRegClassForFixedVectors = [
this](
MVT VT) {
249 if (useRVVForFixedLengthVectorVT(VT))
250 addRegClassForFixedVectors(VT);
253 if (useRVVForFixedLengthVectorVT(VT))
254 addRegClassForFixedVectors(VT);
292 if (Subtarget.hasStdExtP()) {
293 if (Subtarget.is64Bit()) {
330 if (!(Subtarget.hasVendorXCValu() && !Subtarget.is64Bit())) {
340 if (!Subtarget.hasVendorXTHeadBb() && !Subtarget.hasVendorXqcibm() &&
341 !Subtarget.hasVendorXAndesPerf())
346 if (!Subtarget.hasStdExtZbb() && !Subtarget.hasVendorXTHeadBb() &&
347 !Subtarget.hasVendorXqcibm() && !Subtarget.hasVendorXAndesPerf() &&
348 !(Subtarget.hasVendorXCValu() && !Subtarget.is64Bit()))
351 if (Subtarget.hasStdExtZilsd() && !Subtarget.is64Bit()) {
356 if (Subtarget.is64Bit()) {
364 }
else if (Subtarget.hasStdExtP()) {
369 if (!Subtarget.hasStdExtZmmul()) {
371 }
else if (Subtarget.is64Bit()) {
378 if (!Subtarget.hasStdExtM()) {
381 }
else if (Subtarget.is64Bit()) {
383 {MVT::i8, MVT::i16, MVT::i32},
Custom);
391 if (!Subtarget.hasStdExtP() || !Subtarget.hasStdExtZmmul() ||
398 if (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) {
399 if (Subtarget.is64Bit())
401 }
else if (Subtarget.hasVendorXTHeadBb()) {
402 if (Subtarget.is64Bit())
405 }
else if (Subtarget.hasVendorXCVbitmanip() && !Subtarget.is64Bit()) {
411 if (Subtarget.hasStdExtP())
417 if (Subtarget.hasREVLike()) {
423 if (Subtarget.hasStdExtZbkb())
427 if (Subtarget.hasStdExtZbb() ||
428 (Subtarget.hasVendorXCValu() && !Subtarget.is64Bit())) {
433 if (Subtarget.hasCTZLike()) {
434 if (Subtarget.is64Bit())
440 if (!Subtarget.hasCPOPLike()) {
443 if (Subtarget.is64Bit())
450 if (Subtarget.hasCLZLike()) {
454 if (Subtarget.is64Bit() &&
455 (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtP()))
458 if (Subtarget.hasVendorXCVbitmanip() && !Subtarget.is64Bit())
463 if (Subtarget.hasStdExtP()) {
465 if (Subtarget.is64Bit())
469 if (Subtarget.hasStdExtP() ||
470 (Subtarget.hasVendorXCValu() && !Subtarget.is64Bit())) {
472 if (Subtarget.is64Bit())
474 }
else if (Subtarget.hasShortForwardBranchIALU()) {
477 }
else if (Subtarget.is64Bit()) {
481 if (!Subtarget.useMIPSCCMovInsn() && !Subtarget.hasVendorXTHeadCondMov())
484 if ((Subtarget.hasStdExtP() || Subtarget.hasVendorXqcia()) &&
485 !Subtarget.is64Bit()) {
488 }
else if (Subtarget.hasStdExtP() && Subtarget.is64Bit()) {
491 }
else if (!Subtarget.hasStdExtZbb() && Subtarget.is64Bit()) {
496 if ((Subtarget.hasStdExtP() || Subtarget.hasVendorXqcia()) &&
497 !Subtarget.is64Bit()) {
504 if (Subtarget.hasStdExtP() && !Subtarget.is64Bit()) {
510 if (Subtarget.hasStdExtZbc() || Subtarget.hasStdExtZbkc())
512 if (Subtarget.hasStdExtZbc())
515 static const unsigned FPLegalNodeTypes[] = {
531 static const unsigned FPOpToLibCall[] = {
ISD::FREM};
533 static const unsigned FPRndMode[] = {
537 static const unsigned ZfhminZfbfminPromoteOps[] = {
549 if (Subtarget.hasStdExtP()) {
550 static const MVT P32VecVTs[] = {MVT::v2i16, MVT::v4i8};
551 static const MVT P64VecVTs[] = {MVT::v2i32, MVT::v4i16, MVT::v8i8};
553 if (Subtarget.is64Bit()) {
560 {MVT::v2i16, MVT::v4i8},
Custom);
590 if (VT != MVT::v2i32)
592 if (VT.getVectorElementType() != MVT::i8) {
614 if (!Subtarget.is64Bit())
620 if (!Subtarget.is64Bit()) {
625 for (
MVT VT : P64VecVTs) {
647 {MVT::v4i16, MVT::v8i8},
Legal);
658 {MVT::v4i16, MVT::v8i8},
Custom);
665 {MVT::v4i16, MVT::v8i8},
Custom);
670 {MVT::v4i16, MVT::v2i32},
Legal);
680 {MVT::v4i16, MVT::v2i32},
Legal);
685 {MVT::v2i16, MVT::v4i8, MVT::v2i32, MVT::v4i16},
690 if (Subtarget.hasStdExtZfbfmin()) {
705 if (Subtarget.hasStdExtZfhminOrZhinxmin()) {
706 if (Subtarget.hasStdExtZfhOrZhinx()) {
713 if (Subtarget.hasStdExtZfa())
729 if (!Subtarget.hasStdExtD()) {
749 Subtarget.hasStdExtZfh() && Subtarget.hasStdExtZfa() ?
Legal :
Promote);
765 if (Subtarget.is64Bit())
769 if (Subtarget.hasStdExtFOrZfinx()) {
792 if (Subtarget.hasStdExtZfa()) {
801 if (Subtarget.hasStdExtFOrZfinx() && Subtarget.is64Bit())
804 if (Subtarget.hasStdExtDOrZdinx()) {
807 if (!Subtarget.is64Bit())
810 if (Subtarget.hasStdExtZdinx() && !Subtarget.hasStdExtZilsd() &&
811 !Subtarget.is64Bit()) {
816 if (Subtarget.hasStdExtZfa()) {
822 if (Subtarget.is64Bit())
852 if (Subtarget.is64Bit()) {
859 if (Subtarget.hasStdExtFOrZfinx()) {
885 if (Subtarget.is64Bit())
895 if (Subtarget.is64Bit()) {
902 if (Subtarget.is64Bit())
905 if (Subtarget.hasVendorXMIPSCBOP())
910 if (Subtarget.hasStdExtZalrsc()) {
912 if (Subtarget.hasStdExtZabha() && Subtarget.hasStdExtZacas())
916 }
else if (Subtarget.hasForcedAtomics()) {
931 if (Subtarget.hasVInstructions()) {
940 {MVT::i8, MVT::i16},
Custom);
941 if (Subtarget.is64Bit())
951 static const unsigned IntegerVPOps[] = {
952 ISD::VP_SDIV, ISD::VP_UDIV, ISD::VP_SREM,
953 ISD::VP_UREM, ISD::VP_REDUCE_ADD, ISD::VP_REDUCE_AND,
954 ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR, ISD::VP_REDUCE_SMAX,
955 ISD::VP_REDUCE_SMIN, ISD::VP_REDUCE_UMAX, ISD::VP_REDUCE_UMIN,
957 ISD::EXPERIMENTAL_VP_REVERSE, ISD::EXPERIMENTAL_VP_SPLICE,
958 ISD::VP_CTTZ_ELTS, ISD::VP_CTTZ_ELTS_ZERO_POISON};
960 static const unsigned FloatingPointVPOps[] = {
961 ISD::VP_REDUCE_FADD, ISD::VP_REDUCE_SEQ_FADD,
962 ISD::VP_REDUCE_FMIN, ISD::VP_REDUCE_FMAX, ISD::VP_MERGE,
963 ISD::VP_REDUCE_FMINIMUM, ISD::VP_REDUCE_FMAXIMUM};
965 static const unsigned IntegerVecReduceOps[] = {
970 static const unsigned FloatingPointVecReduceOps[] = {
974 static const unsigned FloatingPointLibCallOps[] = {
978 if (!Subtarget.is64Bit()) {
987 ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR,
988 ISD::VP_REDUCE_SMAX, ISD::VP_REDUCE_SMIN,
989 ISD::VP_REDUCE_UMAX, ISD::VP_REDUCE_UMIN},
993 for (
MVT VT : BoolVecVTs) {
1014 ISD::VP_CTTZ_ELTS, ISD::VP_CTTZ_ELTS_ZERO_POISON},
1022 {ISD::VP_REDUCE_AND, ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR}, VT,
1058 for (
MVT VT : IntVecVTs) {
1069 if (VT.getVectorElementType() == MVT::i64 && !Subtarget.hasStdExtV())
1075 if (Subtarget.hasStdExtZvabd()) {
1078 if (VT.getVectorElementType() == MVT::i8 ||
1079 VT.getVectorElementType() == MVT::i16)
1128 {ISD::VP_LOAD, ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1129 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER, ISD::VP_SCATTER},
1154 if (Subtarget.hasStdExtZvkb()) {
1161 if (Subtarget.hasStdExtZvbb()) {
1177 if (VT.getVectorElementType() == MVT::i64) {
1178 if (Subtarget.hasStdExtZvbc())
1181 if (Subtarget.hasStdExtZvbc32e()) {
1183 }
else if (Subtarget.hasStdExtZvbc()) {
1199 for (
MVT VT : VecTupleVTs) {
1220 static const unsigned ZvfhminZvfbfminPromoteOps[] = {
1256 static const unsigned ZvfbfaPromoteOps[] = {
ISD::FDIV,
1274 static const unsigned ZvfhminZvfbfminPromoteVPOps[] = {
1275 ISD::VP_REDUCE_FMIN,
1276 ISD::VP_REDUCE_FMAX,
1277 ISD::VP_REDUCE_FMINIMUM,
1278 ISD::VP_REDUCE_FMAXIMUM};
1281 const auto SetCommonVFPActions = [&](
MVT VT) {
1321 {ISD::VP_LOAD, ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1322 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER, ISD::VP_SCATTER},
1360 const auto SetCommonVFPExtLoadTruncStoreActions =
1362 for (
auto SmallVT : SmallerVTs) {
1370 const auto SetCommonPromoteToF32Actions = [&](
MVT VT) {
1395 ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1396 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER,
1423 const auto SetZvfbfaActions = [&](
MVT VT) {
1456 ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1457 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER,
1478 if (Subtarget.hasVInstructionsF16()) {
1479 for (
MVT VT : F16VecVTs) {
1482 SetCommonVFPActions(VT);
1484 }
else if (Subtarget.hasVInstructionsF16Minimal()) {
1485 for (
MVT VT : F16VecVTs) {
1488 SetCommonPromoteToF32Actions(VT);
1492 if (Subtarget.hasVInstructionsBF16()) {
1493 for (
MVT VT : BF16VecVTs) {
1496 SetZvfbfaActions(VT);
1498 }
else if (Subtarget.hasVInstructionsBF16Minimal()) {
1499 for (
MVT VT : BF16VecVTs) {
1502 SetCommonPromoteToF32Actions(VT);
1506 if (Subtarget.hasVInstructionsF32()) {
1507 for (
MVT VT : F32VecVTs) {
1510 SetCommonVFPActions(VT);
1511 SetCommonVFPExtLoadTruncStoreActions(VT, F16VecVTs);
1512 SetCommonVFPExtLoadTruncStoreActions(VT, BF16VecVTs);
1516 if (Subtarget.hasVInstructionsF64()) {
1517 for (
MVT VT : F64VecVTs) {
1520 SetCommonVFPActions(VT);
1521 SetCommonVFPExtLoadTruncStoreActions(VT, F16VecVTs);
1522 SetCommonVFPExtLoadTruncStoreActions(VT, BF16VecVTs);
1523 SetCommonVFPExtLoadTruncStoreActions(VT, F32VecVTs);
1527 if (Subtarget.useRVVForFixedLengthVectors()) {
1529 if (!useRVVForFixedLengthVectorVT(VT))
1578 {ISD::VP_REDUCE_AND, ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR}, VT,
1629 ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1630 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER,
1668 if (Subtarget.hasStdExtZvkb())
1671 if (Subtarget.hasStdExtZvbb()) {
1698 if (!useRVVForFixedLengthVectorVT(VT))
1724 ISD::VP_SCATTER, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1725 ISD::EXPERIMENTAL_VP_STRIDED_STORE},
1736 !Subtarget.hasVInstructionsF16()) {
1742 if (Subtarget.hasStdExtZfhmin()) {
1773 if (Subtarget.hasStdExtZfbfmin()) {
1780 if (Subtarget.hasVInstructionsBF16()) {
1801 if (Subtarget.hasVInstructionsBF16())
1845 if (Subtarget.is64Bit())
1847 if (Subtarget.hasStdExtZfhminOrZhinxmin())
1849 if (Subtarget.hasStdExtZfbfmin())
1851 if (Subtarget.hasStdExtFOrZfinx())
1853 if (Subtarget.hasStdExtDOrZdinx())
1858 if (Subtarget.hasStdExtZaamo())
1861 if (Subtarget.hasForcedAtomics()) {
1871 if (Subtarget.hasVendorXTHeadMemIdx()) {
1880 if (Subtarget.is64Bit()) {
1887 if (Subtarget.hasVendorXCVmem() && !Subtarget.is64Bit()) {
1898 if (Subtarget.hasStdExtZvdot4a8i() && Subtarget.getELen() >= 64) {
1908 if (Subtarget.useRVVForFixedLengthVectors()) {
1910 if (VT.getVectorElementType() != MVT::i32 ||
1911 !useRVVForFixedLengthVectorVT(VT))
1921 if (Subtarget.hasVendorXAndesBFHCvt() && !Subtarget.hasStdExtZfh()) {
1927 const Align FunctionAlignment(Subtarget.hasStdExtZca() ? 2 : 4);
1939 if (Subtarget.hasStdExtFOrZfinx())
1943 if (Subtarget.hasVInstructions())
1945 if (Subtarget.hasVInstructions() || Subtarget.hasStdExtP())
1948 if ((Subtarget.hasStdExtZbs() && Subtarget.is64Bit()) ||
1949 Subtarget.hasVInstructions() || Subtarget.hasStdExtP())
1952 if (Subtarget.hasStdExtZbkb())
1955 if (Subtarget.hasStdExtFOrZfinx())
1958 if (Subtarget.hasVInstructions())
1971 ISD::EXPERIMENTAL_VP_REVERSE,
1986 if (Subtarget.hasVendorXTHeadMemPair())
1988 if (Subtarget.useRVVForFixedLengthVectors() || Subtarget.hasStdExtP())
2014 Subtarget.getMaxStoresPerMemmove(
true);
2023 if (Subtarget.is64Bit() && Subtarget.hasStdExtP())
2024 if (VT == MVT::v2i16 || VT == MVT::v4i8)
2035 if (Subtarget.hasVInstructions() &&
2046bool RISCVTargetLowering::shouldExpandGetVectorLength(
EVT TripCountVT,
2048 bool IsScalable)
const {
2055 if (TripCountVT != MVT::i32 && TripCountVT != Subtarget.
getXLenVT())
2073 return !Subtarget.hasVInstructions() ||
2081 auto &
DL =
I.getDataLayout();
2083 auto SetRVVLoadStoreInfo = [&](
unsigned PtrOp,
bool IsStore,
2084 bool IsUnitStrided,
bool UsePtrVal =
false) {
2089 Info.ptrVal =
I.getArgOperand(PtrOp);
2091 Info.fallbackAddressSpace =
2092 I.getArgOperand(PtrOp)->getType()->getPointerAddressSpace();
2096 MemTy =
I.getArgOperand(0)->getType();
2099 MemTy =
I.getType();
2114 Info.align =
DL.getABITypeAlign(MemTy);
2124 if (
I.hasMetadata(LLVMContext::MD_nontemporal))
2131 case Intrinsic::riscv_masked_atomicrmw_xchg:
2132 case Intrinsic::riscv_masked_atomicrmw_add:
2133 case Intrinsic::riscv_masked_atomicrmw_sub:
2134 case Intrinsic::riscv_masked_atomicrmw_nand:
2135 case Intrinsic::riscv_masked_atomicrmw_max:
2136 case Intrinsic::riscv_masked_atomicrmw_min:
2137 case Intrinsic::riscv_masked_atomicrmw_umax:
2138 case Intrinsic::riscv_masked_atomicrmw_umin:
2139 case Intrinsic::riscv_masked_cmpxchg:
2146 Info.memVT = MVT::i32;
2147 Info.ptrVal =
I.getArgOperand(0);
2149 Info.align =
Align(4);
2154 case Intrinsic::riscv_seg2_load_mask:
2155 case Intrinsic::riscv_seg3_load_mask:
2156 case Intrinsic::riscv_seg4_load_mask:
2157 case Intrinsic::riscv_seg5_load_mask:
2158 case Intrinsic::riscv_seg6_load_mask:
2159 case Intrinsic::riscv_seg7_load_mask:
2160 case Intrinsic::riscv_seg8_load_mask:
2161 case Intrinsic::riscv_sseg2_load_mask:
2162 case Intrinsic::riscv_sseg3_load_mask:
2163 case Intrinsic::riscv_sseg4_load_mask:
2164 case Intrinsic::riscv_sseg5_load_mask:
2165 case Intrinsic::riscv_sseg6_load_mask:
2166 case Intrinsic::riscv_sseg7_load_mask:
2167 case Intrinsic::riscv_sseg8_load_mask:
2168 SetRVVLoadStoreInfo( 0,
false,
2171 case Intrinsic::riscv_seg2_store_mask:
2172 case Intrinsic::riscv_seg3_store_mask:
2173 case Intrinsic::riscv_seg4_store_mask:
2174 case Intrinsic::riscv_seg5_store_mask:
2175 case Intrinsic::riscv_seg6_store_mask:
2176 case Intrinsic::riscv_seg7_store_mask:
2177 case Intrinsic::riscv_seg8_store_mask:
2179 SetRVVLoadStoreInfo(
I.arg_size() - 3,
2183 case Intrinsic::riscv_sseg2_store_mask:
2184 case Intrinsic::riscv_sseg3_store_mask:
2185 case Intrinsic::riscv_sseg4_store_mask:
2186 case Intrinsic::riscv_sseg5_store_mask:
2187 case Intrinsic::riscv_sseg6_store_mask:
2188 case Intrinsic::riscv_sseg7_store_mask:
2189 case Intrinsic::riscv_sseg8_store_mask:
2191 SetRVVLoadStoreInfo(
I.arg_size() - 4,
2195 case Intrinsic::riscv_vlm:
2196 SetRVVLoadStoreInfo( 0,
2201 case Intrinsic::riscv_vle:
2202 case Intrinsic::riscv_vle_mask:
2203 case Intrinsic::riscv_vleff:
2204 case Intrinsic::riscv_vleff_mask:
2205 SetRVVLoadStoreInfo( 1,
2210 case Intrinsic::riscv_vsm:
2211 case Intrinsic::riscv_vse:
2212 case Intrinsic::riscv_vse_mask:
2213 SetRVVLoadStoreInfo( 1,
2218 case Intrinsic::riscv_vlse:
2219 case Intrinsic::riscv_vlse_mask:
2220 case Intrinsic::riscv_vloxei:
2221 case Intrinsic::riscv_vloxei_mask:
2222 case Intrinsic::riscv_vluxei:
2223 case Intrinsic::riscv_vluxei_mask:
2224 SetRVVLoadStoreInfo( 1,
2228 case Intrinsic::riscv_vsse:
2229 case Intrinsic::riscv_vsse_mask:
2230 case Intrinsic::riscv_vsoxei:
2231 case Intrinsic::riscv_vsoxei_mask:
2232 case Intrinsic::riscv_vsuxei:
2233 case Intrinsic::riscv_vsuxei_mask:
2234 SetRVVLoadStoreInfo( 1,
2238 case Intrinsic::riscv_vlseg2:
2239 case Intrinsic::riscv_vlseg3:
2240 case Intrinsic::riscv_vlseg4:
2241 case Intrinsic::riscv_vlseg5:
2242 case Intrinsic::riscv_vlseg6:
2243 case Intrinsic::riscv_vlseg7:
2244 case Intrinsic::riscv_vlseg8:
2245 case Intrinsic::riscv_vlseg2ff:
2246 case Intrinsic::riscv_vlseg3ff:
2247 case Intrinsic::riscv_vlseg4ff:
2248 case Intrinsic::riscv_vlseg5ff:
2249 case Intrinsic::riscv_vlseg6ff:
2250 case Intrinsic::riscv_vlseg7ff:
2251 case Intrinsic::riscv_vlseg8ff:
2252 SetRVVLoadStoreInfo(
I.arg_size() - 3,
2256 case Intrinsic::riscv_vlseg2_mask:
2257 case Intrinsic::riscv_vlseg3_mask:
2258 case Intrinsic::riscv_vlseg4_mask:
2259 case Intrinsic::riscv_vlseg5_mask:
2260 case Intrinsic::riscv_vlseg6_mask:
2261 case Intrinsic::riscv_vlseg7_mask:
2262 case Intrinsic::riscv_vlseg8_mask:
2263 case Intrinsic::riscv_vlseg2ff_mask:
2264 case Intrinsic::riscv_vlseg3ff_mask:
2265 case Intrinsic::riscv_vlseg4ff_mask:
2266 case Intrinsic::riscv_vlseg5ff_mask:
2267 case Intrinsic::riscv_vlseg6ff_mask:
2268 case Intrinsic::riscv_vlseg7ff_mask:
2269 case Intrinsic::riscv_vlseg8ff_mask:
2270 SetRVVLoadStoreInfo(
I.arg_size() - 5,
2274 case Intrinsic::riscv_vlsseg2:
2275 case Intrinsic::riscv_vlsseg3:
2276 case Intrinsic::riscv_vlsseg4:
2277 case Intrinsic::riscv_vlsseg5:
2278 case Intrinsic::riscv_vlsseg6:
2279 case Intrinsic::riscv_vlsseg7:
2280 case Intrinsic::riscv_vlsseg8:
2281 case Intrinsic::riscv_vloxseg2:
2282 case Intrinsic::riscv_vloxseg3:
2283 case Intrinsic::riscv_vloxseg4:
2284 case Intrinsic::riscv_vloxseg5:
2285 case Intrinsic::riscv_vloxseg6:
2286 case Intrinsic::riscv_vloxseg7:
2287 case Intrinsic::riscv_vloxseg8:
2288 case Intrinsic::riscv_vluxseg2:
2289 case Intrinsic::riscv_vluxseg3:
2290 case Intrinsic::riscv_vluxseg4:
2291 case Intrinsic::riscv_vluxseg5:
2292 case Intrinsic::riscv_vluxseg6:
2293 case Intrinsic::riscv_vluxseg7:
2294 case Intrinsic::riscv_vluxseg8:
2295 SetRVVLoadStoreInfo(
I.arg_size() - 4,
2299 case Intrinsic::riscv_vlsseg2_mask:
2300 case Intrinsic::riscv_vlsseg3_mask:
2301 case Intrinsic::riscv_vlsseg4_mask:
2302 case Intrinsic::riscv_vlsseg5_mask:
2303 case Intrinsic::riscv_vlsseg6_mask:
2304 case Intrinsic::riscv_vlsseg7_mask:
2305 case Intrinsic::riscv_vlsseg8_mask:
2306 case Intrinsic::riscv_vloxseg2_mask:
2307 case Intrinsic::riscv_vloxseg3_mask:
2308 case Intrinsic::riscv_vloxseg4_mask:
2309 case Intrinsic::riscv_vloxseg5_mask:
2310 case Intrinsic::riscv_vloxseg6_mask:
2311 case Intrinsic::riscv_vloxseg7_mask:
2312 case Intrinsic::riscv_vloxseg8_mask:
2313 case Intrinsic::riscv_vluxseg2_mask:
2314 case Intrinsic::riscv_vluxseg3_mask:
2315 case Intrinsic::riscv_vluxseg4_mask:
2316 case Intrinsic::riscv_vluxseg5_mask:
2317 case Intrinsic::riscv_vluxseg6_mask:
2318 case Intrinsic::riscv_vluxseg7_mask:
2319 case Intrinsic::riscv_vluxseg8_mask:
2320 SetRVVLoadStoreInfo(
I.arg_size() - 6,
2324 case Intrinsic::riscv_vsseg2:
2325 case Intrinsic::riscv_vsseg3:
2326 case Intrinsic::riscv_vsseg4:
2327 case Intrinsic::riscv_vsseg5:
2328 case Intrinsic::riscv_vsseg6:
2329 case Intrinsic::riscv_vsseg7:
2330 case Intrinsic::riscv_vsseg8:
2331 SetRVVLoadStoreInfo(
I.arg_size() - 3,
2335 case Intrinsic::riscv_vsseg2_mask:
2336 case Intrinsic::riscv_vsseg3_mask:
2337 case Intrinsic::riscv_vsseg4_mask:
2338 case Intrinsic::riscv_vsseg5_mask:
2339 case Intrinsic::riscv_vsseg6_mask:
2340 case Intrinsic::riscv_vsseg7_mask:
2341 case Intrinsic::riscv_vsseg8_mask:
2342 SetRVVLoadStoreInfo(
I.arg_size() - 4,
2346 case Intrinsic::riscv_vssseg2:
2347 case Intrinsic::riscv_vssseg3:
2348 case Intrinsic::riscv_vssseg4:
2349 case Intrinsic::riscv_vssseg5:
2350 case Intrinsic::riscv_vssseg6:
2351 case Intrinsic::riscv_vssseg7:
2352 case Intrinsic::riscv_vssseg8:
2353 case Intrinsic::riscv_vsoxseg2:
2354 case Intrinsic::riscv_vsoxseg3:
2355 case Intrinsic::riscv_vsoxseg4:
2356 case Intrinsic::riscv_vsoxseg5:
2357 case Intrinsic::riscv_vsoxseg6:
2358 case Intrinsic::riscv_vsoxseg7:
2359 case Intrinsic::riscv_vsoxseg8:
2360 case Intrinsic::riscv_vsuxseg2:
2361 case Intrinsic::riscv_vsuxseg3:
2362 case Intrinsic::riscv_vsuxseg4:
2363 case Intrinsic::riscv_vsuxseg5:
2364 case Intrinsic::riscv_vsuxseg6:
2365 case Intrinsic::riscv_vsuxseg7:
2366 case Intrinsic::riscv_vsuxseg8:
2367 SetRVVLoadStoreInfo(
I.arg_size() - 4,
2371 case Intrinsic::riscv_vssseg2_mask:
2372 case Intrinsic::riscv_vssseg3_mask:
2373 case Intrinsic::riscv_vssseg4_mask:
2374 case Intrinsic::riscv_vssseg5_mask:
2375 case Intrinsic::riscv_vssseg6_mask:
2376 case Intrinsic::riscv_vssseg7_mask:
2377 case Intrinsic::riscv_vssseg8_mask:
2378 case Intrinsic::riscv_vsoxseg2_mask:
2379 case Intrinsic::riscv_vsoxseg3_mask:
2380 case Intrinsic::riscv_vsoxseg4_mask:
2381 case Intrinsic::riscv_vsoxseg5_mask:
2382 case Intrinsic::riscv_vsoxseg6_mask:
2383 case Intrinsic::riscv_vsoxseg7_mask:
2384 case Intrinsic::riscv_vsoxseg8_mask:
2385 case Intrinsic::riscv_vsuxseg2_mask:
2386 case Intrinsic::riscv_vsuxseg3_mask:
2387 case Intrinsic::riscv_vsuxseg4_mask:
2388 case Intrinsic::riscv_vsuxseg5_mask:
2389 case Intrinsic::riscv_vsuxseg6_mask:
2390 case Intrinsic::riscv_vsuxseg7_mask:
2391 case Intrinsic::riscv_vsuxseg8_mask:
2392 SetRVVLoadStoreInfo(
I.arg_size() - 5,
2396 case Intrinsic::riscv_sf_vlte8:
2397 case Intrinsic::riscv_sf_vlte16:
2398 case Intrinsic::riscv_sf_vlte32:
2399 case Intrinsic::riscv_sf_vlte64:
2401 Info.ptrVal =
I.getArgOperand(1);
2403 case Intrinsic::riscv_sf_vlte8:
2404 Info.memVT = MVT::i8;
2405 Info.align =
Align(1);
2407 case Intrinsic::riscv_sf_vlte16:
2408 Info.memVT = MVT::i16;
2409 Info.align =
Align(2);
2411 case Intrinsic::riscv_sf_vlte32:
2412 Info.memVT = MVT::i32;
2413 Info.align =
Align(4);
2415 case Intrinsic::riscv_sf_vlte64:
2416 Info.memVT = MVT::i64;
2417 Info.align =
Align(8);
2424 case Intrinsic::riscv_sf_vste8:
2425 case Intrinsic::riscv_sf_vste16:
2426 case Intrinsic::riscv_sf_vste32:
2427 case Intrinsic::riscv_sf_vste64:
2429 Info.ptrVal =
I.getArgOperand(1);
2431 case Intrinsic::riscv_sf_vste8:
2432 Info.memVT = MVT::i8;
2433 Info.align =
Align(1);
2435 case Intrinsic::riscv_sf_vste16:
2436 Info.memVT = MVT::i16;
2437 Info.align =
Align(2);
2439 case Intrinsic::riscv_sf_vste32:
2440 Info.memVT = MVT::i32;
2441 Info.align =
Align(4);
2443 case Intrinsic::riscv_sf_vste64:
2444 Info.memVT = MVT::i64;
2445 Info.align =
Align(8);
2473 if (Subtarget.hasVendorXqcilo()) {
2502 if (Subtarget.hasVendorXqcilia())
2513 if (Subtarget.is64Bit() || !SrcTy->isIntegerTy() || !DstTy->
isIntegerTy())
2515 unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();
2517 return (SrcBits == 64 && DestBits == 32);
2528 return (SrcBits == 64 && DestBits == 32);
2534 if (Subtarget.hasVInstructions() &&
2539 if (SrcBits == DestBits * 2) {
2551 EVT MemVT = LD->getMemoryVT();
2552 if ((MemVT == MVT::i8 || MemVT == MVT::i16) &&
2562 return Subtarget.is64Bit() && SrcVT == MVT::i32 && DstVT == MVT::i64;
2570 return Subtarget.hasCTZLike();
2574 return Subtarget.hasCLZLike();
2585 if (!Subtarget.hasBEXTILike())
2590 return !Mask->getValue().isSignedIntN(12) && Mask->getValue().isPowerOf2();
2594 EVT VT =
Y.getValueType();
2599 return (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) &&
2604 EVT VT =
Y.getValueType();
2609 return Subtarget.hasStdExtZvkb();
2614 if (Subtarget.hasStdExtZbs())
2615 return X.getValueType().isScalarInteger();
2618 if (Subtarget.hasVendorXTHeadBs())
2619 return C !=
nullptr;
2621 return C &&
C->getAPIntValue().ule(10);
2625 unsigned BinOpcode,
EVT VT,
unsigned SelectOpcode,
SDValue X,
2631 if (!VT.
isVector() || !Subtarget.hasVInstructions())
2642 assert(Ty->isIntegerTy());
2644 unsigned BitSize = Ty->getIntegerBitWidth();
2645 if (BitSize > Subtarget.getXLen())
2649 int64_t Val = Imm.getSExtValue();
2657 if (!Subtarget.enableUnalignedScalarMem())
2667 return Seq.
size() <= Subtarget.getMaxBuildIntsCost();
2673 unsigned OldShiftOpcode,
unsigned NewShiftOpcode,
2728 if (!Subtarget.hasStdExtZfa())
2731 bool IsSupportedVT =
false;
2732 if (VT == MVT::f16) {
2733 IsSupportedVT = Subtarget.hasStdExtZfh() || Subtarget.hasStdExtZvfh();
2734 }
else if (VT == MVT::f32) {
2735 IsSupportedVT =
true;
2736 }
else if (VT == MVT::f64) {
2737 assert(Subtarget.hasStdExtD() &&
"Expect D extension");
2738 IsSupportedVT =
true;
2748 bool ForCodeSize)
const {
2749 bool IsLegalVT =
false;
2751 IsLegalVT = Subtarget.hasStdExtZfhminOrZhinxmin();
2752 else if (VT == MVT::f32)
2753 IsLegalVT = Subtarget.hasStdExtFOrZfinx();
2754 else if (VT == MVT::f64)
2755 IsLegalVT = Subtarget.hasStdExtDOrZdinx();
2756 else if (VT == MVT::bf16)
2757 IsLegalVT = Subtarget.hasStdExtZfbfmin();
2773 return Imm.isZero();
2777 if (Imm.isNegZero())
2782 const int FmvCost = Subtarget.hasStdExtZfinx() ? 0 : 1;
2785 Subtarget.getXLen(), Subtarget);
2791 unsigned Index)
const {
2792 if (!Subtarget.hasVInstructions())
2810 if (EltVT == MVT::i1)
2816 unsigned MinVLen = Subtarget.getRealMinVLen();
2823 if (Index + ResElts <= MinVLMAX && Index < 31)
2832 return (ResElts * 2) == SrcElts && Index == ResElts;
2840 if (VT == MVT::f16 && Subtarget.hasStdExtFOrZfinx() &&
2841 !Subtarget.hasStdExtZfhminOrZhinxmin())
2849 std::optional<MVT> RegisterVT)
const {
2851 if (VT == (Subtarget.is64Bit() ? MVT::i128 : MVT::i64) && RegisterVT &&
2852 *RegisterVT == MVT::Untyped)
2863 if (VT == MVT::f16 && Subtarget.hasStdExtFOrZfinx() &&
2864 !Subtarget.hasStdExtZfhminOrZhinxmin())
2883 !Subtarget.hasVendorXAndesPerf()) {
2889 ShAmt =
LHS.getValueSizeInBits() - 1 -
Log2_64(Mask);
2903 int64_t
C = RHSC->getSExtValue();
2913 if ((Subtarget.hasVendorXqcicm() || Subtarget.hasVendorXqcicli()) &&
2939 if ((Subtarget.hasVendorXqcicm() || Subtarget.hasVendorXqcicli()) &&
2974 if (VT.
SimpleTy >= MVT::riscv_nxv1i8x2 &&
2975 VT.
SimpleTy <= MVT::riscv_nxv1i8x8)
2977 if (VT.
SimpleTy >= MVT::riscv_nxv2i8x2 &&
2978 VT.
SimpleTy <= MVT::riscv_nxv2i8x8)
2980 if (VT.
SimpleTy >= MVT::riscv_nxv4i8x2 &&
2981 VT.
SimpleTy <= MVT::riscv_nxv4i8x8)
2983 if (VT.
SimpleTy >= MVT::riscv_nxv8i8x2 &&
2984 VT.
SimpleTy <= MVT::riscv_nxv8i8x8)
2986 if (VT.
SimpleTy >= MVT::riscv_nxv16i8x2 &&
2987 VT.
SimpleTy <= MVT::riscv_nxv16i8x4)
2989 if (VT.
SimpleTy == MVT::riscv_nxv32i8x2)
2999 switch (KnownSize) {
3027 return RISCV::VRRegClassID;
3029 return RISCV::VRM2RegClassID;
3031 return RISCV::VRM4RegClassID;
3033 return RISCV::VRM8RegClassID;
3041 static_assert(RISCV::sub_vrm1_7 == RISCV::sub_vrm1_0 + 7,
3042 "Unexpected subreg numbering");
3043 return RISCV::sub_vrm1_0 + Index;
3046 static_assert(RISCV::sub_vrm2_3 == RISCV::sub_vrm2_0 + 3,
3047 "Unexpected subreg numbering");
3048 return RISCV::sub_vrm2_0 + Index;
3051 static_assert(RISCV::sub_vrm4_1 == RISCV::sub_vrm4_0 + 1,
3052 "Unexpected subreg numbering");
3053 return RISCV::sub_vrm4_0 + Index;
3061 unsigned RegsPerField =
3064 switch (RegsPerField) {
3067 return RISCV::VRN2M1RegClassID;
3069 return RISCV::VRN3M1RegClassID;
3071 return RISCV::VRN4M1RegClassID;
3073 return RISCV::VRN5M1RegClassID;
3075 return RISCV::VRN6M1RegClassID;
3077 return RISCV::VRN7M1RegClassID;
3079 return RISCV::VRN8M1RegClassID;
3083 return RISCV::VRN2M2RegClassID;
3085 return RISCV::VRN3M2RegClassID;
3087 return RISCV::VRN4M2RegClassID;
3091 return RISCV::VRN2M4RegClassID;
3099 return RISCV::VRRegClassID;
3108std::pair<unsigned, unsigned>
3110 MVT VecVT,
MVT SubVecVT,
unsigned InsertExtractIdx,
3112 static_assert((RISCV::VRM8RegClassID > RISCV::VRM4RegClassID &&
3113 RISCV::VRM4RegClassID > RISCV::VRM2RegClassID &&
3114 RISCV::VRM2RegClassID > RISCV::VRRegClassID),
3115 "Register classes not ordered");
3122 if (VecRegClassID == SubRegClassID)
3123 return {RISCV::NoSubRegister, 0};
3126 "Only allow scalable vector subvector.");
3128 "Invalid vector tuple insert/extract for vector and subvector with "
3139 unsigned SubRegIdx = RISCV::NoSubRegister;
3140 for (
const unsigned RCID :
3141 {RISCV::VRM4RegClassID, RISCV::VRM2RegClassID, RISCV::VRRegClassID})
3142 if (VecRegClassID > RCID && SubRegClassID <= RCID) {
3146 SubRegIdx =
TRI->composeSubRegIndices(SubRegIdx,
3151 return {SubRegIdx, InsertExtractIdx};
3156bool RISCVTargetLowering::mergeStoresAfterLegalization(
EVT VT)
const {
3157 if (Subtarget.hasStdExtP() && !Subtarget.
is64Bit() &&
3158 (VT == MVT::i32 || VT == MVT::v2i16 || VT == MVT::v4i8))
3170 return Subtarget.is64Bit() ? Subtarget.hasVInstructionsI64() :
true;
3174 return Subtarget.hasVInstructions();
3176 return Subtarget.hasVInstructionsI64();
3178 return Subtarget.hasVInstructionsF16Minimal();
3180 return Subtarget.hasVInstructionsBF16Minimal();
3182 return Subtarget.hasVInstructionsF32();
3184 return Subtarget.hasVInstructionsF64();
3198 "Unexpected opcode");
3200 unsigned IntNo =
Op.getConstantOperandVal(HasChain ? 1 : 0);
3202 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo);
3205 return Op.getOperand(
II->VLOperand + 1 + HasChain);
3279bool RISCVTargetLowering::useRVVForFixedLengthVectorVT(
MVT VT)
const {
3280 return ::useRVVForFixedLengthVectorVT(VT, Subtarget);
3290 "Expected legal fixed length vector!");
3293 unsigned MaxELen = Subtarget.
getELen();
3321 return ::getContainerForFixedLengthVector(VT,
getSubtarget());
3328 "Expected to convert into a scalable vector!");
3329 assert(V.getValueType().isFixedLengthVector() &&
3330 "Expected a fixed length vector operand!");
3339 "Expected to convert into a fixed length vector!");
3340 assert(V.getValueType().isScalableVector() &&
3341 "Expected a scalable vector operand!");
3360 return DAG.
getNode(RISCVISD::VMSET_VL,
DL, MaskVT, VL);
3363static std::pair<SDValue, SDValue>
3372static std::pair<SDValue, SDValue>
3385static std::pair<SDValue, SDValue>
3402std::pair<unsigned, unsigned>
3410 unsigned VectorBitsMax = Subtarget.getRealMaxVLen();
3414 unsigned VectorBitsMin = Subtarget.getRealMinVLen();
3418 return std::make_pair(MinVLMAX, MaxVLMAX);
3430 EVT VT,
unsigned DefinedValues)
const {
3439 unsigned DLenFactor = Subtarget.getDLenFactor();
3444 std::tie(LMul, Fractional) =
3447 Cost = LMul <= DLenFactor ? (DLenFactor / LMul) : 1;
3449 Cost = (LMul * DLenFactor);
3463 bool Log2CostModel =
3465 if (Log2CostModel && LMULCost.isValid()) {
3466 unsigned Log =
Log2_64(LMULCost.getValue());
3468 return LMULCost * Log;
3470 return LMULCost * LMULCost;
3501 Op.getValueType() == MVT::bf16) {
3502 bool IsStrict =
Op->isStrictFPOpcode();
3507 {Op.getOperand(0), Op.getOperand(1)});
3509 {
Op.getValueType(), MVT::Other},
3515 DAG.
getNode(
Op.getOpcode(),
DL, MVT::f32,
Op.getOperand(0)),
3530 MVT DstVT =
Op.getSimpleValueType();
3539 Src.getValueType() == MVT::bf16) {
3545 Opc = IsSigned ? RISCVISD::FCVT_X : RISCVISD::FCVT_XU;
3546 else if (DstVT == MVT::i64 && SatVT == MVT::i32)
3547 Opc = IsSigned ? RISCVISD::FCVT_W_RV64 : RISCVISD::FCVT_WU_RV64;
3554 Opc,
DL, DstVT, Src,
3557 if (
Opc == RISCVISD::FCVT_WU_RV64)
3568 MVT SrcVT = Src.getSimpleValueType();
3574 if (SatVT != DstEltVT)
3577 MVT DstContainerVT = DstVT;
3578 MVT SrcContainerVT = SrcVT;
3584 "Expected same element count");
3593 {Src, Src, DAG.getCondCode(ISD::SETNE),
3594 DAG.getUNDEF(Mask.getValueType()), Mask, VL});
3598 if (DstEltSize > (2 * SrcEltSize)) {
3601 Src = DAG.
getNode(RISCVISD::FP_EXTEND_VL,
DL, InterVT, Src, Mask, VL);
3604 MVT CvtContainerVT = DstContainerVT;
3605 MVT CvtEltVT = DstEltVT;
3606 if (SrcEltSize > (2 * DstEltSize)) {
3612 IsSigned ? RISCVISD::VFCVT_RTZ_X_F_VL : RISCVISD::VFCVT_RTZ_XU_F_VL;
3615 while (CvtContainerVT != DstContainerVT) {
3619 unsigned ClipOpc = IsSigned ? RISCVISD::TRUNCATE_VECTOR_VL_SSAT
3620 : RISCVISD::TRUNCATE_VECTOR_VL_USAT;
3621 Res = DAG.
getNode(ClipOpc,
DL, CvtContainerVT, Res, Mask, VL);
3625 RISCVISD::VMV_V_X_VL,
DL, DstContainerVT, DAG.
getUNDEF(DstContainerVT),
3627 Res = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, DstContainerVT, IsNan, SplatZero,
3628 Res, DAG.
getUNDEF(DstContainerVT), VL);
3638 bool IsStrict =
Op->isStrictFPOpcode();
3639 SDValue SrcVal =
Op.getOperand(IsStrict ? 1 : 0);
3649 {
Op.getOperand(0), SrcVal});
3650 return DAG.
getNode(
Op.getOpcode(),
DL, {Op.getValueType(), MVT::Other},
3651 {Ext.getValue(1), Ext.getValue(0)});
3700 MVT VT =
Op.getSimpleValueType();
3710 MVT ContainerVT = VT;
3719 SDValue Abs = DAG.
getNode(RISCVISD::FABS_VL,
DL, ContainerVT, Src, Mask, VL);
3732 DAG.
getUNDEF(ContainerVT), MaxValNode, VL);
3737 DAG.
getNode(RISCVISD::SETCC_VL,
DL, SetccVT,
3746 switch (
Op.getOpcode()) {
3756 Truncated = DAG.
getNode(RISCVISD::VFCVT_RM_X_F_VL,
DL, IntVT, Src, Mask,
3761 Truncated = DAG.
getNode(RISCVISD::VFCVT_RTZ_X_F_VL,
DL, IntVT, Src,
3765 Truncated = DAG.
getNode(RISCVISD::VFROUND_NOEXCEPT_VL,
DL, ContainerVT, Src,
3771 if (Truncated.
getOpcode() != RISCVISD::VFROUND_NOEXCEPT_VL)
3772 Truncated = DAG.
getNode(RISCVISD::SINT_TO_FP_VL,
DL, ContainerVT, Truncated,
3776 Truncated = DAG.
getNode(RISCVISD::FCOPYSIGN_VL,
DL, ContainerVT, Truncated,
3777 Src, Src, Mask, VL);
3792 MVT VT =
Op.getSimpleValueType();
3796 MVT ContainerVT = VT;
3808 MVT MaskVT = Mask.getSimpleValueType();
3811 {Chain, Src, Src, DAG.getCondCode(ISD::SETUNE),
3812 DAG.getUNDEF(MaskVT), Mask, VL});
3814 Src = DAG.
getNode(RISCVISD::STRICT_FADD_VL,
DL,
3816 {Chain, Src, Src, Src, Unorder, VL});
3820 SDValue Abs = DAG.
getNode(RISCVISD::FABS_VL,
DL, ContainerVT, Src, Mask, VL);
3833 DAG.
getUNDEF(ContainerVT), MaxValNode, VL);
3837 RISCVISD::SETCC_VL,
DL, MaskVT,
3845 switch (
Op.getOpcode()) {
3855 RISCVISD::STRICT_VFCVT_RM_X_F_VL,
DL, DAG.
getVTList(IntVT, MVT::Other),
3856 {Chain, Src, Mask, DAG.getTargetConstant(FRM, DL, XLenVT), VL});
3861 DAG.
getNode(RISCVISD::STRICT_VFCVT_RTZ_X_F_VL,
DL,
3862 DAG.
getVTList(IntVT, MVT::Other), Chain, Src, Mask, VL);
3865 Truncated = DAG.
getNode(RISCVISD::STRICT_VFROUND_NOEXCEPT_VL,
DL,
3866 DAG.
getVTList(ContainerVT, MVT::Other), Chain, Src,
3874 Truncated = DAG.
getNode(RISCVISD::STRICT_SINT_TO_FP_VL,
DL,
3875 DAG.
getVTList(ContainerVT, MVT::Other), Chain,
3876 Truncated, Mask, VL);
3881 Truncated = DAG.
getNode(RISCVISD::FCOPYSIGN_VL,
DL, ContainerVT, Truncated,
3882 Src, Src, Mask, VL);
3892 MVT VT =
Op.getSimpleValueType();
3913 return DAG.
getNode(RISCVISD::FROUND,
DL, VT, Src, MaxValNode,
3921 MVT DstVT =
Op.getSimpleValueType();
3923 MVT SrcVT = Src.getSimpleValueType();
3928 MVT DstContainerVT = DstVT;
3929 MVT SrcContainerVT = SrcVT;
3941 if (SrcElemType == MVT::f16 || SrcElemType == MVT::bf16) {
3943 Src = DAG.
getNode(RISCVISD::FP_EXTEND_VL,
DL, F32VT, Src, Mask, VL);
3947 DAG.
getNode(RISCVISD::VFCVT_RM_X_F_VL,
DL, DstContainerVT, Src, Mask,
3967 return DAG.
getNode(RISCVISD::VSLIDEDOWN_VL,
DL, VT,
Ops);
3979 return DAG.
getNode(RISCVISD::VSLIDEUP_VL,
DL, VT,
Ops);
4004 return std::nullopt;
4022 unsigned EltSizeInBits) {
4025 return std::nullopt;
4026 bool IsInteger =
Op.getValueType().isInteger();
4028 std::optional<unsigned> SeqStepDenom;
4029 std::optional<APInt> SeqStepNum;
4030 std::optional<APInt> SeqAddend;
4031 std::optional<std::pair<APInt, unsigned>> PrevElt;
4032 assert(EltSizeInBits >=
Op.getValueType().getScalarSizeInBits());
4037 const unsigned OpSize =
Op.getScalarValueSizeInBits();
4038 for (
auto [Idx, Elt] :
enumerate(
Op->op_values())) {
4039 if (Elt.isUndef()) {
4040 Elts[Idx] = std::nullopt;
4044 Elts[Idx] = Elt->getAsAPIntVal().trunc(OpSize).zext(EltSizeInBits);
4049 return std::nullopt;
4050 Elts[Idx] = *ExactInteger;
4054 for (
auto [Idx, Elt] :
enumerate(Elts)) {
4063 unsigned IdxDiff = Idx - PrevElt->second;
4064 APInt ValDiff = *Elt - PrevElt->first;
4072 int64_t Remainder = ValDiff.
srem(IdxDiff);
4077 return std::nullopt;
4078 ValDiff = ValDiff.
sdiv(IdxDiff);
4083 SeqStepNum = ValDiff;
4084 else if (ValDiff != SeqStepNum)
4085 return std::nullopt;
4088 SeqStepDenom = IdxDiff;
4089 else if (IdxDiff != *SeqStepDenom)
4090 return std::nullopt;
4094 if (!PrevElt || PrevElt->first != *Elt)
4095 PrevElt = std::make_pair(*Elt, Idx);
4099 if (!SeqStepNum || !SeqStepDenom)
4100 return std::nullopt;
4104 for (
auto [Idx, Elt] :
enumerate(Elts)) {
4108 (
APInt(EltSizeInBits, Idx,
false,
true) *
4110 .sdiv(*SeqStepDenom);
4112 APInt Addend = *Elt - ExpectedVal;
4115 else if (Addend != SeqAddend)
4116 return std::nullopt;
4119 assert(SeqAddend &&
"Must have an addend if we have a step");
4121 return VIDSequence{SeqStepNum->getSExtValue(), *SeqStepDenom,
4122 SeqAddend->getSExtValue()};
4137 if (EltTy == MVT::i1 ||
4140 MVT SrcVT = Src.getSimpleValueType();
4156 MVT ContainerVT = VT;
4160 MVT SrcContainerVT = SrcVT;
4175 SDValue Gather = DAG.
getNode(RISCVISD::VRGATHER_VX_VL,
DL, ContainerVT, Src,
4176 Idx, DAG.
getUNDEF(ContainerVT), Mask, VL);
4184 MVT VT =
Op.getSimpleValueType();
4193 int64_t StepNumerator = SimpleVID->StepNumerator;
4194 unsigned StepDenominator = SimpleVID->StepDenominator;
4195 int64_t Addend = SimpleVID->Addend;
4197 assert(StepNumerator != 0 &&
"Invalid step");
4198 bool Negate =
false;
4199 int64_t SplatStepVal = StepNumerator;
4203 if (StepNumerator != 1 && StepNumerator !=
INT64_MIN &&
4205 Negate = StepNumerator < 0;
4207 SplatStepVal =
Log2_64(std::abs(StepNumerator));
4217 (SplatStepVal >= 0 || StepDenominator == 1) &&
isInt<32>(Addend)) {
4227 if ((StepOpcode ==
ISD::MUL && SplatStepVal != 1) ||
4228 (StepOpcode ==
ISD::SHL && SplatStepVal != 0)) {
4230 VID = DAG.
getNode(StepOpcode,
DL, VIDVT, VID, SplatStep);
4232 if (StepDenominator != 1) {
4237 if (Addend != 0 || Negate) {
4263 MVT VT =
Op.getSimpleValueType();
4272 unsigned NumElts =
Op.getNumOperands();
4275 unsigned MostCommonCount = 0;
4277 unsigned NumUndefElts =
4285 unsigned NumScalarLoads = 0;
4291 unsigned &
Count = ValueCounts[V];
4294 NumScalarLoads += !CFP->isPosZero();
4299 if (++
Count >= MostCommonCount) {
4301 MostCommonCount =
Count;
4305 assert(DominantValue &&
"Not expecting an all-undef BUILD_VECTOR");
4306 unsigned NumDefElts = NumElts - NumUndefElts;
4307 unsigned DominantValueCountThreshold = NumDefElts <= 2 ? 0 : NumDefElts - 2;
4313 ((MostCommonCount > DominantValueCountThreshold) ||
4325 if (
SDValue LastOp =
Op->getOperand(
Op->getNumOperands() - 1);
4326 !LastOp.isUndef() && ValueCounts[LastOp] == 1 &&
4327 LastOp != DominantValue) {
4330 VT.
isFloatingPoint() ? RISCVISD::VFSLIDE1DOWN_VL : RISCVISD::VSLIDE1DOWN_VL;
4336 Processed.
insert(LastOp);
4342 if (V.isUndef() || !Processed.
insert(V).second)
4344 if (ValueCounts[V] == 1) {
4352 return DAG.getConstant(V == V1, DL, XLenVT);
4368 MVT VT =
Op.getSimpleValueType();
4377 unsigned NumElts =
Op.getNumOperands();
4398 unsigned NumViaIntegerBits = std::clamp(NumElts, 8u, Subtarget.
getXLen());
4399 NumViaIntegerBits = std::min(NumViaIntegerBits, Subtarget.
getELen());
4407 unsigned IntegerViaVecElts =
divideCeil(NumElts, NumViaIntegerBits);
4408 MVT IntegerViaVecVT =
4413 unsigned BitPos = 0, IntegerEltIdx = 0;
4416 for (
unsigned I = 0;
I < NumElts;) {
4418 bool BitValue = !V.isUndef() && V->getAsZExtVal();
4419 Bits |= ((
uint64_t)BitValue << BitPos);
4425 if (
I % NumViaIntegerBits == 0 ||
I == NumElts) {
4426 if (NumViaIntegerBits <= 32)
4429 Elts[IntegerEltIdx] = Elt;
4438 if (NumElts < NumViaIntegerBits) {
4442 assert(IntegerViaVecVT == MVT::v1i8 &&
"Unexpected mask vector type");
4457 : RISCVISD::VMV_V_X_VL;
4477 assert((ViaIntVT == MVT::i16 || ViaIntVT == MVT::i32) &&
4478 "Unexpected sequence type");
4482 unsigned ViaVecLen =
4490 const auto &SeqV =
OpIdx.value();
4491 if (!SeqV.isUndef())
4493 ((SeqV->getAsZExtVal() & EltMask) << (
OpIdx.index() * EltBitSize));
4499 if (ViaIntVT == MVT::i32)
4522 BV->getRepeatedSequence(Sequence) &&
4523 (Sequence.size() * EltBitSize) <= Subtarget.
getELen()) {
4524 unsigned SeqLen = Sequence.size();
4526 assert((ViaIntVT == MVT::i16 || ViaIntVT == MVT::i32 ||
4527 ViaIntVT == MVT::i64) &&
4528 "Unexpected sequence type");
4533 const unsigned RequiredVL = NumElts / SeqLen;
4534 const unsigned ViaVecLen =
4536 NumElts : RequiredVL;
4539 unsigned EltIdx = 0;
4544 for (
const auto &SeqV : Sequence) {
4545 if (!SeqV.isUndef())
4547 ((SeqV->getAsZExtVal() & EltMask) << (EltIdx * EltBitSize));
4554 if (ViaIntVT == MVT::i32)
4561 (!Subtarget.
is64Bit() && ViaIntVT == MVT::i64)) &&
4562 "Unexpected bitcast sequence");
4566 MVT ViaContainerVT =
4569 DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ViaContainerVT,
4573 if (ViaVecLen != RequiredVL)
4592 Source, DAG, Subtarget);
4593 SDValue Res = DAG.
getNode(RISCVISD::VSEXT_VL,
DL, ContainerVT, Source, Mask, VL);
4612 return RISCV::PACKH;
4614 return Subtarget.
is64Bit() ? RISCV::PACKW : RISCV::PACK;
4629 MVT VT =
Op.getSimpleValueType();
4637 if (!Subtarget.hasStdExtZbb() || !Subtarget.hasStdExtZba())
4642 if (ElemSizeInBits >= std::min(Subtarget.
getELen(), Subtarget.
getXLen()) ||
4656 if (Subtarget.hasStdExtZbkb())
4661 ElemDL, XLenVT,
A,
B),
4673 NewOperands.
reserve(NumElts / 2);
4675 NewOperands.
push_back(pack(
Op.getOperand(i),
Op.getOperand(i + 1)));
4685 MVT VT =
Op.getSimpleValueType();
4693 if (Subtarget.isRV32() && Subtarget.hasStdExtP()) {
4694 if (VT != MVT::v4i8)
4707 DAG.
getNode(RISCVISD::PPAIRE_DB,
DL, {MVT::v4i8, MVT::v4i8},
4708 {Val0, Val2, Val1, Val3});
4714 RISCV::PACK,
DL, MVT::i32,
4715 {DAG.getNode(ISD::BITCAST, DL, MVT::i32, PPairDB.getValue(0)),
4716 DAG.getNode(ISD::BITCAST, DL, MVT::i32, PPairDB.getValue(1))}),
4729 if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
4730 (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin())) {
4740 NewOps[
I] = DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT, Elem);
4792 bool IsScalar =
all_of(
Op->ops().drop_front(),
4793 [](
const SDUse &U) { return U.get().isUndef(); });
4796 ? (IsScalar ? RISCVISD::VFMV_S_F_VL : RISCVISD::VFMV_V_F_VL)
4797 : (IsScalar ? RISCVISD::VMV_S_X_VL : RISCVISD::VMV_V_X_VL);
4825 auto OneVRegOfOps =
ArrayRef(BuildVectorOps).slice(i, ElemsPerVReg);
4829 unsigned InsertIdx = (i / ElemsPerVReg) * NumOpElts;
4851 unsigned NumUndefElts =
4853 unsigned NumDefElts = NumElts - NumUndefElts;
4854 if (NumDefElts >= 8 && NumDefElts > NumElts / 2 &&
4861 for (
const auto &[Idx, U] :
enumerate(
Op->ops())) {
4863 if (Idx < NumElts / 2) {
4870 bool SelectMaskVal = (Idx < NumElts / 2);
4873 assert(SubVecAOps.
size() == NumElts && SubVecBOps.
size() == NumElts &&
4874 MaskVals.
size() == NumElts);
4909 unsigned UndefCount = 0;
4916 LinearBudget -= PerSlideCost;
4919 LinearBudget -= PerSlideCost;
4922 LinearBudget -= PerSlideCost;
4925 if (LinearBudget < 0)
4930 "Illegal type which will result in reserved encoding");
4946 bool SlideUp =
false;
4971 if (EVecEltVT != ContainerEltVT)
4992 std::reverse(Operands.
begin(), Operands.
end());
5020 Vec = getVSlide(ContainerVT, DAG.
getUNDEF(ContainerVT), Vec,
Offset, Mask,
5027 Opcode = SlideUp ? RISCVISD::VFSLIDE1UP_VL : RISCVISD::VFSLIDE1DOWN_VL;
5029 Opcode = SlideUp ? RISCVISD::VSLIDE1UP_VL : RISCVISD::VSLIDE1DOWN_VL;
5038 Vec = getVSlide(ContainerVT, DAG.
getUNDEF(ContainerVT), Vec,
Offset, Mask,
5054 if ((LoC >> 31) == HiC)
5055 return DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, VT, Passthru,
Lo, VL);
5067 auto InterVec = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, InterVT,
5076 Hi.getConstantOperandVal(1) == 31)
5077 return DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, VT, Passthru,
Lo, VL);
5082 return DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, VT, Passthru,
Lo, VL);
5085 return DAG.
getNode(RISCVISD::SPLAT_VECTOR_SPLIT_I64_VL,
DL, VT, Passthru,
Lo,
5095 assert(Scalar.getValueType() == MVT::i64 &&
"Unexpected VT!");
5107 bool HasPassthru = Passthru && !Passthru.
isUndef();
5108 if (!HasPassthru && !Passthru)
5117 if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
5118 (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin()))
5119 Scalar = DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT, Scalar);
5128 return DAG.
getNode(RISCVISD::VFMV_V_F_VL,
DL, VT, Passthru, Scalar, VL);
5132 if (Scalar.getValueType().bitsLE(XLenVT)) {
5139 Scalar = DAG.
getNode(ExtOpc,
DL, XLenVT, Scalar);
5140 return DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, VT, Passthru, Scalar, VL);
5143 assert(XLenVT == MVT::i32 && Scalar.getValueType() == MVT::i64 &&
5144 "Unexpected scalar for splat lowering!");
5147 return DAG.
getNode(RISCVISD::VMV_S_X_VL,
DL, VT, Passthru,
5173 MVT ExtractedContainerVT = ExtractedVT;
5175 ExtractedContainerVT =
5178 ExtractedVal, DAG, Subtarget);
5180 if (ExtractedContainerVT.
bitsLE(VT))
5192 if (!Scalar.getValueType().bitsLE(XLenVT))
5195 VT,
DL, DAG, Subtarget);
5203 Scalar = DAG.
getNode(ExtOpc,
DL, XLenVT, Scalar);
5213 EVT VT =
V1.getValueType();
5227 if (
V1.getConstantOperandVal(1) != 0 ||
5244 Src && Src.
getValueType().getVectorNumElements() == (NumElts * 2))
5251 MVT ContainerVT = VT;
5269 if (!Subtarget.hasStdExtZvzip())
5275 int Size = Mask.size();
5277 assert(
Size == (
int)NumElts &&
"Unexpected mask size");
5283 EvenSrc = StartIndexes[0];
5284 OddSrc = StartIndexes[1];
5287 if (EvenSrc != 0 && OddSrc != 0)
5297 int HalfNumElts = NumElts / 2;
5298 return ((EvenSrc % HalfNumElts) == 0) && ((OddSrc % HalfNumElts) == 0);
5303 std::array<std::pair<int, int>, 2> &SrcInfo) {
5308 if (SrcInfo[0].second == 0 && SrcInfo[1].second == 0)
5312 if ((SrcInfo[0].second > 0 && SrcInfo[1].second < 0) ||
5313 SrcInfo[1].second == 0)
5315 assert(SrcInfo[0].first != -1 &&
"Must find one slide");
5323 if (SrcInfo[1].first == -1)
5325 return SrcInfo[0].second < 0 && SrcInfo[1].second > 0 &&
5326 SrcInfo[1].second - SrcInfo[0].second == (int)NumElts;
5331 bool RequiredPolarity) {
5332 int NumElts = Mask.size();
5333 for (
const auto &[Idx, M] :
enumerate(Mask)) {
5336 int Src = M >= NumElts;
5337 int Diff = (int)Idx - (M % NumElts);
5338 bool C = Src == SrcInfo[1].first && Diff == SrcInfo[1].second;
5339 assert(
C != (Src == SrcInfo[0].first && Diff == SrcInfo[0].second) &&
5340 "Must match exactly one of the two slides");
5341 if (RequiredPolarity != (
C == (Idx / Factor) % 2))
5353static bool isPairEven(
const std::array<std::pair<int, int>, 2> &SrcInfo,
5355 Factor = SrcInfo[1].second;
5357 Mask.size() % Factor == 0 &&
5369static bool isPairOdd(
const std::array<std::pair<int, int>, 2> &SrcInfo,
5371 Factor = -SrcInfo[1].second;
5373 Mask.size() % Factor == 0 &&
5386 ElementCount SrcEC = Src.getValueType().getVectorElementCount();
5393 unsigned Shift = Index * EltBits;
5418 std::optional<int> SplatIdx;
5420 if (M == -1 ||
I == (
unsigned)M)
5422 if (SplatIdx && *SplatIdx != M)
5431 for (
int MaskIndex : Mask) {
5432 bool SelectMaskVal = MaskIndex == *SplatIdx;
5435 assert(MaskVals.
size() == NumElts &&
"Unexpected select-like shuffle");
5460 auto findNonEXTRACT_SUBVECTORParent =
5461 [](
SDValue Parent) -> std::pair<SDValue, uint64_t> {
5466 Parent.getOperand(0).getSimpleValueType().isFixedLengthVector()) {
5467 Offset += Parent.getConstantOperandVal(1);
5468 Parent = Parent.getOperand(0);
5470 return std::make_pair(Parent,
Offset);
5473 auto [V1Src, V1IndexOffset] = findNonEXTRACT_SUBVECTORParent(
V1);
5474 auto [V2Src, V2IndexOffset] = findNonEXTRACT_SUBVECTORParent(V2);
5483 for (
size_t i = 0; i != NewMask.
size(); ++i) {
5484 if (NewMask[i] == -1)
5487 if (
static_cast<size_t>(NewMask[i]) < NewMask.
size()) {
5488 NewMask[i] = NewMask[i] + V1IndexOffset;
5492 NewMask[i] = NewMask[i] - NewMask.
size() + V2IndexOffset;
5498 if (NewMask[0] <= 0)
5502 for (
unsigned i = 1; i != NewMask.
size(); ++i)
5503 if (NewMask[i - 1] + 1 != NewMask[i])
5507 MVT SrcVT = Src.getSimpleValueType();
5536 int NumSubElts, Index;
5541 bool OpsSwapped = Mask[Index] < (int)NumElts;
5543 SDValue ToInsert = OpsSwapped ?
V1 : V2;
5554 if (NumSubElts + Index >= (
int)NumElts)
5565 Res = DAG.
getNode(RISCVISD::VMV_V_V_VL,
DL, ContainerVT, InPlace, ToInsert,
5568 Res =
getVSlideup(DAG, Subtarget,
DL, ContainerVT, InPlace, ToInsert,
5591 unsigned NumElts = Mask.size();
5594 int Lane = Mask[Idx];
5599 bool SecondOp =
false;
5600 if ((
unsigned)Lane < NumElts) {
5601 OrigLane = V1Mask[Lane];
5603 OrigLane = V2Mask[Lane - NumElts];
5609 if ((
unsigned)OrigLane >= NumElts)
5612 OrigLane += NumElts;
5613 NewMask[Idx] = OrigLane;
5630 bool OpsSwapped =
false;
5645 const unsigned E = Mask.size() - ((
Offset > 0) ?
Offset : 0);
5646 for (
unsigned i = S; i !=
E; ++i)
5647 if (Mask[i] >= 0 && (
unsigned)Mask[i] !=
Base + i +
Offset)
5653 bool IsVSlidedown = isSlideMask(Mask, OpsSwapped ? 0 : NumElts, 1);
5654 if (!IsVSlidedown && !isSlideMask(Mask, OpsSwapped ? 0 : NumElts, -1))
5657 const int InsertIdx = Mask[IsVSlidedown ? (NumElts - 1) : 0];
5659 if (InsertIdx < 0 || InsertIdx / NumElts != (
unsigned)OpsSwapped)
5677 IsVSlidedown ? RISCVISD::VSLIDE1DOWN_VL : RISCVISD::VSLIDE1UP_VL,
DL,
5683 auto OpCode = IsVSlidedown ?
5684 (VT.
isFloatingPoint() ? RISCVISD::VFSLIDE1DOWN_VL : RISCVISD::VSLIDE1DOWN_VL) :
5685 (VT.
isFloatingPoint() ? RISCVISD::VFSLIDE1UP_VL : RISCVISD::VSLIDE1UP_VL);
5688 auto Vec = DAG.
getNode(OpCode,
DL, ContainerVT,
5691 Splat, TrueMask, VL);
5703 for (
unsigned i = 0; i < Mask.size(); i++)
5704 LaneIsUndef[i % Factor] &= (Mask[i] == -1);
5707 for (
unsigned i = 0; i < Factor; i++) {
5718 for (
unsigned i = 0; i < Mask.size() / Factor; i++) {
5719 unsigned j = i * Factor + Index;
5720 if (Mask[j] != -1 && (
unsigned)Mask[j] != i)
5729 assert(RISCVISD::VPAIRE_VL ==
Opc || RISCVISD::VPAIRO_VL ==
Opc);
5737 MVT ContainerVT = IntVT;
5744 MVT InnerVT = ContainerVT;
5763 MVT ContainerVT = IntVT;
5773 DAG.
getNode(RISCVISD::VZIP_VL,
DL, ResVT, Op0, Op1, Passthru, Mask, VL);
5784 assert(
Opc == RISCVISD::VUNZIPE_VL ||
Opc == RISCVISD::VUNZIPO_VL);
5785 MVT VT =
Op.getSimpleValueType();
5790 MVT ContainerVT = IntVT;
5825 MVT VT = V.getSimpleValueType();
5840 EC.multiplyCoefficientBy(Factor));
5859 MVT VecContainerVT = VecVT;
5876 MVT WideContainerVT = WideVT;
5882 EvenV = DAG.
getBitcast(VecContainerVT, EvenV);
5889 if (Subtarget.hasStdExtZvbb()) {
5893 Interleaved = DAG.
getNode(RISCVISD::VWSLL_VL,
DL, WideContainerVT, OddV,
5894 OffsetVec, Passthru, Mask, VL);
5895 Interleaved = DAG.
getNode(RISCVISD::VWADDU_W_VL,
DL, WideContainerVT,
5896 Interleaved, EvenV, Passthru, Mask, VL);
5903 Interleaved = DAG.
getNode(RISCVISD::VWADDU_VL,
DL, WideContainerVT, EvenV,
5904 OddV, Passthru, Mask, VL);
5910 OddV, AllOnesVec, Passthru, Mask, VL);
5917 Interleaved = DAG.
getNode(RISCVISD::ADD_VL,
DL, WideContainerVT,
5918 Interleaved, OddsMul, Passthru, Mask, VL);
5925 Interleaved = DAG.
getBitcast(ResultContainerVT, Interleaved);
5971 if (ViaEltSize > NumElts)
5979 if (ViaEltSize > NumElts)
5985 if (ViaEltSize > NumElts)
5992 MVT &RotateVT,
unsigned &RotateAmt) {
5995 unsigned NumSubElts;
5997 NumElts, NumSubElts, RotateAmt))
6000 NumElts / NumSubElts);
6068 unsigned NumOfSrcRegs = NumElts / NumOpElts;
6069 unsigned NumOfDestRegs = NumElts / NumOpElts;
6078 Mask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs,
6080 [&](
ArrayRef<int> SrcSubMask,
unsigned SrcVecIdx,
unsigned DstVecIdx) {
6081 Operands.
emplace_back().emplace_back(SrcVecIdx, UINT_MAX,
6084 [&](
ArrayRef<int> SrcSubMask,
unsigned Idx1,
unsigned Idx2,
bool NewReg) {
6089 assert(Operands.
size() == NumOfDestRegs &&
"Whole vector must be processed");
6094 unsigned NumShuffles = std::accumulate(
6095 Operands.
begin(), Operands.
end(), 0u,
6101 for (const auto &P : Data) {
6102 unsigned Idx2 = std::get<1>(P);
6103 ArrayRef<int> Mask = std::get<2>(P);
6104 if (Idx2 != UINT_MAX)
6106 else if (ShuffleVectorInst::isIdentityMask(Mask, Mask.size()))
6111 if ((NumOfDestRegs > 2 && NumShuffles > NumOfDestRegs) ||
6112 (NumOfDestRegs <= 2 && NumShuffles >= 4))
6114 auto ExtractValue = [&, &DAG = DAG](
SDValue SrcVec,
unsigned ExtractIdx) {
6115 SDValue SubVec = DAG.getExtractSubvector(
DL, M1VT, SrcVec, ExtractIdx);
6119 auto PerformShuffle = [&, &DAG = DAG](
SDValue SubVec1,
SDValue SubVec2,
6121 SDValue SubVec = DAG.getVectorShuffle(OneRegVT,
DL, SubVec1, SubVec2, Mask);
6124 SDValue Vec = DAG.getUNDEF(ContainerVT);
6130 const auto &[Idx1, Idx2,
_] =
Data[
I];
6138 V = ExtractValue(Idx1 >= NumOfSrcRegs ? V2 :
V1,
6139 (Idx1 % NumOfSrcRegs) * NumOpElts);
6140 if (Idx2 != UINT_MAX) {
6143 V = ExtractValue(Idx2 >= NumOfSrcRegs ? V2 :
V1,
6144 (Idx2 % NumOfSrcRegs) * NumOpElts);
6148 for (
const auto &[Idx1, Idx2, Mask] :
Data) {
6151 V = PerformShuffle(
V1, V2, Mask);
6155 unsigned InsertIdx =
I * NumOpElts;
6157 Vec = DAG.getInsertSubvector(
DL, Vec, V, InsertIdx);
6167 bool SawUndef =
false;
6168 for (
const auto &[Idx, M] :
enumerate(Mask)) {
6175 if (Idx > (
unsigned)M)
6208 for (
int Idx : Mask) {
6211 unsigned SrcIdx = Idx % Mask.size();
6212 int Src = (
uint32_t)Idx < Mask.size() ? 0 : 1;
6213 if (Srcs[SrcIdx] == -1)
6216 else if (Srcs[SrcIdx] != Src)
6222 for (
int Lane : Srcs) {
6235 for (
unsigned I = 0;
I < Mask.size();
I++) {
6239 NewMask[
I] = Mask[
I] % Mask.size();
6253 if ((M / Span) != (
int)(
I / Span))
6255 int SpanIdx =
I % Span;
6265 return all_of(Mask, [&](
const auto &Idx) {
return Idx == -1 || Idx < Span; });
6277 int SpanIdx =
I % Span;
6278 if (Mask[SpanIdx] != M)
6292 MVT VT =
Op.getSimpleValueType();
6300 if (ElementSize > 32)
6328 if (VT != MVT::v8i8 && VT != MVT::v4i16)
6334 unsigned EvenSrc = StartIndexes[0];
6335 unsigned OddSrc = StartIndexes[1];
6336 if (EvenSrc == 0 && OddSrc == NumElts)
6337 return DAG.
getNode(RISCVISD::PZIP,
DL, VT,
V1, V2);
6338 if (EvenSrc == NumElts && OddSrc == 0)
6339 return DAG.
getNode(RISCVISD::PZIP,
DL, VT, V2,
V1);
6350 MVT XLenVT = Subtarget.getXLenVT();
6351 MVT VT =
Op.getSimpleValueType();
6356 if (Subtarget.hasStdExtP() && !Subtarget.hasVInstructions()) {
6360 auto IsLowReverse = [&](
unsigned L) {
6363 all_of(
Mask.drop_front(L), [](
int M) { return M < 0; });
6365 if (IsLowReverse(NumElts))
6371 IsLowReverse(NumElts / 2)) {
6409 auto [TrueMask, VL] = TrueMaskVL;
6424 V.getOperand(0).getSimpleValueType().getVectorNumElements();
6425 V =
V.getOperand(
Offset / OpElements);
6438 SDVTList VTs = DAG.
getVTList({ContainerVT, MVT::Other});
6455 MVT SplatVT = ContainerVT;
6458 if (SVT == MVT::bf16 ||
6459 (SVT == MVT::f16 && !Subtarget.hasStdExtZfh())) {
6468 V = DAG.
getLoad(SVT,
DL, Ld->getChain(), NewAddr,
6469 Ld->getPointerInfo().getWithOffset(
Offset),
6470 Ld->getBaseAlign(), Ld->getMemOperand()->getFlags());
6473 Ld->getPointerInfo().getWithOffset(
Offset), SVT,
6475 Ld->getMemOperand()->getFlags());
6479 : RISCVISD::VMV_V_X_VL;
6487 assert(Lane < (
int)NumElts &&
"Unexpected lane!");
6490 DAG.
getUNDEF(ContainerVT), TrueMask, VL);
6512 if (Subtarget.hasStdExtZvkb())
6528 assert(MaxFactor == 2 || MaxFactor == 4 || MaxFactor == 8);
6529 for (
unsigned Factor = 2; Factor <= MaxFactor; Factor <<= 1) {
6532 1 <
count_if(Mask, [](
int Idx) {
return Idx != -1; })) {
6536 [&Mask](
int Idx) {
return Idx < (int)
Mask.size(); }) &&
6537 1 <
count_if(Mask, [&Mask](
int Idx) {
6538 return Idx >= (int)
Mask.size();
6568 if (Subtarget.hasStdExtZvzip() &&
6570 1 <
count_if(Mask, [](
int Idx) {
return Idx != -1; })) {
6571 bool UsesBothSources =
6573 [&Mask](
int Idx) {
return Idx < (int)
Mask.size(); }) &&
6575 [&Mask](
int Idx) {
return Idx >= (int)
Mask.size(); });
6578 unsigned Opc =
Index == 0 ? RISCVISD::VUNZIPE_VL : RISCVISD::VUNZIPO_VL;
6584 }
else if (
auto VLEN = Subtarget.getRealVLen();
6594 if (UsesBothSources &&
6595 V1.getSimpleValueType().getVectorMinNumElements() >= 2 &&
6610 int EvenSrc, OddSrc;
6620 bool LaneIsUndef[2] = {
true,
true};
6621 for (
const auto &[Idx, M] :
enumerate(Mask))
6622 LaneIsUndef[Idx % 2] &= (
M == -1);
6626 if (LaneIsUndef[0]) {
6629 assert(EvenSrc >= 0 &&
"Undef source?");
6630 EvenV = (EvenSrc /
Size) == 0 ?
V1 : V2;
6634 if (LaneIsUndef[1]) {
6637 assert(OddSrc >= 0 &&
"Undef source?");
6638 OddV = (OddSrc /
Size) == 0 ?
V1 : V2;
6655 std::array<std::pair<int, int>, 2> SrcInfo;
6662 auto GetSourceFor = [&](
const std::pair<int, int> &
Info) {
6663 int SrcIdx =
Info.first;
6664 assert(SrcIdx == 0 || SrcIdx == 1);
6665 SDValue &Src = Sources[SrcIdx];
6672 auto GetSlide = [&](
const std::pair<int, int> &Src,
SDValue Mask,
6674 auto [TrueMask, VL] = TrueMaskVL;
6675 SDValue SrcV = GetSourceFor(Src);
6676 int SlideAmt = Src.second;
6677 if (SlideAmt == 0) {
6679 assert(Mask == TrueMask);
6686 return getVSlideup(DAG, Subtarget,
DL, ContainerVT, Passthru, SrcV,
6691 if (SrcInfo[1].first == -1) {
6693 Res = GetSlide(SrcInfo[0], TrueMask, Res);
6697 if (Subtarget.hasStdExtZvzip()) {
6698 bool TryWiden =
false;
6702 SDValue Src1 = SrcInfo[0].first == 0 ?
V1 : V2;
6703 SDValue Src2 = SrcInfo[1].first == 0 ?
V1 : V2;
6711 SDValue Src1 = SrcInfo[1].first == 0 ?
V1 : V2;
6712 SDValue Src2 = SrcInfo[0].first == 0 ?
V1 : V2;
6731 for (
const auto &[Idx, M] :
enumerate(Mask)) {
6733 (SrcInfo[1].second > 0 && Idx < (
unsigned)SrcInfo[1].second)) {
6737 int Src =
M >= (int)NumElts;
6738 int Diff = (int)Idx - (M % NumElts);
6739 bool C = Src == SrcInfo[1].first && Diff == SrcInfo[1].second;
6740 assert(
C ^ (Src == SrcInfo[0].first && Diff == SrcInfo[0].second) &&
6741 "Must match exactly one of the two slides");
6744 assert(MaskVals.
size() == NumElts &&
"Unexpected select-like shuffle");
6751 Res = GetSlide(SrcInfo[0], TrueMask, Res);
6752 Res = GetSlide(SrcInfo[1], SelectMask, Res);
6757 assert(!
V1.isUndef() &&
"Unexpected shuffle canonicalization");
6772 assert(MaxFactor == 2 || MaxFactor == 4 || MaxFactor == 8);
6773 for (
unsigned Factor = 4; Factor <= MaxFactor; Factor <<= 1) {
6786 unsigned MinVLen = Subtarget.getRealMinVLen();
6788 if (NumElts > MinVLMAX) {
6789 unsigned MaxIdx = 0;
6793 MaxIdx = std::max({(unsigned)
I, (
unsigned)
M, MaxIdx});
6795 unsigned NewNumElts =
6796 std::max((uint64_t)MinVLMAX,
PowerOf2Ceil(MaxIdx + 1));
6797 if (NewNumElts != NumElts) {
6801 Mask.take_front(NewNumElts));
6818 for (
auto Idx : Mask) {
6821 assert(Idx >= 0 && (
unsigned)Idx < NumElts);
6831 any_of(Mask, [&](
const auto &Idx) {
return Idx > 255; })) {
6841 unsigned GatherVVOpc = RISCVISD::VRGATHER_VV_VL;
6847 GatherVVOpc = RISCVISD::VRGATHEREI16_VV_VL;
6855 (IndexVT.
getSizeInBits() / Subtarget.getRealMinVLen()) > 1) {
6856 GatherVVOpc = RISCVISD::VRGATHEREI16_VV_VL;
6860 MVT IndexContainerVT =
6865 for (
int MaskIndex : Mask) {
6866 bool IsLHSIndex = MaskIndex < (int)NumElts && MaskIndex >= 0;
6876 if (NumElts <= MinVLMAX) {
6878 DAG.
getUNDEF(ContainerVT), TrueMask, VL);
6884 auto [InnerTrueMask, InnerVL] =
6896 for (
int i = 0; i <
N; i++) {
6900 DAG.
getNode(GatherVVOpc,
DL, M1VT, SubV1, SubIndex,
6901 DAG.
getUNDEF(M1VT), InnerTrueMask, InnerVL);
6918 DAG.
getUNDEF(M1VT), InnerTrueMask, InnerVL);
6920 for (
int i = 0; i <
N; i++)
6936 for (
int i = 0; i <
N; i++) {
6939 DAG.
getUNDEF(IndexContainerVT), LHSIndices,
6940 SlideAmt, TrueMask, VL);
6944 DAG.
getNode(GatherVVOpc,
DL, M1VT, SubV1, SubIndex,
6945 DAG.
getUNDEF(M1VT), InnerTrueMask, InnerVL);
6955 DAG.
getUNDEF(ContainerVT), TrueMask, VL);
6961 SmallVector<int> ShuffleMaskLHS, ShuffleMaskRHS;
6965 for (
int MaskIndex : Mask) {
6966 bool IsLHSOrUndefIndex = MaskIndex < (int)NumElts;
6967 ShuffleMaskLHS.
push_back(IsLHSOrUndefIndex && MaskIndex >= 0
6969 ShuffleMaskRHS.
push_back(IsLHSOrUndefIndex ? -1 : (MaskIndex - NumElts));
7000 for (
int MaskIndex : Mask) {
7001 bool SelectMaskVal = (MaskIndex < (int)NumElts) ^ !SwapOps;
7005 assert(MaskVals.
size() == NumElts &&
"Unexpected select-like shuffle");
7016 if (!
isTypeLegal(VT) || !Subtarget.hasVInstructions())
7023 const unsigned NumElts = M.size();
7030 std::array<std::pair<int, int>, 2> SrcInfo;
7041RISCVTargetLowering::lowerCTLZ_CTTZ_ZERO_POISON(
SDValue Op,
7043 MVT VT =
Op.getSimpleValueType();
7047 MVT ContainerVT = VT;
7052 MVT FloatEltVT = (EltSize >= 32) ? MVT::f64 :
MVT::f32;
7054 FloatEltVT = MVT::f32;
7061 "Expected legal float type!");
7072 if (FloatVT.
bitsGT(VT)) {
7083 MVT ContainerFloatVT =
7085 FloatVal = DAG.
getNode(RISCVISD::VFCVT_RM_F_XU_VL,
DL, ContainerFloatVT,
7086 Src, Mask, RTZRM, VL);
7093 unsigned ShiftAmt = FloatEltVT == MVT::f64 ? 52 : 23;
7100 else if (IntVT.
bitsGT(VT))
7104 unsigned ExponentBias = FloatEltVT == MVT::f64 ? 1023 : 127;
7112 unsigned Adjust = ExponentBias + (EltSize - 1);
7127 MVT XLenVT = Subtarget.getXLenVT();
7129 MVT SrcVT =
Source.getSimpleValueType();
7138 SrcVT = ContainerVT;
7150 SDValue Res = DAG.
getNode(RISCVISD::VFIRST_VL,
DL, XLenVT, Source, Mask, EVL);
7151 if (
Op->getOpcode() == ISD::VP_CTTZ_ELTS_ZERO_POISON)
7169 assert(Load &&
Load->getMemoryVT().isVector() &&
"Expected vector load");
7172 Load->getMemoryVT(),
7173 *
Load->getMemOperand()))
7177 MVT VT =
Op.getSimpleValueType();
7179 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
7180 "Unexpected unaligned RVV load type");
7184 "Expecting equally-sized RVV vector types to be legal");
7186 Load->getPointerInfo(),
Load->getBaseAlign(),
7187 Load->getMemOperand()->getFlags());
7198 assert(Store &&
Store->getValue().getValueType().isVector() &&
7199 "Expected vector store");
7202 Store->getMemoryVT(),
7203 *
Store->getMemOperand()))
7210 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
7211 "Unexpected unaligned RVV store type");
7215 "Expecting equally-sized RVV vector types to be legal");
7216 StoredVal = DAG.
getBitcast(NewVT, StoredVal);
7218 Store->getPointerInfo(),
Store->getBaseAlign(),
7219 Store->getMemOperand()->getFlags());
7229 assert(Load &&
Load->getMemoryVT().isVector() &&
"Expected vector load");
7232 Load->getMemoryVT(),
7233 *
Load->getMemOperand()))
7243 MVT VT =
Op.getSimpleValueType();
7245 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
7246 "Unexpected unaligned RVV load type");
7250 "Expecting equally-sized RVV vector types to be legal");
7259 Load->getPointerInfo(),
Load->getBaseAlign(),
7260 Load->getMemOperand()->getFlags(), AAMDNodes());
7271 assert(Store &&
Store->getValue().getValueType().isVector() &&
7272 "Expected vector store");
7275 Store->getMemoryVT(),
7276 *
Store->getMemOperand()))
7289 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
7290 "Unexpected unaligned RVV store type");
7294 "Expecting equally-sized RVV vector types to be legal");
7300 StoredVal = DAG.
getBitcast(NewVT, StoredVal);
7305 Store->getPointerInfo(),
Store->getMemOperand()->getFlags(),
Size,
7306 Store->getBaseAlign());
7317 assert(
Op.getValueType() == MVT::i64 &&
"Unexpected VT");
7346 unsigned ShiftAmt, AddOpc;
7357 MVT VT =
Op.getSimpleValueType();
7361 bool Negate =
false;
7365 if (Index < 0 &&
Imm.isNegative()) {
7388 unsigned IsData =
Op.getConstantOperandVal(4);
7391 if (Subtarget.hasVendorXMIPSCBOP() && !IsData)
7392 return Op.getOperand(0);
7404 if (Subtarget.hasStdExtZtso()) {
7428 MVT VT =
Op.getSimpleValueType();
7429 MVT XLenVT = Subtarget.getXLenVT();
7430 unsigned Check =
Op.getConstantOperandVal(1);
7431 unsigned TDCMask = 0;
7459 MVT VT0 =
Op.getOperand(0).getSimpleValueType();
7465 VL,
Op->getFlags());
7482 SDValue FPCLASS = DAG.
getNode(RISCVISD::FCLASS_VL,
DL, ContainerDstVT, Op0,
7483 Mask, VL,
Op->getFlags());
7485 TDCMaskV = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerDstVT,
7486 DAG.
getUNDEF(ContainerDstVT), TDCMaskV, VL);
7489 DAG.
getNode(RISCVISD::SETCC_VL,
DL, ContainerVT,
7495 TDCMaskV, DAG.
getUNDEF(ContainerDstVT), Mask, VL);
7498 SplatZero = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerDstVT,
7499 DAG.
getUNDEF(ContainerDstVT), SplatZero, VL);
7519 MVT VT =
Op.getSimpleValueType();
7553 MVT ContainerVT = VT;
7564 SDValue XIsNonNan = DAG.
getNode(RISCVISD::SETCC_VL,
DL, Mask.getValueType(),
7565 {X, X, DAG.getCondCode(ISD::SETOEQ),
7566 DAG.getUNDEF(ContainerVT), Mask, VL});
7567 NewY = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, ContainerVT, XIsNonNan,
Y,
X,
7573 SDValue YIsNonNan = DAG.
getNode(RISCVISD::SETCC_VL,
DL, Mask.getValueType(),
7574 {Y, Y, DAG.getCondCode(ISD::SETOEQ),
7575 DAG.getUNDEF(ContainerVT), Mask, VL});
7576 NewX = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, ContainerVT, YIsNonNan,
X,
Y,
7581 Op.getOpcode() ==
ISD::FMAXIMUM ? RISCVISD::VFMAX_VL : RISCVISD::VFMIN_VL;
7583 DAG.
getUNDEF(ContainerVT), Mask, VL);
7593 "Wrong opcode for lowering FABS or FNEG.");
7596 MVT VT =
Op.getSimpleValueType();
7597 assert((VT == MVT::f16 || VT == MVT::bf16) &&
"Unexpected type");
7601 DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT,
Op.getOperand(0));
7604 Mask = Mask.sext(Subtarget.
getXLen());
7609 return DAG.
getNode(RISCVISD::FMV_H_X,
DL, VT, Logic);
7617 MVT VT =
Op.getSimpleValueType();
7618 assert((VT == MVT::f16 || VT == MVT::bf16) &&
"Unexpected type");
7628 if (SignSize == Subtarget.
getXLen())
7632 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT, Sign);
7634 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTW_RV64,
DL, XLenVT, Sign);
7636 assert(XLenVT == MVT::i32 &&
"Unexpected type");
7639 return DAG.
getNode(RISCVISD::SplitF64,
DL, {MVT::i32, MVT::i32}, Sign)
7669 return DAG.
getNode(RISCVISD::FMV_H_X,
DL, VT, CopiedSign);
7674#define OP_CASE(NODE) \
7676 return RISCVISD::NODE##_VL;
7677#define VP_CASE(NODE) \
7678 case ISD::VP_##NODE: \
7679 return RISCVISD::NODE##_VL;
7681 switch (
Op.getOpcode()) {
7735 return RISCVISD::CTLZ_VL;
7737 return RISCVISD::CTTZ_VL;
7739 return RISCVISD::VFMADD_VL;
7741 return RISCVISD::STRICT_VFMADD_VL;
7743 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
7744 return RISCVISD::VMAND_VL;
7745 return RISCVISD::AND_VL;
7747 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
7748 return RISCVISD::VMOR_VL;
7749 return RISCVISD::OR_VL;
7751 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
7752 return RISCVISD::VMXOR_VL;
7753 return RISCVISD::XOR_VL;
7756 return RISCVISD::VZEXT_VL;
7758 return RISCVISD::VSEXT_VL;
7760 return RISCVISD::SETCC_VL;
7762 return RISCVISD::VMERGE_VL;
7764 return RISCVISD::VMERGE_VL;
7767 return RISCVISD::VFMIN_VL;
7770 return RISCVISD::VFMAX_VL;
7773 return RISCVISD::VFCVT_RM_X_F_VL;
7775 return RISCVISD::UDIV_VL;
7777 return RISCVISD::UREM_VL;
7779 return RISCVISD::SDIV_VL;
7781 return RISCVISD::SREM_VL;
7791 MVT OpVT =
Op.getSimpleValueType();
7813 for (
unsigned j = 0; j !=
Op.getNumOperands(); ++j) {
7814 if (!
Op.getOperand(j).getValueType().isVector()) {
7815 LoOperands[j] =
Op.getOperand(j);
7816 HiOperands[j] =
Op.getOperand(j);
7819 std::tie(LoOperands[j], HiOperands[j]) =
7824 DAG.
getNode(
Op.getOpcode(),
DL, LoVT, LoOperands,
Op->getFlags());
7826 DAG.
getNode(
Op.getOpcode(),
DL, HiVT, HiOperands,
Op->getFlags());
7838 auto [EVLLo, EVLHi] =
7839 DAG.
SplitEVL(
Op.getOperand(3),
Op.getOperand(1).getValueType(),
DL);
7843 {Op.getOperand(0), Lo, MaskLo, EVLLo},
Op->getFlags());
7845 {ResLo, Hi, MaskHi, EVLHi},
Op->getFlags());
7848 unsigned Opcode =
Op.getOpcode();
7854 Op.getOperand(0),
Lo,
Op->getFlags());
7864 return DAG.
getNode(BaseOpc,
DL,
Op.getValueType(), ResLo, ResHi,
7882 for (
unsigned j = 0; j !=
Op.getNumOperands(); ++j) {
7883 if (!
Op.getOperand(j).getValueType().isVector()) {
7884 LoOperands[j] =
Op.getOperand(j);
7885 HiOperands[j] =
Op.getOperand(j);
7888 std::tie(LoOperands[j], HiOperands[j]) =
7893 DAG.
getNode(
Op.getOpcode(),
DL, LoVTs, LoOperands,
Op->getFlags());
7896 DAG.
getNode(
Op.getOpcode(),
DL, HiVTs, HiOperands,
Op->getFlags());
7904RISCVTargetLowering::lowerXAndesBfHCvtBFloat16Load(
SDValue Op,
7906 assert(Subtarget.hasVendorXAndesBFHCvt() && !Subtarget.hasStdExtZfh() &&
7907 "Unexpected bfloat16 load lowering");
7911 EVT MemVT =
LD->getMemoryVT();
7916 LD->getMemOperand());
7924 DAG.
getNode(RISCVISD::NDS_FMV_BF16_X,
DL, MVT::bf16, OrSixteenOne);
7929RISCVTargetLowering::lowerXAndesBfHCvtBFloat16Store(
SDValue Op,
7931 assert(Subtarget.hasVendorXAndesBFHCvt() && !Subtarget.hasStdExtZfh() &&
7932 "Unexpected bfloat16 store lowering");
7937 Subtarget.getXLenVT(),
ST->getValue());
7939 ST->getChain(),
DL, FMV,
ST->getBasePtr(),
7941 ST->getMemOperand());
7949 switch (
Op.getOpcode()) {
7952 "Unimplemented RISCVTargetLowering::LowerOperation Case");
7958 return lowerGlobalAddress(
Op, DAG);
7960 return lowerBlockAddress(
Op, DAG);
7962 return lowerConstantPool(
Op, DAG);
7964 return lowerJumpTable(
Op, DAG);
7966 return lowerGlobalTLSAddress(
Op, DAG);
7970 return lowerConstantFP(
Op, DAG);
7972 return lowerSELECT(
Op, DAG);
7974 return lowerBRCOND(
Op, DAG);
7976 return lowerVASTART(
Op, DAG);
7978 return lowerFRAMEADDR(
Op, DAG);
7980 return lowerRETURNADDR(
Op, DAG);
7982 return lowerShiftLeftParts(
Op, DAG);
7984 return lowerShiftRightParts(
Op, DAG,
true);
7986 return lowerShiftRightParts(
Op, DAG,
false);
7989 if (
Op.getValueType().isFixedLengthVector()) {
7990 assert(Subtarget.hasStdExtZvkb());
7991 return lowerToScalableOp(
Op, DAG);
7993 assert(Subtarget.hasVendorXTHeadBb() &&
7994 !(Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) &&
7995 "Unexpected custom legalization");
8002 EVT VT =
Op.getValueType();
8005 MVT XLenVT = Subtarget.getXLenVT();
8006 if (Op0VT == MVT::i16 &&
8007 ((VT == MVT::f16 && Subtarget.hasStdExtZfhminOrZhinxmin()) ||
8008 (VT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()))) {
8010 return DAG.
getNode(RISCVISD::FMV_H_X,
DL, VT, NewOp0);
8012 if (VT == MVT::f32 && Op0VT == MVT::i32 && Subtarget.is64Bit() &&
8013 Subtarget.hasStdExtFOrZfinx()) {
8015 return DAG.
getNode(RISCVISD::FMV_W_X_RV64,
DL, MVT::f32, NewOp0);
8017 if (VT == MVT::f64 && Op0VT == MVT::i64 && !Subtarget.is64Bit() &&
8018 Subtarget.hasStdExtDOrZdinx()) {
8021 return DAG.
getNode(RISCVISD::BuildPairF64,
DL, MVT::f64,
Lo,
Hi);
8028 if (Op0VT.
getSimpleVT() == Subtarget.getXLenVT() &&
8042 "Unexpected types");
8074 return LowerINTRINSIC_WO_CHAIN(
Op, DAG);
8076 return LowerINTRINSIC_W_CHAIN(
Op, DAG);
8078 return LowerINTRINSIC_VOID(
Op, DAG);
8080 return LowerIS_FPCLASS(
Op, DAG);
8082 MVT VT =
Op.getSimpleValueType();
8084 assert(Subtarget.hasStdExtZvbb());
8085 return lowerToScalableOp(
Op, DAG);
8088 assert(Subtarget.hasStdExtZbkb() &&
"Unexpected custom legalization");
8092 return DAG.
getNode(RISCVISD::BREV8,
DL, VT, BSwap);
8098 if (!
Op.getSimpleValueType().isVector())
8100 return lowerVectorTrunc(
Op, DAG);
8103 if (
Op.getOperand(0).getValueType().isVector() &&
8104 Op.getOperand(0).getValueType().getVectorElementType() == MVT::i1)
8105 return lowerVectorMaskExt(
Op, DAG, 1);
8106 if (
Op.getValueType().isScalableVector())
8108 return lowerToScalableOp(
Op, DAG);
8110 if (
Op.getOperand(0).getValueType().isVector() &&
8111 Op.getOperand(0).getValueType().getVectorElementType() == MVT::i1)
8112 return lowerVectorMaskExt(
Op, DAG, -1);
8113 if (
Op.getValueType().isScalableVector())
8115 return lowerToScalableOp(
Op, DAG);
8117 return lowerSPLAT_VECTOR_PARTS(
Op, DAG);
8119 return lowerINSERT_VECTOR_ELT(
Op, DAG);
8121 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
8123 MVT VT =
Op.getSimpleValueType();
8131 MVT ContainerVT = VT;
8138 V = DAG.
getNode(RISCVISD::VFMV_S_F_VL,
DL, ContainerVT,
8139 DAG.
getUNDEF(ContainerVT), Scalar, VL);
8142 V = DAG.
getNode(RISCVISD::VMV_S_X_VL,
DL, ContainerVT,
8143 DAG.
getUNDEF(ContainerVT), Scalar, VL);
8150 MVT XLenVT = Subtarget.getXLenVT();
8151 MVT VT =
Op.getSimpleValueType();
8170 }
else if (
Log2 > 3) {
8174 }
else if ((Val % 8) == 0) {
8192 if (
Op.getValueType() == MVT::f16 && Subtarget.is64Bit() &&
8193 Op.getOperand(1).getValueType() == MVT::i32) {
8210 return lowerVectorFPExtendOrRound(
Op, DAG);
8213 return lowerStrictFPExtendOrRoundLike(
Op, DAG);
8218 Op.getValueType().isVector() &&
8219 ((
Op.getValueType().getScalarType() == MVT::f16 &&
8220 (Subtarget.hasVInstructionsF16Minimal() &&
8221 !Subtarget.hasVInstructionsF16())) ||
8222 (
Op.getValueType().getScalarType() == MVT::bf16 &&
8223 (Subtarget.hasVInstructionsBF16Minimal() &&
8224 (!Subtarget.hasVInstructionsBF16() ||
8225 Op1.getValueType().getScalarSizeInBits() > 8))))) {
8243 Op1.getValueType().isVector() &&
8244 ((Op1.getValueType().getScalarType() == MVT::f16 &&
8245 (Subtarget.hasVInstructionsF16Minimal() &&
8246 !Subtarget.hasVInstructionsF16())) ||
8247 (Op1.getValueType().getScalarType() == MVT::bf16 &&
8248 (Subtarget.hasVInstructionsBF16Minimal() &&
8249 (!Subtarget.hasVInstructionsBF16() ||
8250 Op.getValueType().getScalarSizeInBits() > 8))))) {
8252 Op1.getValueType().getVectorElementCount());
8259 return DAG.
getNode(
Op.getOpcode(),
DL,
Op.getValueType(), WidenVec);
8269 MVT VT =
Op.getSimpleValueType();
8272 bool IsStrict =
Op->isStrictFPOpcode();
8273 SDValue Src =
Op.getOperand(0 + IsStrict);
8274 MVT SrcVT = Src.getSimpleValueType();
8285 "Unexpected vector element types");
8289 if (EltSize > (2 * SrcEltSize)) {
8301 Op.getOperand(0), Ext);
8305 assert((SrcEltVT == MVT::f16 || SrcEltVT == MVT::bf16) &&
8306 "Unexpected FP_TO_[US]INT lowering");
8311 auto [FExt, Chain] =
8313 return DAG.
getNode(
Op.getOpcode(),
DL,
Op->getVTList(), Chain, FExt);
8320 if (SrcEltSize > (2 * EltSize)) {
8323 assert((EltVT == MVT::f16 || EltVT == MVT::bf16) &&
8324 "Unexpected [US]_TO_FP lowering");
8329 Op.getOperand(0), Src);
8344 Op.getOperand(0), Src);
8362 unsigned RVVOpc = 0;
8363 switch (
Op.getOpcode()) {
8367 RVVOpc = RISCVISD::VFCVT_RTZ_X_F_VL;
8370 RVVOpc = RISCVISD::VFCVT_RTZ_XU_F_VL;
8373 RVVOpc = RISCVISD::SINT_TO_FP_VL;
8376 RVVOpc = RISCVISD::UINT_TO_FP_VL;
8379 RVVOpc = RISCVISD::STRICT_VFCVT_RTZ_X_F_VL;
8382 RVVOpc = RISCVISD::STRICT_VFCVT_RTZ_XU_F_VL;
8385 RVVOpc = RISCVISD::STRICT_SINT_TO_FP_VL;
8388 RVVOpc = RISCVISD::STRICT_UINT_TO_FP_VL;
8395 "Expected same element count");
8402 Op.getOperand(0), Src, Mask, VL);
8406 Src = DAG.
getNode(RVVOpc,
DL, ContainerVT, Src, Mask, VL);
8415 assert(!Subtarget.isSoftFPABI() &&
"Unexpected custom legalization");
8421 makeLibCall(DAG, LC, MVT::f32,
Op.getOperand(0), CallOptions,
DL).first;
8422 if (Subtarget.is64Bit())
8423 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTW_RV64,
DL, MVT::i64, Res);
8427 assert(Subtarget.hasStdExtFOrZfinx() &&
"Unexpected custom legalization");
8428 MVT VT =
Op.getSimpleValueType();
8433 SDValue Res = Subtarget.is64Bit()
8434 ? DAG.
getNode(RISCVISD::FMV_W_X_RV64,
DL, MVT::f32,
Op)
8445 assert(Subtarget.hasStdExtFOrZfinx() &&
"Unexpected custom legalisation");
8448 bool IsStrict =
Op->isStrictFPOpcode();
8449 SDValue Op0 = IsStrict ?
Op.getOperand(1) :
Op.getOperand(0);
8453 std::tie(Res, Chain) =
8454 makeLibCall(DAG, LC, MVT::f32, Op0, CallOptions,
DL, Chain);
8455 if (Subtarget.is64Bit())
8456 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTW_RV64,
DL, MVT::i64, Res);
8466 assert(Subtarget.hasStdExtFOrZfinx() &&
"Unexpected custom legalisation");
8469 bool IsStrict =
Op->isStrictFPOpcode();
8470 SDValue Op0 = IsStrict ?
Op.getOperand(1) :
Op.getOperand(0);
8472 SDValue Arg = Subtarget.is64Bit()
8473 ? DAG.
getNode(RISCVISD::FMV_W_X_RV64,
DL, MVT::f32, Op0)
8476 std::tie(Res, Chain) =
makeLibCall(DAG, RTLIB::FPEXT_F16_F32, MVT::f32, Arg,
8477 CallOptions,
DL, Chain);
8493 MVT VT =
Op.getSimpleValueType();
8506 if (
Op.getValueType().isVector())
8508 assert(
Op.getOperand(0).getValueType() == MVT::f16 &&
8509 "Unexpected custom legalisation");
8512 return DAG.
getNode(
Op.getOpcode(),
DL,
Op.getValueType(), Ext);
8518 assert(
Op.getOperand(1).getValueType() == MVT::f16 &&
8519 "Unexpected custom legalisation");
8522 {
Op.getOperand(0),
Op.getOperand(1)});
8523 return DAG.
getNode(
Op.getOpcode(),
DL, {Op.getValueType(), MVT::Other},
8524 {Ext.getValue(1), Ext.getValue(0)});
8531 return lowerVECREDUCE(
Op, DAG);
8535 if (
Op.getOperand(0).getValueType().getVectorElementType() == MVT::i1)
8536 return lowerVectorMaskVecReduction(
Op, DAG,
false);
8537 return lowerVECREDUCE(
Op, DAG);
8541 return lowerFPVECREDUCE(
Op, DAG);
8549 return lowerFPVECREDUCE(
Op, DAG);
8550 case ISD::VP_REDUCE_ADD:
8551 case ISD::VP_REDUCE_UMAX:
8552 case ISD::VP_REDUCE_SMAX:
8553 case ISD::VP_REDUCE_UMIN:
8554 case ISD::VP_REDUCE_SMIN:
8555 case ISD::VP_REDUCE_FADD:
8556 case ISD::VP_REDUCE_SEQ_FADD:
8557 case ISD::VP_REDUCE_FMIN:
8558 case ISD::VP_REDUCE_FMAX:
8559 case ISD::VP_REDUCE_FMINIMUM:
8560 case ISD::VP_REDUCE_FMAXIMUM:
8563 return lowerVPREDUCE(
Op, DAG);
8564 case ISD::VP_REDUCE_AND:
8565 case ISD::VP_REDUCE_OR:
8566 case ISD::VP_REDUCE_XOR:
8567 if (
Op.getOperand(1).getValueType().getVectorElementType() == MVT::i1)
8568 return lowerVectorMaskVecReduction(
Op, DAG,
true);
8569 return lowerVPREDUCE(
Op, DAG);
8570 case ISD::VP_CTTZ_ELTS:
8571 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
8572 return lowerVPCttzElements(
Op, DAG);
8576 DAG.
getUNDEF(ContainerVT), DAG, Subtarget);
8579 return lowerINSERT_SUBVECTOR(
Op, DAG);
8581 return lowerEXTRACT_SUBVECTOR(
Op, DAG);
8583 return lowerVECTOR_DEINTERLEAVE(
Op, DAG);
8585 return lowerVECTOR_INTERLEAVE(
Op, DAG);
8587 return lowerSTEP_VECTOR(
Op, DAG);
8589 return lowerVECTOR_REVERSE(
Op, DAG);
8592 return lowerVECTOR_SPLICE(
Op, DAG);
8594 MVT VT =
Op.getSimpleValueType();
8596 if (!Subtarget.is64Bit() && EltVT == MVT::i64)
8601 MVT VT =
Op.getSimpleValueType();
8603 if ((EltVT == MVT::f16 && !Subtarget.hasVInstructionsF16()) ||
8604 EltVT == MVT::bf16) {
8607 if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
8608 (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin()))
8609 Elt = DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, Subtarget.getXLenVT(),
8618 if (EltVT == MVT::i1)
8619 return lowerVectorMaskSplat(
Op, DAG);
8623 return lowerVECTOR_SHUFFLE(
Op, DAG);
8628 MVT VT =
Op.getSimpleValueType();
8629 MVT ContainerVT = VT;
8641 if (
Op.getNumOperands() > 2 &&
8645 size_t HalfNumOps =
Op.getNumOperands() / 2;
8647 Op->ops().take_front(HalfNumOps));
8649 Op->ops().drop_front(HalfNumOps));
8653 unsigned NumOpElts =
8654 Op.getOperand(0).getSimpleValueType().getVectorMinNumElements();
8667 EVT VT = Load->getValueType(0);
8668 if (VT == MVT::f64) {
8669 assert(Subtarget.hasStdExtZdinx() && !Subtarget.hasStdExtZilsd() &&
8670 !Subtarget.is64Bit() &&
"Unexpected custom legalisation");
8674 SDValue BasePtr = Load->getBasePtr();
8675 SDValue Chain = Load->getChain();
8678 DAG.
getLoad(MVT::i32,
DL, Chain, BasePtr, Load->getPointerInfo(),
8679 Load->getBaseAlign(), Load->getMemOperand()->getFlags());
8682 MVT::i32,
DL, Chain, BasePtr, Load->getPointerInfo().getWithOffset(4),
8683 Load->getBaseAlign(), Load->getMemOperand()->getFlags());
8688 if (!Subtarget.isLittleEndian())
8695 if (Subtarget.hasStdExtP() && !Subtarget.is64Bit() &&
8696 (VT == MVT::v2i32 || VT == MVT::v4i16 || VT == MVT::v8i8)) {
8697 assert(!Subtarget.is64Bit() &&
"Unexpected custom legalisation");
8701 if (VT == MVT::v2i32)
8703 else if (VT == MVT::v4i16)
8704 HalfVT = MVT::v2i16;
8709 SDValue BasePtr = Load->getBasePtr();
8710 SDValue Chain = Load->getChain();
8714 DAG.
getLoad(HalfVT,
DL, Chain, BasePtr, Load->getPointerInfo(),
8715 Load->getBaseAlign(), Load->getMemOperand()->getFlags());
8721 Load->getPointerInfo().getWithOffset(HalfSize),
8722 Load->getBaseAlign(), Load->getMemOperand()->getFlags());
8728 if (VT == MVT::v2i32) {
8739 if (VT == MVT::bf16)
8740 return lowerXAndesBfHCvtBFloat16Load(
Op, DAG);
8745 MVT XLenVT = Subtarget.getXLenVT();
8748 unsigned NumElts = Sz / (NF * 8);
8749 int Log2LMUL =
Log2_64(NumElts) - 3;
8752 Flag.setNoUnsignedWrap(
true);
8754 SDValue BasePtr = Load->getBasePtr();
8762 for (
unsigned i = 0; i < NF; ++i) {
8767 Ret = DAG.
getNode(RISCVISD::TUPLE_INSERT,
DL, VT, Ret, LoadVal,
8775 if (
auto V = expandUnalignedRVVLoad(
Op, DAG))
8777 if (
Op.getValueType().isFixedLengthVector())
8778 return lowerFixedLengthVectorLoadToRVV(
Op, DAG);
8783 SDValue StoredVal = Store->getValue();
8786 if (VT == MVT::f64) {
8787 assert(Subtarget.hasStdExtZdinx() && !Subtarget.hasStdExtZilsd() &&
8788 !Subtarget.is64Bit() &&
"Unexpected custom legalisation");
8792 SDValue BasePtr = Store->getBasePtr();
8793 SDValue Chain = Store->getChain();
8795 DAG.
getVTList(MVT::i32, MVT::i32), StoredVal);
8801 if (!Subtarget.isLittleEndian())
8805 Chain,
DL,
Lo, BasePtr, Store->getPointerInfo(),
8806 Store->getBaseAlign(), Store->getMemOperand()->getFlags());
8809 Chain,
DL,
Hi, BasePtr, Store->getPointerInfo().getWithOffset(4),
8810 Store->getBaseAlign(), Store->getMemOperand()->getFlags());
8813 if (VT == MVT::i64) {
8814 assert(Subtarget.hasStdExtZilsd() && !Subtarget.is64Bit() &&
8815 "Unexpected custom legalisation");
8816 if (Store->isTruncatingStore())
8819 if (Store->getAlign() < Subtarget.getZilsdAlign())
8830 {Store->getChain(), Lo, Hi, Store->getBasePtr()}, MVT::i64,
8831 Store->getMemOperand());
8834 if (Subtarget.hasStdExtP() && !Subtarget.is64Bit() &&
8835 (VT == MVT::v2i32 || VT == MVT::v4i16 || VT == MVT::v8i8)) {
8836 assert(!Subtarget.is64Bit() &&
"Unexpected custom legalisation");
8839 SDValue Val = Store->getValue();
8843 if (VT == MVT::v2i32)
8845 else if (VT == MVT::v4i16)
8846 HalfVT = MVT::v2i16;
8851 SDValue BasePtr = Store->getBasePtr();
8852 SDValue Chain = Store->getChain();
8856 if (VT == MVT::v2i32) {
8873 Chain,
DL,
Lo, BasePtr, Store->getPointerInfo(),
8874 Store->getBaseAlign(), Store->getMemOperand()->getFlags());
8879 Chain,
DL,
Hi, BasePtr,
8880 Store->getPointerInfo().getWithOffset(HalfSize),
8881 Store->getBaseAlign(), Store->getMemOperand()->getFlags());
8886 if (VT == MVT::bf16)
8887 return lowerXAndesBfHCvtBFloat16Store(
Op, DAG);
8892 MVT XLenVT = Subtarget.getXLenVT();
8895 unsigned NumElts = Sz / (NF * 8);
8896 int Log2LMUL =
Log2_64(NumElts) - 3;
8899 Flag.setNoUnsignedWrap(
true);
8901 SDValue Chain = Store->getChain();
8902 SDValue BasePtr = Store->getBasePtr();
8909 for (
unsigned i = 0; i < NF; ++i) {
8911 DAG.
getNode(RISCVISD::TUPLE_EXTRACT,
DL,
8914 Ret = DAG.
getStore(Chain,
DL, Extract, BasePtr,
8916 Store->getBaseAlign(),
8917 Store->getMemOperand()->getFlags());
8924 if (
auto V = expandUnalignedRVVStore(
Op, DAG))
8926 if (
Op.getOperand(1).getValueType().isFixedLengthVector())
8927 return lowerFixedLengthVectorStoreToRVV(
Op, DAG);
8931 if (
SDValue V = expandUnalignedVPLoad(
Op, DAG))
8935 return lowerMaskedLoad(
Op, DAG);
8936 case ISD::VP_LOAD_FF:
8937 return lowerLoadFF(
Op, DAG);
8939 if (
SDValue V = expandUnalignedVPStore(
Op, DAG))
8943 return lowerMaskedStore(
Op, DAG);
8945 return lowerVectorCompress(
Op, DAG);
8954 EVT VT =
Op.getValueType();
8965 MVT OpVT =
Op.getOperand(0).getSimpleValueType();
8967 MVT VT =
Op.getSimpleValueType();
8972 "Unexpected CondCode");
9005 return DAG.
getSetCC(
DL, VT, RHS, LHS, CCVal);
9008 MVT VT =
Op.getSimpleValueType();
9035 return DAG.
getSetCC(
DL, VT, RHS, LHS, CCVal);
9044 return lowerToScalableOp(
Op, DAG);
9054 return lowerToScalableOp(
Op, DAG);
9056 EVT VT =
Op.getValueType();
9058 if (Subtarget.hasStdExtP() && !Subtarget.is64Bit() &&
9059 (VT == MVT::v4i16 || VT == MVT::v8i8)) {
9072 MaskLo, TrueLo, FalseLo);
9074 MaskHi, TrueHi, FalseHi);
9078 return lowerToScalableOp(
Op, DAG);
9086 EVT VT =
Op.getValueType();
9087 unsigned Opc =
Op.getOpcode();
9089 if (Subtarget.hasStdExtP() && !Subtarget.is64Bit() &&
9090 (VT == MVT::v4i16 || VT == MVT::v8i8)) {
9096 MVT HalfVT = (VT == MVT::v4i16) ? MVT::v2i16 : MVT::v4i8;
9099 auto [LHSLo, LHSHi] = DAG.
SplitVector(LHS,
DL, HalfVT, HalfVT);
9102 auto [RHSLo, RHSHi] = DAG.
SplitVector(RHS,
DL, HalfVT, HalfVT);
9111 if (Subtarget.hasStdExtP() && !Subtarget.is64Bit() &&
9113 (VT == MVT::v4i8 || VT == MVT::v2i16)) {
9115 "Unexpected custom legalisation");
9117 MVT WideVT = (VT == MVT::v4i8) ? MVT::v4i16 : MVT::v2i32;
9121 DAG.
getNode(WMulOpc,
DL, WideVT,
Op.getOperand(0),
Op.getOperand(1));
9129 return lowerToScalableOp(
Op, DAG);
9132 EVT VT =
Op.getValueType();
9133 assert(Subtarget.hasStdExtP() && Subtarget.is64Bit() &&
9134 (VT == MVT::v2i32 || VT == MVT::v4i16) &&
9135 "Unexpected custom legalisation");
9143 if (
Op.getSimpleValueType().isFixedLengthVector()) {
9144 if (Subtarget.hasStdExtP()) {
9156 switch (
Op.getOpcode()) {
9160 Opc = RISCVISD::PSHL;
9163 Opc = RISCVISD::PSRL;
9166 Opc = RISCVISD::PSRA;
9169 Opc = RISCVISD::PSSHA;
9175 return lowerToScalableOp(
Op, DAG);
9179 assert(
Op.getOperand(1).getValueType() == MVT::i32 && Subtarget.is64Bit() &&
9180 "Unexpected custom legalisation");
9187 MVT VT =
Op.getSimpleValueType();
9202 if (
Op.getValueType() == MVT::f16 ||
Op.getValueType() == MVT::bf16)
9230 return lowerToScalableOp(
Op, DAG);
9233 EVT VT =
Op->getValueType(0);
9235 if (Subtarget.hasStdExtZvabd() && VT.
isVector() &&
9238 return lowerToScalableOp(
Op, DAG);
9255 return lowerABS(
Op, DAG);
9260 if (Subtarget.hasStdExtZvbb())
9261 return lowerToScalableOp(
Op, DAG);
9263 return lowerCTLZ_CTTZ_ZERO_POISON(
Op, DAG);
9265 MVT VT =
Op.getSimpleValueType();
9267 "Unexpected custom legalisation");
9277 if (
Op.getValueType() == MVT::f16 ||
Op.getValueType() == MVT::bf16)
9281 return lowerToScalableOp(
Op, DAG);
9290 return lowerToScalableOp(
Op, DAG);
9293 return lowerVectorStrictFSetcc(
Op, DAG);
9303 case ISD::VP_GATHER:
9304 return lowerMaskedGather(
Op, DAG);
9306 case ISD::VP_SCATTER:
9307 return lowerMaskedScatter(
Op, DAG);
9309 return lowerGET_ROUNDING(
Op, DAG);
9311 return lowerSET_ROUNDING(
Op, DAG);
9313 return lowerGET_FPENV(
Op, DAG);
9315 return lowerSET_FPENV(
Op, DAG);
9317 return lowerRESET_FPENV(
Op, DAG);
9319 return lowerGET_FPMODE(
Op, DAG);
9321 return lowerSET_FPMODE(
Op, DAG);
9323 return lowerRESET_FPMODE(
Op, DAG);
9325 return lowerEH_DWARF_CFA(
Op, DAG);
9327 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
9328 return lowerVPMergeMask(
Op, DAG);
9334 return lowerVPOp(
Op, DAG);
9335 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
9336 return lowerVPStridedLoad(
Op, DAG);
9337 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
9338 return lowerVPStridedStore(
Op, DAG);
9339 case ISD::EXPERIMENTAL_VP_SPLICE:
9340 return lowerVPSpliceExperimental(
Op, DAG);
9341 case ISD::EXPERIMENTAL_VP_REVERSE:
9342 return lowerVPReverseExperimental(
Op, DAG);
9345 "llvm.clear_cache only needs custom lower on Linux targets");
9348 return emitFlushICache(DAG,
Op.getOperand(0),
Op.getOperand(1),
9349 Op.getOperand(2), Flags,
DL);
9352 return lowerDYNAMIC_STACKALLOC(
Op, DAG);
9354 return lowerINIT_TRAMPOLINE(
Op, DAG);
9356 return lowerADJUST_TRAMPOLINE(
Op, DAG);
9360 return lowerPARTIAL_REDUCE_MLA(
Op, DAG);
9370 MakeLibCallOptions CallOptions;
9371 std::pair<SDValue, SDValue> CallResult =
9372 makeLibCall(DAG, RTLIB::RISCV_FLUSH_ICACHE, MVT::isVoid,
9373 {Start, End, Flags}, CallOptions,
DL, InChain);
9376 return CallResult.second;
9381 if (!Subtarget.is64Bit())
9389 std::unique_ptr<MCCodeEmitter> CodeEmitter(
9418 const bool HasCFBranch =
9419 MF.
getInfo<RISCVMachineFunctionInfo>()->hasCFProtectionBranch();
9420 const unsigned StaticChainIdx = HasCFBranch ? 5 : 4;
9421 const unsigned StaticChainOffset = StaticChainIdx * 4;
9422 const unsigned FunctionAddressOffset = StaticChainOffset + 8;
9425 auto GetEncoding = [&](
const MCInst &MC) {
9428 CodeEmitter->encodeInstruction(MC, CB, Fixups, STI);
9435 SmallVector<uint32_t> Encodings;
9440 GetEncoding(MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X7).addImm(0)),
9444 GetEncoding(MCInstBuilder(RISCV::LD)
9447 .addImm(FunctionAddressOffset)),
9450 GetEncoding(MCInstBuilder(RISCV::LD)
9453 .addImm(StaticChainOffset)),
9456 GetEncoding(MCInstBuilder(RISCV::JALR)
9464 GetEncoding(MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X0).addImm(0)),
9467 GetEncoding(MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X28).addImm(0)),
9471 GetEncoding(MCInstBuilder(RISCV::LD)
9474 .addImm(FunctionAddressOffset - 4)),
9477 GetEncoding(MCInstBuilder(RISCV::LD)
9480 .addImm(StaticChainOffset - 4)),
9483 GetEncoding(MCInstBuilder(RISCV::JALR)
9495 Root, dl, DAG.
getConstant(Encoding, dl, MVT::i64), Addr,
9496 MachinePointerInfo(TrmpAddr, Idx * 4), MVT::i32));
9500 SDValue FunctionAddress =
Op.getOperand(2);
9504 struct OffsetValuePair {
9508 } OffsetValues[] = {
9509 {StaticChainOffset, StaticChain},
9510 {FunctionAddressOffset, FunctionAddress},
9512 for (
auto &OffsetValue : OffsetValues) {
9515 DAG.
getConstant(OffsetValue.Offset, dl, MVT::i64));
9516 OffsetValue.Addr = Addr;
9518 DAG.
getStore(Root, dl, OffsetValue.Value, Addr,
9519 MachinePointerInfo(TrmpAddr, OffsetValue.Offset)));
9522 assert(OutChains.
size() == StaticChainIdx + 2 &&
9523 "Size of OutChains mismatch");
9528 SDValue EndOfTrmp = OffsetValues[0].Addr;
9539 if (!Subtarget.is64Bit())
9542 return Op.getOperand(0);
9552 MVT VT =
Op.getSimpleValueType();
9558 MVT ArgVT =
A.getSimpleValueType();
9559 assert(ArgVT ==
B.getSimpleValueType() &&
9569 MVT ContainerVT = VT;
9578 switch (
Op.getOpcode()) {
9580 Opc = RISCVISD::VDOT4A_VL;
9583 Opc = RISCVISD::VDOT4AU_VL;
9586 Opc = RISCVISD::VDOT4ASU_VL;
9612 N->getOffset(), Flags);
9641template <
class NodeTy>
9643 bool IsLocal,
bool IsExternWeak)
const {
9653 if (IsLocal && !Subtarget.allowTaggedGlobals())
9657 return DAG.
getNode(RISCVISD::LLA,
DL, Ty, Addr);
9680 if (Subtarget.hasVendorXqcili()) {
9684 return DAG.
getNode(RISCVISD::QC_E_LI,
DL, Ty, Addr);
9691 return DAG.
getNode(RISCVISD::ADD_LO,
DL, Ty, MNHi, AddrLo);
9715 return DAG.
getNode(RISCVISD::LLA,
DL, Ty, Addr);
9723 return DAG.
getNode(RISCVISD::LLA,
DL, Ty, Addr);
9731 assert(
N->getOffset() == 0 &&
"unexpected offset in global node");
9732 const GlobalValue *GV =
N->getGlobal();
9741 return getAddr(
N, DAG);
9748 return getAddr(
N, DAG);
9755 return getAddr(
N, DAG);
9760 bool UseGOT)
const {
9763 const GlobalValue *GV =
N->getGlobal();
9764 MVT XLenVT = Subtarget.getXLenVT();
9801 DAG.
getNode(RISCVISD::ADD_TPREL,
DL, Ty, MNHi, TPReg, AddrAdd);
9802 return DAG.
getNode(RISCVISD::ADD_LO,
DL, Ty, MNAdd, AddrLo);
9810 const GlobalValue *GV =
N->getGlobal();
9821 Args.emplace_back(Load, CallTy);
9824 TargetLowering::CallLoweringInfo CLI(DAG);
9838 const GlobalValue *GV =
N->getGlobal();
9854 assert(
N->getOffset() == 0 &&
"unexpected offset in global node");
9868 Addr = getStaticTLSAddr(
N, DAG,
false);
9871 Addr = getStaticTLSAddr(
N, DAG,
true);
9876 : getDynamicTLSAddr(
N, DAG);
9893 if (
LHS == LHS2 &&
RHS == RHS2) {
9898 }
else if (
LHS == RHS2 &&
RHS == LHS2) {
9906 return std::nullopt;
9918 MVT VT =
N->getSimpleValueType(0);
9945 int64_t MulImm = TrueC->getSExtValue();
9947 Subtarget.hasVendorXqciac())
9948 return DAG.
getNode(RISCVISD::QC_MULIADD,
DL, VT, CondV, CondV,
9952 uint64_t TrueM1 = TrueC->getZExtValue() - 1;
9954 unsigned ShAmount =
Log2_64(TrueM1);
9956 return DAG.
getNode(RISCVISD::SHL_ADD,
DL, VT, CondV,
9972 if (~TrueVal == FalseVal) {
10012 if (Subtarget.hasShortForwardBranchIALU())
10015 unsigned SelOpNo = 0;
10025 unsigned ConstSelOpNo = 1;
10026 unsigned OtherSelOpNo = 2;
10033 if (!ConstSelOpNode || ConstSelOpNode->
isOpaque())
10038 if (!ConstBinOpNode || ConstBinOpNode->
isOpaque())
10044 SDValue NewConstOps[2] = {ConstSelOp, ConstBinOp};
10046 std::swap(NewConstOps[0], NewConstOps[1]);
10058 SDValue NewNonConstOps[2] = {OtherSelOp, ConstBinOp};
10060 std::swap(NewNonConstOps[0], NewNonConstOps[1]);
10063 SDValue NewT = (ConstSelOpNo == 1) ? NewConstOp : NewNonConstOp;
10064 SDValue NewF = (ConstSelOpNo == 1) ? NewNonConstOp : NewConstOp;
10073 MVT VT =
Op.getSimpleValueType();
10074 MVT XLenVT = Subtarget.getXLenVT();
10082 if (Subtarget.isPExtPackedType(VT)) {
10104 bool FPinGPR = Subtarget.hasStdExtZfinx();
10108 Subtarget.getXLenVT().getSizeInBits());
10110 bool UseZicondForFPSel = Subtarget.hasStdExtZicond() && FPinGPR &&
10113 if (UseZicondForFPSel) {
10120 if (VT == MVT::f16)
10121 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT, V);
10123 if (VT == MVT::f32 && Subtarget.is64Bit())
10124 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTW_RV64,
DL, XLenVT, V);
10129 SDValue TrueVInt = CastToInt(TrueV);
10130 SDValue FalseVInt = CastToInt(FalseV);
10137 if (VT == MVT::f32 && Subtarget.is64Bit())
10138 return DAG.
getNode(RISCVISD::FMV_W_X_RV64,
DL, VT, ResultInt);
10140 if (VT == MVT::f16)
10141 return DAG.
getNode(RISCVISD::FMV_H_X,
DL, VT, ResultInt);
10154 return DAG.
getNode(RISCVISD::CZERO_EQZ,
DL, VT, TrueV, CondV);
10157 return DAG.
getNode(RISCVISD::CZERO_NEZ,
DL, VT, FalseV, CondV);
10161 auto getNotOperand = [](
const SDValue &
Op) -> std::optional<const SDValue> {
10162 using namespace llvm::SDPatternMatch;
10167 return std::nullopt;
10173 auto NotOperand = (TrueV.
getOperand(0) == FalseV)
10175 : getNotOperand(TrueV.getOperand(0));
10178 DAG.
getNode(RISCVISD::CZERO_EQZ,
DL, VT, *NotOperand, CondV);
10184 DAG.
getNode(RISCVISD::CZERO_NEZ,
DL, VT, FalseV, CondV));
10191 auto NotOperand = (FalseV.
getOperand(0) == TrueV)
10193 : getNotOperand(FalseV.getOperand(0));
10196 DAG.
getNode(RISCVISD::CZERO_NEZ,
DL, VT, *NotOperand, CondV);
10202 DAG.
getNode(RISCVISD::CZERO_EQZ,
DL, VT, TrueV, CondV));
10219 int64_t TrueImm =
TrueVal.getSExtValue();
10220 int64_t FalseImm =
FalseVal.getSExtValue();
10239 if ((TrueVal - FalseVal).isPowerOf2() &&
FalseVal.isSignedIntN(12)) {
10244 if ((FalseVal - TrueVal).isPowerOf2() &&
TrueVal.isSignedIntN(12)) {
10251 auto getCost = [&](
const APInt &Delta,
const APInt &Addend) {
10253 Delta, Subtarget.getXLen(), Subtarget,
true);
10255 if (Addend.isSignedIntN(12))
10258 Addend, Subtarget.getXLen(), Subtarget,
true);
10259 return AddendCost + DeltaCost;
10261 bool IsCZERO_NEZ =
getCost(FalseVal - TrueVal, TrueVal) <=
10262 getCost(TrueVal - FalseVal, FalseVal);
10264 IsCZERO_NEZ ? FalseVal - TrueVal : TrueVal - FalseVal,
DL, VT);
10266 DAG.
getNode(IsCZERO_NEZ ? RISCVISD::CZERO_NEZ : RISCVISD::CZERO_EQZ,
10267 DL, VT, LHSVal, CondV);
10275 SDValue ConstVal = IsCZERO_NEZ ? TrueV : FalseV;
10276 SDValue RegV = IsCZERO_NEZ ? FalseV : TrueV;
10282 unsigned SubOpc = (RawConstVal == -0x800) ?
ISD::XOR : ISD::
SUB;
10283 unsigned AddOpc = (RawConstVal == -0x800) ?
ISD::XOR : ISD::
ADD;
10286 DAG.
getNode(IsCZERO_NEZ ? RISCVISD::CZERO_NEZ : RISCVISD::CZERO_EQZ,
10287 DL, VT, SubOp, CondV);
10288 return DAG.
getNode(AddOpc,
DL, VT, CZERO, ConstVal);
10294 if (!Subtarget.hasConditionalMoveFusion())
10297 DAG.
getNode(RISCVISD::CZERO_EQZ,
DL, VT, TrueV, CondV),
10298 DAG.
getNode(RISCVISD::CZERO_NEZ,
DL, VT, FalseV, CondV),
10302 if (
Op.hasOneUse()) {
10303 unsigned UseOpc =
Op->user_begin()->getOpcode();
10305 SDNode *BinOp = *
Op->user_begin();
10312 return lowerSELECT(NewSel, DAG);
10322 if (FPTV && FPFV) {
10366 if (TrueVal - 1 == FalseVal)
10368 if (TrueVal + 1 == FalseVal)
10375 RHS == TrueV &&
LHS == FalseV) {
10406 MVT XLenVT = Subtarget.getXLenVT();
10417 return DAG.
getNode(RISCVISD::BR_CC,
DL,
Op.getValueType(),
Op.getOperand(0),
10418 LHS,
RHS, TargetCC,
Op.getOperand(2));
10421 return DAG.
getNode(RISCVISD::BR_CC,
DL,
Op.getValueType(),
Op.getOperand(0),
10428 RISCVMachineFunctionInfo *FuncInfo = MF.
getInfo<RISCVMachineFunctionInfo>();
10438 MachinePointerInfo(SV));
10443 const RISCVRegisterInfo &RI = *Subtarget.getRegisterInfo();
10448 int XLenInBytes = Subtarget.getXLen() / 8;
10450 EVT VT =
Op.getValueType();
10453 unsigned Depth =
Op.getConstantOperandVal(0);
10455 int Offset = -(XLenInBytes * 2);
10467 const RISCVRegisterInfo &RI = *Subtarget.getRegisterInfo();
10471 MVT XLenVT = Subtarget.getXLenVT();
10472 int XLenInBytes = Subtarget.getXLen() / 8;
10474 EVT VT =
Op.getValueType();
10476 unsigned Depth =
Op.getConstantOperandVal(0);
10478 int Off = -XLenInBytes;
10479 SDValue FrameAddr = lowerFRAMEADDR(
Op, DAG);
10483 MachinePointerInfo());
10498 EVT VT =
Lo.getValueType();
10499 unsigned XLen = Subtarget.getXLen();
10502 if (Subtarget.hasStdExtP()) {
10566 bool IsSRA)
const {
10571 EVT VT =
Lo.getValueType();
10574 if (Subtarget.hasStdExtP()) {
10575 unsigned XLen = Subtarget.getXLen();
10578 if (Subtarget.is64Bit()) {
10586 LoRes = DAG.
getNode(IsSRA ? RISCVISD::NSRA : RISCVISD::NSRL,
DL, VT,
Lo,
10605 if (Subtarget.is64Bit()) {
10679 MVT VT =
Op.getSimpleValueType();
10684 return DAG.
getNode(RISCVISD::VMSET_VL,
DL, VT, VL);
10688 return DAG.
getNode(RISCVISD::VMCLR_VL,
DL, VT, VL);
10705 MVT VecVT =
Op.getSimpleValueType();
10707 "Unexpected SPLAT_VECTOR_PARTS lowering");
10713 MVT ContainerVT = VecVT;
10733 int64_t ExtTrueVal)
const {
10735 MVT VecVT =
Op.getSimpleValueType();
10738 assert(Src.getValueType().isVector() &&
10739 Src.getValueType().getVectorElementType() == MVT::i1);
10744 if (Src.getOpcode() ==
ISD::XOR &&
10752 MVT I1ContainerVT =
10759 MVT XLenVT = Subtarget.getXLenVT();
10765 if (
Xor.getOpcode() == RISCVISD::VMXOR_VL) {
10777 SplatZero = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerVT,
10778 DAG.
getUNDEF(ContainerVT), SplatZero, VL);
10779 SplatTrueVal = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerVT,
10780 DAG.
getUNDEF(ContainerVT), SplatTrueVal, VL);
10782 DAG.
getNode(RISCVISD::VMERGE_VL,
DL, ContainerVT, CC, SplatTrueVal,
10783 SplatZero, DAG.
getUNDEF(ContainerVT), VL);
10794 EVT MaskVT =
Op.getValueType();
10797 "Unexpected type for vector mask lowering");
10799 MVT VecVT = Src.getSimpleValueType();
10801 MVT ContainerVT = VecVT;
10813 SplatOne = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerVT,
10814 DAG.
getUNDEF(ContainerVT), SplatOne, VL);
10815 SplatZero = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerVT,
10816 DAG.
getUNDEF(ContainerVT), SplatZero, VL);
10819 SDValue Trunc = DAG.
getNode(RISCVISD::AND_VL,
DL, ContainerVT, Src, SplatOne,
10820 DAG.
getUNDEF(ContainerVT), Mask, VL);
10821 Trunc = DAG.
getNode(RISCVISD::SETCC_VL,
DL, MaskContainerVT,
10831 unsigned Opc =
Op.getOpcode();
10834 MVT VT =
Op.getSimpleValueType();
10836 assert(VT.
isVector() &&
"Unexpected type for vector truncate lowering");
10840 return lowerVectorMaskTrunc(
Op, DAG);
10848 MVT SrcVT = Src.getSimpleValueType();
10853 "Unexpected vector truncate lowering");
10855 MVT ContainerVT = SrcVT;
10866 NewOpc = RISCVISD::TRUNCATE_VECTOR_VL_SSAT;
10868 NewOpc = RISCVISD::TRUNCATE_VECTOR_VL_USAT;
10870 NewOpc = RISCVISD::TRUNCATE_VECTOR_VL;
10876 }
while (SrcEltVT != DstEltVT);
10885RISCVTargetLowering::lowerStrictFPExtendOrRoundLike(
SDValue Op,
10890 MVT VT =
Op.getSimpleValueType();
10891 MVT SrcVT = Src.getSimpleValueType();
10892 MVT ContainerVT = VT;
10911 ? RISCVISD::STRICT_FP_EXTEND_VL
10912 : RISCVISD::STRICT_VFNCVT_ROD_VL;
10915 Chain, Src, Mask, VL);
10916 Chain = Src.getValue(1);
10920 ? RISCVISD::STRICT_FP_EXTEND_VL
10921 : RISCVISD::STRICT_FP_ROUND_VL;
10923 Chain, Src, Mask, VL);
10934RISCVTargetLowering::lowerVectorFPExtendOrRound(
SDValue Op,
10941 MVT VT =
Op.getSimpleValueType();
10943 assert(VT.
isVector() &&
"Unexpected type for vector truncate lowering");
10946 MVT SrcVT = Src.getSimpleValueType();
10948 bool IsDirectExtend =
10956 bool IsDirectConv = IsDirectExtend || IsDirectTrunc;
10963 MVT ContainerVT = VT;
10973 unsigned ConvOpc = IsExtend ? RISCVISD::FP_EXTEND_VL : RISCVISD::FP_ROUND_VL;
10975 if (IsDirectConv) {
10976 Src = DAG.
getNode(ConvOpc,
DL, ContainerVT, Src, Mask, VL);
10982 unsigned InterConvOpc =
10983 IsExtend ? RISCVISD::FP_EXTEND_VL : RISCVISD::VFNCVT_ROD_VL;
10987 DAG.
getNode(InterConvOpc,
DL, InterVT, Src, Mask, VL);
10989 DAG.
getNode(ConvOpc,
DL, ContainerVT, IntermediateConv, Mask, VL);
11000static std::optional<MVT>
11006 const unsigned MinVLMAX = VectorBitsMin / EltSize;
11008 if (MaxIdx < MinVLMAX)
11010 else if (MaxIdx < MinVLMAX * 2)
11013 else if (MaxIdx < MinVLMAX * 4)
11018 return std::nullopt;
11031 MVT VecVT =
Op.getSimpleValueType();
11032 MVT XLenVT = Subtarget.getXLenVT();
11047 if ((ValVT == MVT::f16 && !Subtarget.hasVInstructionsF16()) ||
11048 (ValVT == MVT::bf16 && !Subtarget.hasVInstructionsBF16())) {
11053 DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT, Val), Idx);
11062 unsigned IdxVal = IdxC->getZExtValue();
11066 if (!Subtarget.is64Bit() && (VecVT == MVT::v4i16 || VecVT == MVT::v8i8)) {
11067 unsigned HalfNumElts = NumElts / 2;
11069 MVT HalfVT =
Lo.getSimpleValueType();
11070 if (IdxVal < HalfNumElts) {
11086 if (NumElts == 2) {
11103 if (NumElts == 4 || NumElts == 8) {
11105 unsigned ShiftAmt = IdxVal * EltBits;
11106 uint64_t PosMask = ((1ULL << EltBits) - 1) << ShiftAmt;
11112 DAG.
getNode(RISCVISD::MERGE,
DL, XLenVT, Mask, Vec, ShiftedVal);
11119 MVT ContainerVT = VecVT;
11129 std::optional<unsigned> AlignedIdx;
11131 const unsigned OrigIdx = IdxC->getZExtValue();
11134 DL, DAG, Subtarget)) {
11135 ContainerVT = *ShrunkVT;
11143 if (
auto VLEN = Subtarget.getRealVLen(); VLEN && ContainerVT.
bitsGT(M1VT)) {
11146 unsigned RemIdx = OrigIdx % ElemsPerVReg;
11147 unsigned SubRegIdx = OrigIdx / ElemsPerVReg;
11150 ContainerVT = M1VT;
11157 bool IsLegalInsert = Subtarget.is64Bit() || Val.
getValueType() != MVT::i64;
11162 if (!IsLegalInsert) {
11166 IsLegalInsert =
true;
11171 IsLegalInsert =
true;
11180 if (IsLegalInsert) {
11182 VecVT.
isFloatingPoint() ? RISCVISD::VFMV_S_F_VL : RISCVISD::VMV_S_X_VL;
11186 Vec = DAG.
getNode(
Opc,
DL, ContainerVT, Vec, Val, VL);
11202 std::tie(ValLo, ValHi) = DAG.
SplitScalar(Val,
DL, MVT::i32, MVT::i32);
11203 MVT I32ContainerVT =
11213 ValInVec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32ContainerVT,
11214 Vec, Vec, ValLo, I32Mask, InsertI64VL);
11218 ValInVec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32ContainerVT,
11219 Tail, ValInVec, ValHi, I32Mask, InsertI64VL);
11221 ValInVec = DAG.
getBitcast(ContainerVT, ValInVec);
11232 ValInVec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32ContainerVT,
11234 DAG.
getUNDEF(I32ContainerVT), ValLo,
11235 I32Mask, InsertI64VL);
11236 ValInVec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32ContainerVT,
11237 DAG.
getUNDEF(I32ContainerVT), ValInVec, ValHi,
11238 I32Mask, InsertI64VL);
11240 ValInVec = DAG.
getBitcast(ContainerVT, ValInVec);
11253 Idx, Mask, InsertVL, Policy);
11271 EVT EltVT =
Op.getValueType();
11273 MVT XLenVT = Subtarget.getXLenVT();
11278 MVT ContainerVT = VecVT;
11285 DAG.
getNode(RISCVISD::VFIRST_VL,
DL, XLenVT, Vec, Mask, VL);
11292 if (NumElts >= 8) {
11294 unsigned WidenVecLen;
11297 unsigned MaxEEW = Subtarget.getELen();
11302 "the number of elements should be power of 2");
11306 ExtractBitIdx = Idx;
11308 WideEltVT = LargestEltVT;
11311 ExtractElementIdx = DAG.
getNode(
11322 Vec, ExtractElementIdx);
11337 if ((EltVT == MVT::f16 && !Subtarget.hasVInstructionsF16()) ||
11338 (EltVT == MVT::bf16 && !Subtarget.hasVInstructionsBF16())) {
11344 return DAG.
getNode(RISCVISD::FMV_H_X,
DL, EltVT, IntExtract);
11348 if (VecVT != MVT::v4i16 && VecVT != MVT::v2i16 && VecVT != MVT::v8i8 &&
11349 VecVT != MVT::v4i8 && VecVT != MVT::v2i32)
11352 if (!Subtarget.is64Bit() && (VecVT == MVT::v4i16 || VecVT == MVT::v8i8)) {
11356 unsigned IdxVal = IdxC->getZExtValue();
11359 if (IdxVal < HalfNumElts)
11373 MVT ContainerVT = VecVT;
11383 const auto VLen = Subtarget.getRealVLen();
11385 IdxC && VLen && VecVT.
getSizeInBits().getKnownMinValue() > *VLen) {
11387 unsigned OrigIdx = IdxC->getZExtValue();
11390 unsigned RemIdx = OrigIdx % ElemsPerVReg;
11391 unsigned SubRegIdx = OrigIdx / ElemsPerVReg;
11392 unsigned ExtractIdx =
11396 ContainerVT = M1VT;
11401 std::optional<uint64_t> MaxIdx;
11405 MaxIdx = IdxC->getZExtValue();
11407 if (
auto SmallerVT =
11409 ContainerVT = *SmallerVT;
11436 DAG.
getUNDEF(ContainerVT), Vec, Idx, Mask, VL);
11455 "Unexpected opcode");
11462 unsigned IntNo =
Op.getConstantOperandVal(HasChain ? 1 : 0);
11467 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo);
11468 if (!
II || !
II->hasScalarOperand())
11471 unsigned SplatOp =
II->ScalarOperand + 1 + HasChain;
11472 assert(SplatOp <
Op.getNumOperands());
11475 SDValue &ScalarOp = Operands[SplatOp];
11484 if (OpVT.
bitsLT(XLenVT)) {
11491 ScalarOp = DAG.
getNode(ExtOpc,
DL, XLenVT, ScalarOp);
11492 return DAG.
getNode(
Op->getOpcode(),
DL,
Op->getVTList(), Operands);
11501 assert(
II->ScalarOperand > 0 &&
"Unexpected splat operand!");
11502 MVT VT =
Op.getOperand(SplatOp - 1).getSimpleValueType();
11505 assert(XLenVT == MVT::i32 && OpVT == MVT::i64 &&
11512 return DAG.
getNode(
Op->getOpcode(),
DL,
Op->getVTList(), Operands);
11516 case Intrinsic::riscv_vslide1up:
11517 case Intrinsic::riscv_vslide1down:
11518 case Intrinsic::riscv_vslide1up_mask:
11519 case Intrinsic::riscv_vslide1down_mask: {
11521 unsigned NumOps =
Op.getNumOperands();
11522 bool IsMasked =
NumOps == 7;
11528 std::tie(ScalarLo, ScalarHi) =
11537 const auto [MinVLMAX, MaxVLMAX] =
11541 if (AVLInt <= MinVLMAX) {
11543 }
else if (AVLInt >= 2 * MaxVLMAX) {
11575 Passthru = DAG.
getBitcast(I32VT, Operands[1]);
11577 if (IntNo == Intrinsic::riscv_vslide1up ||
11578 IntNo == Intrinsic::riscv_vslide1up_mask) {
11579 Vec = DAG.
getNode(RISCVISD::VSLIDE1UP_VL,
DL, I32VT, Passthru, Vec,
11580 ScalarHi, I32Mask, I32VL);
11581 Vec = DAG.
getNode(RISCVISD::VSLIDE1UP_VL,
DL, I32VT, Passthru, Vec,
11582 ScalarLo, I32Mask, I32VL);
11584 Vec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32VT, Passthru, Vec,
11585 ScalarLo, I32Mask, I32VL);
11586 Vec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32VT, Passthru, Vec,
11587 ScalarHi, I32Mask, I32VL);
11597 SDValue MaskedOff = Operands[1];
11605 return DAG.
getNode(RISCVISD::VMERGE_VL,
DL, VT, Mask, Vec, MaskedOff,
11609 return DAG.
getNode(RISCVISD::VMERGE_VL,
DL, VT, Mask, Vec, MaskedOff,
11618 return DAG.
getNode(
Op->getOpcode(),
DL,
Op->getVTList(), Operands);
11636 const unsigned ElementWidth = 8;
11641 [[maybe_unused]]
unsigned MinVF =
11644 [[maybe_unused]]
unsigned VF =
N->getConstantOperandVal(2);
11648 bool Fractional = VF < LMul1VF;
11649 unsigned LMulVal = Fractional ? LMul1VF / VF : VF / LMul1VF;
11670 MVT ContainerVT = OpVT;
11678 SDValue Res = DAG.
getNode(RISCVISD::VFIRST_VL,
DL, XLenVT, Op0, Mask, VL);
11686 return DAG.
getSelect(
DL, XLenVT, Setcc, VL, Res);
11697 unsigned IntNo =
Op.getConstantOperandVal(HasChain ? 1 : 0);
11701 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo);
11702 if (!
II || !
II->hasScalarOperand())
11705 unsigned SplatOp =
II->ScalarOperand + 1;
11706 assert(SplatOp <
Op.getNumOperands());
11708 SDValue &ScalarOp = Operands[SplatOp];
11718 if (OpVT.
bitsLT(XLenVT)) {
11721 ScalarOp = DAG.
getNode(ExtOpc,
DL, XLenVT, ScalarOp);
11731 for (
SDValue &V : Operands) {
11732 EVT ValType = V.getValueType();
11733 if (ValType.isVector() && ValType.isFloatingPoint()) {
11736 ValType.getVectorElementCount());
11739 if (ValType.isFixedLengthVector()) {
11740 MVT OpContainerVT =
11757 unsigned IntNo =
Op.getConstantOperandVal(0);
11759 MVT XLenVT = Subtarget.getXLenVT();
11764 case Intrinsic::riscv_tuple_insert: {
11769 return DAG.
getNode(RISCVISD::TUPLE_INSERT,
DL,
Op.getValueType(), Vec,
11772 case Intrinsic::riscv_tuple_extract: {
11776 return DAG.
getNode(RISCVISD::TUPLE_EXTRACT,
DL,
Op.getValueType(), Vec,
11779 case Intrinsic::thread_pointer: {
11783 case Intrinsic::riscv_pas:
11784 case Intrinsic::riscv_psa:
11785 case Intrinsic::riscv_psas:
11786 case Intrinsic::riscv_pssa:
11787 case Intrinsic::riscv_paas:
11788 case Intrinsic::riscv_pasa: {
11792 if (Subtarget.is64Bit() ||
Op.getSimpleValueType() != MVT::v2i32)
11795 unsigned EvenOpc, OddOpc;
11797 case Intrinsic::riscv_pas:
11801 case Intrinsic::riscv_psa:
11805 case Intrinsic::riscv_psas:
11809 case Intrinsic::riscv_pssa:
11813 case Intrinsic::riscv_paas:
11814 EvenOpc = RISCVISD::ASUB;
11817 case Intrinsic::riscv_pasa:
11819 OddOpc = RISCVISD::ASUB;
11836 case Intrinsic::riscv_orc_b:
11837 case Intrinsic::riscv_brev8:
11838 case Intrinsic::riscv_sha256sig0:
11839 case Intrinsic::riscv_sha256sig1:
11840 case Intrinsic::riscv_sha256sum0:
11841 case Intrinsic::riscv_sha256sum1:
11842 case Intrinsic::riscv_sm3p0:
11843 case Intrinsic::riscv_sm3p1: {
11846 case Intrinsic::riscv_orc_b:
Opc = RISCVISD::ORC_B;
break;
11847 case Intrinsic::riscv_brev8:
Opc = RISCVISD::BREV8;
break;
11848 case Intrinsic::riscv_sha256sig0:
Opc = RISCVISD::SHA256SIG0;
break;
11849 case Intrinsic::riscv_sha256sig1:
Opc = RISCVISD::SHA256SIG1;
break;
11850 case Intrinsic::riscv_sha256sum0:
Opc = RISCVISD::SHA256SUM0;
break;
11851 case Intrinsic::riscv_sha256sum1:
Opc = RISCVISD::SHA256SUM1;
break;
11852 case Intrinsic::riscv_sm3p0:
Opc = RISCVISD::SM3P0;
break;
11853 case Intrinsic::riscv_sm3p1:
Opc = RISCVISD::SM3P1;
break;
11858 case Intrinsic::riscv_sm4ks:
11859 case Intrinsic::riscv_sm4ed: {
11861 IntNo == Intrinsic::riscv_sm4ks ? RISCVISD::SM4KS : RISCVISD::SM4ED;
11866 case Intrinsic::riscv_zip:
11867 case Intrinsic::riscv_unzip: {
11869 IntNo == Intrinsic::riscv_zip ? RISCVISD::ZIP : RISCVISD::UNZIP;
11872 case Intrinsic::riscv_mopr:
11873 return DAG.
getNode(RISCVISD::MOP_R,
DL, XLenVT,
Op.getOperand(1),
11876 case Intrinsic::riscv_moprr: {
11877 return DAG.
getNode(RISCVISD::MOP_RR,
DL, XLenVT,
Op.getOperand(1),
11878 Op.getOperand(2),
Op.getOperand(3));
11880 case Intrinsic::riscv_clmulh:
11881 case Intrinsic::riscv_clmulr: {
11885 case Intrinsic::riscv_paadd:
11886 case Intrinsic::riscv_paaddu:
11887 case Intrinsic::riscv_pasub:
11888 case Intrinsic::riscv_pasubu:
11889 case Intrinsic::riscv_pabd:
11890 case Intrinsic::riscv_pabdu:
11891 case Intrinsic::riscv_psabs: {
11894 case Intrinsic::riscv_paadd:
11897 case Intrinsic::riscv_paaddu:
11900 case Intrinsic::riscv_pasub:
11901 Opc = RISCVISD::ASUB;
11903 case Intrinsic::riscv_pasubu:
11904 Opc = RISCVISD::ASUBU;
11906 case Intrinsic::riscv_pabd:
11909 case Intrinsic::riscv_pabdu:
11912 case Intrinsic::riscv_psabs:
11913 Opc = RISCVISD::PSABS;
11917 if (IntNo == Intrinsic::riscv_psabs)
11923 case Intrinsic::riscv_pabdsumu:
11924 case Intrinsic::riscv_pabdsumau: {
11933 bool IsAcc = IntNo == Intrinsic::riscv_pabdsumau;
11941 AbdsumauId,
Op.getOperand(1), Rs1Lo, Rs2Lo)
11943 AbdsumuId, Rs1Lo, Rs2Lo);
11947 case Intrinsic::riscv_pmerge: {
11948 EVT VT =
Op.getValueType();
11961 if (!Subtarget.is64Bit() &&
11962 (VT == MVT::v8i8 || VT == MVT::v4i16 || VT == MVT::v2i32)) {
11963 EVT WorkVT = VT == MVT::v2i32 ? EVT(MVT::v4i16) : VT;
11967 MVT HalfVT = WorkVT == MVT::v8i8 ? MVT::v4i8 : MVT::v2i16;
11968 auto [Rs1Lo, Rs1Hi] = DAG.
SplitVector(Rs1,
DL, HalfVT, HalfVT);
11969 auto [Rs2Lo, Rs2Hi] = DAG.
SplitVector(Rs2,
DL, HalfVT, HalfVT);
11970 auto [MaskLo, MaskHi] = DAG.
SplitVector(Mask,
DL, HalfVT, HalfVT);
11971 SDValue ResLo = buildMerge(Rs1Lo, Rs2Lo, MaskLo, HalfVT);
11972 SDValue ResHi = buildMerge(Rs1Hi, Rs2Hi, MaskHi, HalfVT);
11977 return buildMerge(
Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3), VT);
11979 case Intrinsic::experimental_get_vector_length:
11981 case Intrinsic::riscv_vmv_x_s: {
11985 case Intrinsic::riscv_vfmv_f_s:
11987 case Intrinsic::riscv_vmv_v_x:
11989 Op.getOperand(3),
Op.getSimpleValueType(),
DL, DAG,
11991 case Intrinsic::riscv_vfmv_v_f:
11992 return DAG.
getNode(RISCVISD::VFMV_V_F_VL,
DL,
Op.getValueType(),
11993 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
11994 case Intrinsic::riscv_vmv_s_x: {
11997 if (
Scalar.getValueType().bitsLE(XLenVT)) {
11999 return DAG.
getNode(RISCVISD::VMV_S_X_VL,
DL,
Op.getValueType(),
12000 Op.getOperand(1), Scalar,
Op.getOperand(3));
12003 assert(
Scalar.getValueType() == MVT::i64 &&
"Unexpected scalar VT!");
12020 MVT VT =
Op.getSimpleValueType();
12025 if (
Op.getOperand(1).isUndef())
12026 return SplattedVal;
12035 DAG.
getNode(RISCVISD::SETCC_VL,
DL, MaskVT,
12038 return DAG.
getNode(RISCVISD::VMERGE_VL,
DL, VT, SelectCond, SplattedVal,
12041 case Intrinsic::riscv_vfmv_s_f:
12042 return DAG.
getNode(RISCVISD::VFMV_S_F_VL,
DL,
Op.getValueType(),
12043 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
12045 case Intrinsic::riscv_vaesdf_vv:
12046 case Intrinsic::riscv_vaesdf_vs:
12047 case Intrinsic::riscv_vaesdm_vv:
12048 case Intrinsic::riscv_vaesdm_vs:
12049 case Intrinsic::riscv_vaesef_vv:
12050 case Intrinsic::riscv_vaesef_vs:
12051 case Intrinsic::riscv_vaesem_vv:
12052 case Intrinsic::riscv_vaesem_vs:
12053 case Intrinsic::riscv_vaeskf1:
12054 case Intrinsic::riscv_vaeskf2:
12055 case Intrinsic::riscv_vaesz_vs:
12056 case Intrinsic::riscv_vsm4k:
12057 case Intrinsic::riscv_vsm4r_vv:
12058 case Intrinsic::riscv_vsm4r_vs: {
12059 if (!
isValidEGW(4,
Op.getSimpleValueType(), Subtarget) ||
12060 !
isValidEGW(4,
Op->getOperand(1).getSimpleValueType(), Subtarget) ||
12061 !
isValidEGW(4,
Op->getOperand(2).getSimpleValueType(), Subtarget))
12066 case Intrinsic::riscv_vsm3c:
12067 case Intrinsic::riscv_vsm3me: {
12068 if (!
isValidEGW(8,
Op.getSimpleValueType(), Subtarget) ||
12069 !
isValidEGW(8,
Op->getOperand(1).getSimpleValueType(), Subtarget))
12074 case Intrinsic::riscv_vsha2ch:
12075 case Intrinsic::riscv_vsha2cl:
12076 case Intrinsic::riscv_vsha2ms: {
12077 if (
Op->getSimpleValueType(0).getScalarSizeInBits() == 64 &&
12078 !Subtarget.hasStdExtZvknhb())
12080 if (!
isValidEGW(4,
Op.getSimpleValueType(), Subtarget) ||
12081 !
isValidEGW(4,
Op->getOperand(1).getSimpleValueType(), Subtarget) ||
12082 !
isValidEGW(4,
Op->getOperand(2).getSimpleValueType(), Subtarget))
12086 case Intrinsic::riscv_sf_vc_v_x:
12087 case Intrinsic::riscv_sf_vc_v_i:
12088 case Intrinsic::riscv_sf_vc_v_xv:
12089 case Intrinsic::riscv_sf_vc_v_iv:
12090 case Intrinsic::riscv_sf_vc_v_vv:
12091 case Intrinsic::riscv_sf_vc_v_fv:
12092 case Intrinsic::riscv_sf_vc_v_xvv:
12093 case Intrinsic::riscv_sf_vc_v_ivv:
12094 case Intrinsic::riscv_sf_vc_v_vvv:
12095 case Intrinsic::riscv_sf_vc_v_fvv:
12096 case Intrinsic::riscv_sf_vc_v_xvw:
12097 case Intrinsic::riscv_sf_vc_v_ivw:
12098 case Intrinsic::riscv_sf_vc_v_vvw:
12099 case Intrinsic::riscv_sf_vc_v_fvw: {
12100 MVT VT =
Op.getSimpleValueType();
12137 MVT VT =
Op.getSimpleValueType();
12141 if (VT.isFloatingPoint()) {
12143 VT.getVectorElementCount());
12146 if (VT.isFixedLengthVector())
12155 if (VT.isFixedLengthVector())
12157 if (VT.isFloatingPoint())
12180 case Intrinsic::riscv_seg2_load_mask:
12181 case Intrinsic::riscv_seg3_load_mask:
12182 case Intrinsic::riscv_seg4_load_mask:
12183 case Intrinsic::riscv_seg5_load_mask:
12184 case Intrinsic::riscv_seg6_load_mask:
12185 case Intrinsic::riscv_seg7_load_mask:
12186 case Intrinsic::riscv_seg8_load_mask:
12189 case Intrinsic::riscv_sseg2_load_mask:
12190 case Intrinsic::riscv_sseg3_load_mask:
12191 case Intrinsic::riscv_sseg4_load_mask:
12192 case Intrinsic::riscv_sseg5_load_mask:
12193 case Intrinsic::riscv_sseg6_load_mask:
12194 case Intrinsic::riscv_sseg7_load_mask:
12195 case Intrinsic::riscv_sseg8_load_mask:
12203 Intrinsic::riscv_vlseg2_mask, Intrinsic::riscv_vlseg3_mask,
12204 Intrinsic::riscv_vlseg4_mask, Intrinsic::riscv_vlseg5_mask,
12205 Intrinsic::riscv_vlseg6_mask, Intrinsic::riscv_vlseg7_mask,
12206 Intrinsic::riscv_vlseg8_mask};
12208 Intrinsic::riscv_vlsseg2_mask, Intrinsic::riscv_vlsseg3_mask,
12209 Intrinsic::riscv_vlsseg4_mask, Intrinsic::riscv_vlsseg5_mask,
12210 Intrinsic::riscv_vlsseg6_mask, Intrinsic::riscv_vlsseg7_mask,
12211 Intrinsic::riscv_vlsseg8_mask};
12214 unsigned NF =
Op->getNumValues() - 1;
12215 assert(NF >= 2 && NF <= 8 &&
"Unexpected seg number");
12217 MVT VT =
Op->getSimpleValueType(0);
12225 SDValue VL =
Op.getOperand(
Op.getNumOperands() - 1);
12226 SDValue Mask =
Op.getOperand(
Op.getNumOperands() - 2);
12227 MVT MaskVT = Mask.getSimpleValueType();
12232 IsStrided ? VlssegInts[NF - 2] : VlsegInts[NF - 2],
DL, XLenVT);
12248 Ops.insert(std::next(
Ops.begin(), 4),
Op.getOperand(3));
12252 Load->getMemoryVT(), Load->getMemOperand());
12254 for (
unsigned int RetIdx = 0; RetIdx < NF; RetIdx++) {
12256 Result.getValue(0),
12260 Results.push_back(Result.getValue(1));
12266 unsigned IntNo =
Op.getConstantOperandVal(1);
12270 case Intrinsic::riscv_seg2_load_mask:
12271 case Intrinsic::riscv_seg3_load_mask:
12272 case Intrinsic::riscv_seg4_load_mask:
12273 case Intrinsic::riscv_seg5_load_mask:
12274 case Intrinsic::riscv_seg6_load_mask:
12275 case Intrinsic::riscv_seg7_load_mask:
12276 case Intrinsic::riscv_seg8_load_mask:
12277 case Intrinsic::riscv_sseg2_load_mask:
12278 case Intrinsic::riscv_sseg3_load_mask:
12279 case Intrinsic::riscv_sseg4_load_mask:
12280 case Intrinsic::riscv_sseg5_load_mask:
12281 case Intrinsic::riscv_sseg6_load_mask:
12282 case Intrinsic::riscv_sseg7_load_mask:
12283 case Intrinsic::riscv_sseg8_load_mask:
12286 case Intrinsic::riscv_sf_vc_v_x_se:
12288 case Intrinsic::riscv_sf_vc_v_i_se:
12290 case Intrinsic::riscv_sf_vc_v_xv_se:
12292 case Intrinsic::riscv_sf_vc_v_iv_se:
12294 case Intrinsic::riscv_sf_vc_v_vv_se:
12296 case Intrinsic::riscv_sf_vc_v_fv_se:
12298 case Intrinsic::riscv_sf_vc_v_xvv_se:
12300 case Intrinsic::riscv_sf_vc_v_ivv_se:
12302 case Intrinsic::riscv_sf_vc_v_vvv_se:
12304 case Intrinsic::riscv_sf_vc_v_fvv_se:
12306 case Intrinsic::riscv_sf_vc_v_xvw_se:
12308 case Intrinsic::riscv_sf_vc_v_ivw_se:
12310 case Intrinsic::riscv_sf_vc_v_vvw_se:
12312 case Intrinsic::riscv_sf_vc_v_fvw_se:
12325 case Intrinsic::riscv_seg2_store_mask:
12326 case Intrinsic::riscv_seg3_store_mask:
12327 case Intrinsic::riscv_seg4_store_mask:
12328 case Intrinsic::riscv_seg5_store_mask:
12329 case Intrinsic::riscv_seg6_store_mask:
12330 case Intrinsic::riscv_seg7_store_mask:
12331 case Intrinsic::riscv_seg8_store_mask:
12334 case Intrinsic::riscv_sseg2_store_mask:
12335 case Intrinsic::riscv_sseg3_store_mask:
12336 case Intrinsic::riscv_sseg4_store_mask:
12337 case Intrinsic::riscv_sseg5_store_mask:
12338 case Intrinsic::riscv_sseg6_store_mask:
12339 case Intrinsic::riscv_sseg7_store_mask:
12340 case Intrinsic::riscv_sseg8_store_mask:
12349 Intrinsic::riscv_vsseg2_mask, Intrinsic::riscv_vsseg3_mask,
12350 Intrinsic::riscv_vsseg4_mask, Intrinsic::riscv_vsseg5_mask,
12351 Intrinsic::riscv_vsseg6_mask, Intrinsic::riscv_vsseg7_mask,
12352 Intrinsic::riscv_vsseg8_mask};
12354 Intrinsic::riscv_vssseg2_mask, Intrinsic::riscv_vssseg3_mask,
12355 Intrinsic::riscv_vssseg4_mask, Intrinsic::riscv_vssseg5_mask,
12356 Intrinsic::riscv_vssseg6_mask, Intrinsic::riscv_vssseg7_mask,
12357 Intrinsic::riscv_vssseg8_mask};
12361 unsigned NF =
Op->getNumOperands() - (IsStrided ? 6 : 5);
12362 assert(NF >= 2 && NF <= 8 &&
"Unexpected seg number");
12364 MVT VT =
Op->getOperand(2).getSimpleValueType();
12370 SDValue VL =
Op.getOperand(
Op.getNumOperands() - 1);
12371 SDValue Mask =
Op.getOperand(
Op.getNumOperands() - 2);
12372 MVT MaskVT = Mask.getSimpleValueType();
12377 IsStrided ? VsssegInts[NF - 2] : VssegInts[NF - 2],
DL, XLenVT);
12383 for (
unsigned i = 0; i < NF; i++)
12385 RISCVISD::TUPLE_INSERT,
DL, VecTupTy, StoredVal,
12391 FixedIntrinsic->getChain(),
12400 Ops.insert(std::next(
Ops.begin(), 4),
12401 Op.getOperand(
Op.getNumOperands() - 3));
12405 FixedIntrinsic->getMemoryVT(), FixedIntrinsic->getMemOperand());
12410 unsigned IntNo =
Op.getConstantOperandVal(1);
12414 case Intrinsic::riscv_seg2_store_mask:
12415 case Intrinsic::riscv_seg3_store_mask:
12416 case Intrinsic::riscv_seg4_store_mask:
12417 case Intrinsic::riscv_seg5_store_mask:
12418 case Intrinsic::riscv_seg6_store_mask:
12419 case Intrinsic::riscv_seg7_store_mask:
12420 case Intrinsic::riscv_seg8_store_mask:
12421 case Intrinsic::riscv_sseg2_store_mask:
12422 case Intrinsic::riscv_sseg3_store_mask:
12423 case Intrinsic::riscv_sseg4_store_mask:
12424 case Intrinsic::riscv_sseg5_store_mask:
12425 case Intrinsic::riscv_sseg6_store_mask:
12426 case Intrinsic::riscv_sseg7_store_mask:
12427 case Intrinsic::riscv_sseg8_store_mask:
12430 case Intrinsic::riscv_sf_vc_xv_se:
12432 case Intrinsic::riscv_sf_vc_iv_se:
12434 case Intrinsic::riscv_sf_vc_vv_se:
12436 case Intrinsic::riscv_sf_vc_fv_se:
12438 case Intrinsic::riscv_sf_vc_xvv_se:
12440 case Intrinsic::riscv_sf_vc_ivv_se:
12442 case Intrinsic::riscv_sf_vc_vvv_se:
12444 case Intrinsic::riscv_sf_vc_fvv_se:
12446 case Intrinsic::riscv_sf_vc_xvw_se:
12448 case Intrinsic::riscv_sf_vc_ivw_se:
12450 case Intrinsic::riscv_sf_vc_vvw_se:
12452 case Intrinsic::riscv_sf_vc_fvw_se:
12460 switch (ISDOpcode) {
12463 case ISD::VP_REDUCE_ADD:
12465 return RISCVISD::VECREDUCE_ADD_VL;
12466 case ISD::VP_REDUCE_UMAX:
12468 return RISCVISD::VECREDUCE_UMAX_VL;
12469 case ISD::VP_REDUCE_SMAX:
12471 return RISCVISD::VECREDUCE_SMAX_VL;
12472 case ISD::VP_REDUCE_UMIN:
12474 return RISCVISD::VECREDUCE_UMIN_VL;
12475 case ISD::VP_REDUCE_SMIN:
12477 return RISCVISD::VECREDUCE_SMIN_VL;
12478 case ISD::VP_REDUCE_AND:
12480 return RISCVISD::VECREDUCE_AND_VL;
12481 case ISD::VP_REDUCE_OR:
12483 return RISCVISD::VECREDUCE_OR_VL;
12484 case ISD::VP_REDUCE_XOR:
12486 return RISCVISD::VECREDUCE_XOR_VL;
12487 case ISD::VP_REDUCE_FADD:
12488 return RISCVISD::VECREDUCE_FADD_VL;
12489 case ISD::VP_REDUCE_SEQ_FADD:
12490 return RISCVISD::VECREDUCE_SEQ_FADD_VL;
12491 case ISD::VP_REDUCE_FMAX:
12492 case ISD::VP_REDUCE_FMAXIMUM:
12493 return RISCVISD::VECREDUCE_FMAX_VL;
12494 case ISD::VP_REDUCE_FMIN:
12495 case ISD::VP_REDUCE_FMINIMUM:
12496 return RISCVISD::VECREDUCE_FMIN_VL;
12505 SDValue Vec =
Op.getOperand(IsVP ? 1 : 0);
12510 Op.getOpcode() == ISD::VP_REDUCE_AND ||
12511 Op.getOpcode() == ISD::VP_REDUCE_OR ||
12512 Op.getOpcode() == ISD::VP_REDUCE_XOR) &&
12513 "Unexpected reduction lowering");
12515 MVT XLenVT = Subtarget.getXLenVT();
12517 MVT ContainerVT = VecVT;
12525 Mask =
Op.getOperand(2);
12526 VL =
Op.getOperand(3);
12528 std::tie(Mask, VL) =
12533 switch (
Op.getOpcode()) {
12537 case ISD::VP_REDUCE_AND: {
12541 Vec = DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Vec, TrueMask, VL);
12544 Vec = DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, Vec, Mask, VL);
12549 case ISD::VP_REDUCE_OR:
12551 Vec = DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, Vec, Mask, VL);
12555 case ISD::VP_REDUCE_XOR: {
12558 Vec = DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, Vec, Mask, VL);
12579 return DAG.
getNode(BaseOpc,
DL,
Op.getValueType(), SetCC,
Op.getOperand(0));
12585 return (RegisterAVL && RegisterAVL->getReg() == RISCV::X0) ||
12586 (ImmAVL && ImmAVL->getZExtValue() >= 1);
12602 auto InnerVT = VecVT.
bitsLE(M1VT) ? VecVT : M1VT;
12606 auto InnerVL = NonZeroAVL ? VL : DAG.
getConstant(1,
DL, XLenVT);
12609 if (M1VT != InnerVT)
12614 SDValue Ops[] = {PassThru, Vec, InitialValue, Mask, VL, Policy};
12632 VecEVT =
Lo.getValueType();
12645 MVT ContainerVT = VecVT;
12668 Mask, VL,
DL, DAG, Subtarget);
12674static std::tuple<unsigned, SDValue, SDValue>
12678 auto Flags =
Op->getFlags();
12679 unsigned Opcode =
Op.getOpcode();
12687 return std::make_tuple(RISCVISD::VECREDUCE_FADD_VL,
Op.getOperand(0), Zero);
12690 return std::make_tuple(RISCVISD::VECREDUCE_SEQ_FADD_VL,
Op.getOperand(1),
12699 ? RISCVISD::VECREDUCE_FMIN_VL
12700 : RISCVISD::VECREDUCE_FMAX_VL;
12701 return std::make_tuple(RVVOpc,
Op.getOperand(0), Front);
12709 MVT VecEltVT =
Op.getSimpleValueType();
12711 unsigned RVVOpcode;
12712 SDValue VectorVal, ScalarVal;
12713 std::tie(RVVOpcode, VectorVal, ScalarVal) =
12717 MVT ContainerVT = VecVT;
12723 MVT ResVT =
Op.getSimpleValueType();
12726 VL,
DL, DAG, Subtarget);
12731 if (
Op->getFlags().hasNoNaNs())
12737 {VectorVal, VectorVal, DAG.getCondCode(ISD::SETNE),
12738 DAG.getUNDEF(Mask.getValueType()), Mask, VL});
12739 MVT XLenVT = Subtarget.getXLenVT();
12740 SDValue CPop = DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, IsNan, Mask, VL);
12744 DL, ResVT, NoNaNs, Res,
12751 unsigned Opc =
Op.getOpcode();
12755 MVT XLenVT = Subtarget.getXLenVT();
12774 Vec, Mask, VL,
DL, DAG, Subtarget);
12775 if ((
Opc != ISD::VP_REDUCE_FMINIMUM &&
Opc != ISD::VP_REDUCE_FMAXIMUM) ||
12776 Op->getFlags().hasNoNaNs())
12783 RISCVISD::SETCC_VL,
DL, PredVT,
12785 SDValue VCPop = DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, IsNaN, Mask, VL);
12793 DL, ResVT, NoNaNs, Res,
12805 MVT XLenVT = Subtarget.getXLenVT();
12806 unsigned OrigIdx =
Op.getConstantOperandVal(2);
12807 const RISCVRegisterInfo *
TRI = Subtarget.getRegisterInfo();
12809 if (OrigIdx == 0 && Vec.
isUndef())
12820 assert(OrigIdx % 8 == 0 &&
"Invalid index");
12823 "Unexpected mask vector lowering");
12853 const auto VLen = Subtarget.getRealVLen();
12855 MVT ContainerVT = VecVT;
12877 if (OrigIdx == 0) {
12879 DAG.
getNode(RISCVISD::VMV_V_V_VL,
DL, ContainerVT, Vec, SubVec, VL);
12882 SubVec =
getVSlideup(DAG, Subtarget,
DL, ContainerVT, Vec, SubVec,
12883 SlideupAmt, Mask, VL, Policy);
12891 MVT ContainerVecVT = VecVT;
12897 MVT ContainerSubVecVT = SubVecVT;
12903 unsigned SubRegIdx;
12904 ElementCount RemIdx;
12913 ContainerVecVT, ContainerSubVecVT, OrigIdx / Vscale,
TRI);
12914 SubRegIdx = Decompose.first;
12916 (OrigIdx % Vscale));
12920 ContainerVecVT, ContainerSubVecVT, OrigIdx,
TRI);
12921 SubRegIdx = Decompose.first;
12927 Subtarget.expandVScale(SubVecVT.
getSizeInBits()).getKnownMinValue()));
12928 bool ExactlyVecRegSized =
12930 .isKnownMultipleOf(Subtarget.expandVScale(VecRegSize));
12945 if (RemIdx.
isZero() && (ExactlyVecRegSized || Vec.
isUndef())) {
12949 if (SubRegIdx == RISCV::NoSubRegister) {
12971 MVT InterSubVT = ContainerVecVT;
12972 SDValue AlignedExtract = Vec;
12994 if (Subtarget.expandVScale(EndIndex) ==
13001 SubVec = DAG.
getNode(RISCVISD::VMV_V_V_VL,
DL, InterSubVT, AlignedExtract,
13009 SubVec =
getVSlideup(DAG, Subtarget,
DL, InterSubVT, AlignedExtract, SubVec,
13010 SlideupAmt, Mask, VL, Policy);
13015 if (ContainerVecVT.
bitsGT(InterSubVT))
13023 return DAG.
getBitcast(
Op.getSimpleValueType(), SubVec);
13029 MVT SubVecVT =
Op.getSimpleValueType();
13033 MVT XLenVT = Subtarget.getXLenVT();
13034 unsigned OrigIdx =
Op.getConstantOperandVal(1);
13035 const RISCVRegisterInfo *
TRI = Subtarget.getRegisterInfo();
13050 assert(OrigIdx % 8 == 0 &&
"Invalid index");
13053 "Unexpected mask vector lowering");
13079 const auto VLen = Subtarget.getRealVLen();
13087 MVT ContainerVT = VecVT;
13095 if (
auto ShrunkVT =
13097 ContainerVT = *ShrunkVT;
13109 DAG.
getUNDEF(ContainerVT), Vec, SlidedownAmt, Mask, VL);
13120 MVT ContainerSubVecVT = SubVecVT;
13124 unsigned SubRegIdx;
13125 ElementCount RemIdx;
13134 VecVT, ContainerSubVecVT, OrigIdx / Vscale,
TRI);
13135 SubRegIdx = Decompose.first;
13137 (OrigIdx % Vscale));
13141 VecVT, ContainerSubVecVT, OrigIdx,
TRI);
13142 SubRegIdx = Decompose.first;
13169 MVT InterSubVT = VecVT;
13174 assert(SubRegIdx != RISCV::NoSubRegister);
13193 Vec, SlidedownAmt, Mask, VL);
13201 return DAG.
getBitcast(
Op.getSimpleValueType(), Slidedown);
13208 MVT VT =
N.getSimpleValueType();
13212 assert(
Op.getSimpleValueType() == VT &&
13213 "Operands and result must be same type");
13217 unsigned NumVals =
N->getNumValues();
13221 N.getValueType().changeVectorElementType(*DAG.
getContext(), MVT::i8)));
13224 for (
unsigned I = 0;
I < NumVals;
I++) {
13230 if (TruncVals.
size() > 1)
13232 return TruncVals.
front();
13238 MVT VecVT =
Op.getSimpleValueType();
13240 const unsigned Factor =
Op->getNumValues();
13249 MVT ContainerVecVT = VecVT;
13257 for (
unsigned i = 0; i != Factor; ++i) {
13260 Ops[i * 2 + 1] = OpHi;
13271 for (
unsigned i = 0; i != Factor; ++i)
13278 if (Subtarget.hasStdExtZvzip() && Factor == 2 && !IsFixedVector) {
13279 MVT VT =
Op->getSimpleValueType(0);
13304 if (Factor == 2 && !IsFixedVector) {
13322 EvenSplat = DAG.
getBitcast(MVT::nxv64i1, EvenSplat);
13326 OddSplat = DAG.
getBitcast(MVT::nxv64i1, OddSplat);
13331 EvenMask, DAG.
getUNDEF(ConcatVT));
13344 MVT XLenVT = Subtarget.getXLenVT();
13349 MachinePointerInfo PtrInfo;
13350 if (IsFixedVector) {
13352 ElementCount ActualConcatEC =
13366 MachinePointerInfo PI = PtrInfo;
13368 for (
auto [Idx, FieldOp] :
enumerate(
Op->op_values())) {
13374 Tokens[Idx] = DAG.
getStore(Chain,
DL, FieldOp, BasePtr, PI, Alignment);
13379 std::tie(Mask, VL) =
13401 Intrinsic::riscv_vlseg2_mask, Intrinsic::riscv_vlseg3_mask,
13402 Intrinsic::riscv_vlseg4_mask, Intrinsic::riscv_vlseg5_mask,
13403 Intrinsic::riscv_vlseg6_mask, Intrinsic::riscv_vlseg7_mask,
13404 Intrinsic::riscv_vlseg8_mask};
13428 for (
unsigned i = 0U; i < Factor; ++i) {
13430 DAG.
getNode(RISCVISD::TUPLE_EXTRACT,
DL, ContainerVecVT, Load,
13443 MVT VecVT =
Op.getSimpleValueType();
13456 for (
unsigned i = 0U; i < Factor; ++i)
13464 for (
unsigned i = 0U; i < Factor; ++i)
13470 MVT XLenVT = Subtarget.getXLenVT();
13477 for (
unsigned i = 0; i != Factor; ++i) {
13480 Ops[i + Factor] = OpHi;
13491 for (
unsigned i = 0; i != Factor; ++i) {
13492 unsigned IdxLo = 2 * i;
13493 unsigned IdxHi = 2 * i + 1;
13495 Res[IdxLo / Factor].
getValue(IdxLo % Factor),
13496 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
13514 EVT PtrVT =
StackPtr.getValueType();
13520 Intrinsic::riscv_vsseg2_mask, Intrinsic::riscv_vsseg3_mask,
13521 Intrinsic::riscv_vsseg4_mask, Intrinsic::riscv_vsseg5_mask,
13522 Intrinsic::riscv_vsseg6_mask, Intrinsic::riscv_vsseg7_mask,
13523 Intrinsic::riscv_vsseg8_mask,
13531 for (
unsigned i = 0; i < Factor; i++)
13533 DAG.
getNode(RISCVISD::TUPLE_INSERT,
DL, VecTupTy, StoredVal,
13553 for (
unsigned i = 0; i != Factor; ++i) {
13557 Loads[i] = DAG.
getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
13563 if (Subtarget.hasStdExtZvzip() && !
Op.getOperand(0).isUndef() &&
13564 !
Op.getOperand(1).isUndef()) {
13565 MVT VT =
Op->getSimpleValueType(0);
13589 Op.getOperand(0),
Op.getOperand(1));
13613 DAG.
getNode(RISCVISD::ADD_VL,
DL, IdxVT, Idx, VLMax, Idx, OddMask, VL);
13618 Interleaved = DAG.
getNode(RISCVISD::VRGATHEREI16_VV_VL,
DL, ConcatVT,
13635 MVT VT =
Op.getSimpleValueType();
13637 MVT XLenVT = Subtarget.getXLenVT();
13640 uint64_t StepValImm =
Op.getConstantOperandVal(0);
13641 if (StepValImm != 1) {
13650 VL, VT,
DL, DAG, Subtarget);
13665 MVT VecVT =
Op.getSimpleValueType();
13669 if (Subtarget.hasStdExtP() && !Subtarget.hasVInstructions()) {
13671 "Unexpected packed VECTOR_REVERSE type");
13673 if (VecVT == MVT::v2i32) {
13693 MVT ContainerVT = VecVT;
13700 MVT XLenVT = Subtarget.getXLenVT();
13746 unsigned VectorBitsMax = Subtarget.getRealMaxVLen();
13747 unsigned MaxVLMAX =
13752 unsigned GatherOpc = RISCVISD::VRGATHER_VV_VL;
13757 if (MaxVLMAX > 256 && EltSize == 8) {
13773 GatherOpc = RISCVISD::VRGATHEREI16_VV_VL;
13781 GatherOpc = RISCVISD::VRGATHEREI16_VV_VL;
13806 DAG.
getUNDEF(ContainerVT), Mask, VL);
13818 MVT XLenVT = Subtarget.getXLenVT();
13819 MVT VecVT =
Op.getSimpleValueType();
13823 SDValue DownOffset, UpOffset;
13839 DAG, Subtarget,
DL, VecVT, DAG.
getUNDEF(VecVT),
V1, DownOffset, TrueMask,
13840 Subtarget.hasVLDependentLatency() ? UpOffset
13842 return getVSlideup(DAG, Subtarget,
DL, VecVT, SlideDown, V2, UpOffset,
13848RISCVTargetLowering::lowerFixedLengthVectorLoadToRVV(
SDValue Op,
13854 Load->getMemoryVT(),
13855 *
Load->getMemOperand()) &&
13856 "Expecting a correctly-aligned load");
13858 MVT VT =
Op.getSimpleValueType();
13859 MVT XLenVT = Subtarget.getXLenVT();
13864 const auto [MinVLMAX, MaxVLMAX] =
13868 MachineMemOperand *MMO =
Load->getMemOperand();
13881 IsMaskOp ? Intrinsic::riscv_vlm : Intrinsic::riscv_vle,
DL, XLenVT);
13885 Ops.push_back(
Load->getBasePtr());
13887 SDVTList VTs = DAG.
getVTList({ContainerVT, MVT::Other});
13890 Load->getMemoryVT(),
Load->getMemOperand());
13897RISCVTargetLowering::lowerFixedLengthVectorStoreToRVV(
SDValue Op,
13903 Store->getMemoryVT(),
13904 *
Store->getMemOperand()) &&
13905 "Expecting a correctly-aligned store");
13909 MVT XLenVT = Subtarget.getXLenVT();
13925 const auto [MinVLMAX, MaxVLMAX] =
13929 MachineMemOperand *MMO =
Store->getMemOperand();
13939 IsMaskOp ? Intrinsic::riscv_vsm : Intrinsic::riscv_vse,
DL, XLenVT);
13942 {Store->getChain(), IntID, NewValue, Store->getBasePtr(), VL},
13943 Store->getMemoryVT(),
Store->getMemOperand());
13949 MVT VT =
Op.getSimpleValueType();
13952 EVT MemVT = MemSD->getMemoryVT();
13953 MachineMemOperand *MMO = MemSD->getMemOperand();
13954 SDValue Chain = MemSD->getChain();
13958 bool IsExpandingLoad =
false;
13960 Mask = VPLoad->getMask();
13962 VL = VPLoad->getVectorLength();
13966 PassThru =
MLoad->getPassThru();
13967 IsExpandingLoad =
MLoad->isExpandingLoad();
13972 MVT XLenVT = Subtarget.getXLenVT();
13974 MVT ContainerVT = VT;
13988 if (!IsUnmasked && IsExpandingLoad) {
13991 DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, Mask,
13995 unsigned IntID = IsUnmasked || IsExpandingLoad ? Intrinsic::riscv_vle
13996 : Intrinsic::riscv_vle_mask;
13998 if (IntID == Intrinsic::riscv_vle)
14001 Ops.push_back(PassThru);
14002 Ops.push_back(BasePtr);
14003 if (IntID == Intrinsic::riscv_vle_mask)
14004 Ops.push_back(Mask);
14006 if (IntID == Intrinsic::riscv_vle_mask)
14009 SDVTList VTs = DAG.
getVTList({ContainerVT, MVT::Other});
14013 Chain =
Result.getValue(1);
14015 MVT IndexVT = ContainerVT;
14020 bool UseVRGATHEREI16 =
false;
14028 UseVRGATHEREI16 =
true;
14034 DAG.
getUNDEF(IndexVT), Mask, ExpandingVL);
14036 DAG.
getNode(UseVRGATHEREI16 ? RISCVISD::VRGATHEREI16_VV_VL
14037 : RISCVISD::VRGATHER_VV_VL,
14038 DL, ContainerVT, Result, Iota, PassThru, Mask, ExpandingVL);
14049 MVT VT =
Op->getSimpleValueType(0);
14052 EVT MemVT = VPLoadFF->getMemoryVT();
14053 MachineMemOperand *MMO = VPLoadFF->getMemOperand();
14054 SDValue Chain = VPLoadFF->getChain();
14058 SDValue VL = VPLoadFF->getVectorLength();
14060 MVT XLenVT = Subtarget.getXLenVT();
14062 MVT ContainerVT = VT;
14069 unsigned IntID = Intrinsic::riscv_vleff_mask;
14079 SDVTList VTs = DAG.
getVTList({ContainerVT,
Op->getValueType(1), MVT::Other});
14084 Chain =
Result.getValue(2);
14097 EVT MemVT = MemSD->getMemoryVT();
14098 MachineMemOperand *MMO = MemSD->getMemOperand();
14099 SDValue Chain = MemSD->getChain();
14103 bool IsCompressingStore =
false;
14105 Val = VPStore->getValue();
14106 Mask = VPStore->getMask();
14107 VL = VPStore->getVectorLength();
14110 Val = MStore->getValue();
14111 Mask = MStore->getMask();
14112 IsCompressingStore = MStore->isCompressingStore();
14119 MVT XLenVT = Subtarget.getXLenVT();
14121 MVT ContainerVT = VT;
14126 if (!IsUnmasked || IsCompressingStore) {
14135 if (IsCompressingStore) {
14139 DAG.
getUNDEF(ContainerVT), Val, Mask, VL);
14141 DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, Mask,
14146 IsUnmasked ? Intrinsic::riscv_vse : Intrinsic::riscv_vse_mask;
14148 Ops.push_back(Val);
14149 Ops.push_back(BasePtr);
14151 Ops.push_back(Mask);
14166 MVT XLenVT = Subtarget.getXLenVT();
14167 MVT ContainerVT = VT;
14180 Passthru, Val, Mask, VL);
14190 unsigned Opc =
Op.getOpcode();
14197 MVT VT =
Op.getSimpleValueType();
14205 SDVTList VTList =
Op->getVTList();
14230 MVT ContainerInVT = InVT;
14248 RISCVISD::STRICT_FSETCC_VL,
DL, DAG.
getVTList(MaskVT, MVT::Other),
14249 {Chain, Op1, Op1, DAG.getCondCode(ISD::SETOEQ), DAG.getUNDEF(MaskVT),
14252 RISCVISD::STRICT_FSETCC_VL,
DL, DAG.
getVTList(MaskVT, MVT::Other),
14253 {Chain, Op2, Op2, DAG.getCondCode(ISD::SETOEQ), DAG.getUNDEF(MaskVT),
14256 DAG.
getNode(RISCVISD::VMAND_VL,
DL, MaskVT, OrderMask1, OrderMask2, VL);
14259 Res = DAG.
getNode(RISCVISD::STRICT_FSETCCS_VL,
DL,
14261 {Chain, Op1, Op2, CC, Mask, Mask, VL});
14264 : RISCVISD::STRICT_FSETCCS_VL;
14266 {Chain, Op1, Op2, CC, DAG.getUNDEF(MaskVT), Mask, VL});
14279 MVT VT =
Op.getSimpleValueType();
14290 if (Subtarget.hasStdExtZvabd()) {
14292 DAG.
getUNDEF(ContainerVT), Mask, VL);
14295 RISCVISD::VMV_V_X_VL,
DL, ContainerVT, DAG.
getUNDEF(ContainerVT),
14298 DAG.
getUNDEF(ContainerVT), Mask, VL);
14300 DAG.
getUNDEF(ContainerVT), Mask, VL);
14307 const auto &TSInfo =
14311 bool HasPassthruOp = TSInfo.hasPassthruOp(NewOpc);
14312 bool HasMask = TSInfo.hasMaskOp(NewOpc);
14314 MVT VT =
Op.getSimpleValueType();
14319 for (
const SDValue &V :
Op->op_values()) {
14323 if (!
V.getValueType().isVector()) {
14329 assert(useRVVForFixedLengthVectorVT(
V.getSimpleValueType()) &&
14330 "Only fixed length vectors are supported!");
14332 V.getSimpleValueType().getVectorElementType());
14341 Ops.push_back(Mask);
14346 if (
Op->isStrictFPOpcode()) {
14365 const auto &TSInfo =
14369 bool HasPassthruOp = TSInfo.hasPassthruOp(RISCVISDOpc);
14372 MVT VT =
Op.getSimpleValueType();
14375 MVT ContainerVT = VT;
14384 if (HasPassthruOp) {
14387 if (*MaskIdx ==
OpIdx.index())
14391 assert(
Op.getOpcode() == ISD::VP_MERGE);
14393 Ops.push_back(
Ops.back());
14397 if (RISCVISDOpc == RISCVISD::VFCVT_RM_X_F_VL &&
14400 Subtarget.getXLenVT()));
14402 if (!
V.getValueType().isFixedLengthVector()) {
14407 MVT OpVT =
V.getSimpleValueType();
14409 assert(useRVVForFixedLengthVectorVT(OpVT) &&
14410 "Only fixed length vectors are supported!");
14425 MVT VT =
Op.getSimpleValueType();
14426 MVT XLenVT = Subtarget.getXLenVT();
14439 MVT ContainerVT = VT;
14459 TrueVal = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, PromotedVT, TrueVal, SplatOne,
14460 SplatZero, DAG.
getUNDEF(PromotedVT), VL);
14463 SplatOne, SplatZero, DAG.
getUNDEF(PromotedVT), VLMax);
14467 TrueVal, FalseVal, FalseVal, VL);
14472 RISCVISD::SETCC_VL,
DL, ContainerVT,
14482RISCVTargetLowering::lowerVPSpliceExperimental(
SDValue Op,
14484 using namespace SDPatternMatch;
14495 const MVT XLenVT = Subtarget.getXLenVT();
14496 MVT VT =
Op.getSimpleValueType();
14497 MVT ContainerVT = VT;
14507 if (IsMaskVector) {
14517 Op1 = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, ContainerVT, Op1, SplatOneOp1,
14518 SplatZeroOp1, DAG.
getUNDEF(ContainerVT), EVL1);
14526 Op2 = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, ContainerVT, Op2, SplatOneOp2,
14527 SplatZeroOp2, DAG.
getUNDEF(ContainerVT), EVL2);
14530 auto getVectorFirstEle = [](
SDValue Vec) {
14543 if (
auto FirstEle = getVectorFirstEle(
Op->getOperand(0))) {
14546 if ((EltVT == MVT::f16 && !Subtarget.hasVInstructionsF16()) ||
14547 (EltVT == MVT::bf16 && !Subtarget.hasVInstructionsBF16())) {
14555 : RISCVISD::VSLIDE1UP_VL,
14556 DL, ContainerVT, DAG.
getUNDEF(ContainerVT), Op2,
14557 FirstEle, Mask, EVL2);
14567 SDValue DownOffset, UpOffset;
14568 if (ImmValue >= 0) {
14582 DAG.
getUNDEF(ContainerVT), Op1, DownOffset, Mask,
14583 Subtarget.hasVLDependentLatency() ? UpOffset : EVL2);
14587 if (IsMaskVector) {
14591 {Result, DAG.getConstant(0, DL, ContainerVT),
14592 DAG.getCondCode(ISD::SETNE), DAG.getUNDEF(getMaskTypeFor(ContainerVT)),
14602RISCVTargetLowering::lowerVPReverseExperimental(
SDValue Op,
14605 MVT VT =
Op.getSimpleValueType();
14606 MVT XLenVT = Subtarget.getXLenVT();
14612 MVT ContainerVT = VT;
14620 MVT GatherVT = ContainerVT;
14624 if (IsMaskVector) {
14634 Op1 = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, IndicesVT, Op1, SplatOne,
14635 SplatZero, DAG.
getUNDEF(IndicesVT), EVL);
14640 unsigned VectorBitsMax = Subtarget.getRealMaxVLen();
14641 unsigned MaxVLMAX =
14644 unsigned GatherOpc = RISCVISD::VRGATHER_VV_VL;
14650 if (MaxVLMAX > 256 && EltSize == 8) {
14677 DAG.
getUNDEF(GatherVT), Result, Diff, Mask, EVL);
14679 if (IsMaskVector) {
14682 DAG.
getNode(RISCVISD::SETCC_VL,
DL, ContainerVT,
14695 GatherOpc = RISCVISD::VRGATHEREI16_VV_VL;
14702 DAG.
getUNDEF(IndicesVT), VecLen, EVL);
14703 SDValue VRSUB = DAG.
getNode(RISCVISD::SUB_VL,
DL, IndicesVT, VecLenSplat, VID,
14704 DAG.
getUNDEF(IndicesVT), Mask, EVL);
14706 DAG.
getUNDEF(GatherVT), Mask, EVL);
14708 if (IsMaskVector) {
14711 RISCVISD::SETCC_VL,
DL, ContainerVT,
14724 MVT XLenVT = Subtarget.getXLenVT();
14725 MVT VT =
Op.getSimpleValueType();
14726 MVT ContainerVT = VT;
14730 SDVTList VTs = DAG.
getVTList({ContainerVT, MVT::Other});
14738 : Intrinsic::riscv_vlse_mask,
14741 DAG.
getUNDEF(ContainerVT), VPNode->getBasePtr(),
14742 VPNode->getStride()};
14748 Ops.push_back(Mask);
14750 Ops.push_back(VPNode->getVectorLength());
14754 Ops.push_back(Policy);
14759 VPNode->getMemoryVT(), VPNode->getMemOperand());
14771 MVT XLenVT = Subtarget.getXLenVT();
14774 SDValue StoreVal = VPNode->getValue();
14776 MVT ContainerVT = VT;
14787 : Intrinsic::riscv_vsse_mask,
14790 VPNode->getBasePtr(), VPNode->getStride()};
14796 Ops.push_back(Mask);
14798 Ops.push_back(VPNode->getVectorLength());
14801 Ops, VPNode->getMemoryVT(),
14802 VPNode->getMemOperand());
14814 MVT VT =
Op.getSimpleValueType();
14817 EVT MemVT = MemSD->getMemoryVT();
14818 MachineMemOperand *MMO = MemSD->getMemOperand();
14819 SDValue Chain = MemSD->getChain();
14826 Index = VPGN->getIndex();
14827 Mask = VPGN->getMask();
14829 VL = VPGN->getVectorLength();
14835 Index = MGN->getIndex();
14836 Mask = MGN->getMask();
14837 PassThru = MGN->getPassThru();
14841 MVT IndexVT =
Index.getSimpleValueType();
14842 MVT XLenVT = Subtarget.getXLenVT();
14845 "Unexpected VTs!");
14846 assert(
BasePtr.getSimpleValueType() == XLenVT &&
"Unexpected pointer type");
14849 "Unexpected extending MGATHER/VP_GATHER");
14855 MVT ContainerVT = VT;
14879 IsUnmasked ? Intrinsic::riscv_vluxei : Intrinsic::riscv_vluxei_mask;
14884 Ops.push_back(PassThru);
14885 Ops.push_back(BasePtr);
14886 Ops.push_back(Index);
14888 Ops.push_back(Mask);
14893 SDVTList VTs = DAG.
getVTList({ContainerVT, MVT::Other});
14896 Chain =
Result.getValue(1);
14914 EVT MemVT = MemSD->getMemoryVT();
14915 MachineMemOperand *MMO = MemSD->getMemOperand();
14916 SDValue Chain = MemSD->getChain();
14919 [[maybe_unused]]
bool IsTruncatingStore =
false;
14923 Index = VPSN->getIndex();
14924 Mask = VPSN->getMask();
14925 Val = VPSN->getValue();
14926 VL = VPSN->getVectorLength();
14928 IsTruncatingStore =
false;
14932 Index = MSN->getIndex();
14933 Mask = MSN->getMask();
14934 Val = MSN->getValue();
14935 IsTruncatingStore = MSN->isTruncatingStore();
14939 MVT IndexVT =
Index.getSimpleValueType();
14940 MVT XLenVT = Subtarget.getXLenVT();
14943 "Unexpected VTs!");
14944 assert(
BasePtr.getSimpleValueType() == XLenVT &&
"Unexpected pointer type");
14947 assert(!IsTruncatingStore &&
"Unexpected truncating MSCATTER/VP_SCATTER");
14953 MVT ContainerVT = VT;
14977 IsUnmasked ? Intrinsic::riscv_vsoxei : Intrinsic::riscv_vsoxei_mask;
14979 Ops.push_back(Val);
14980 Ops.push_back(BasePtr);
14981 Ops.push_back(Index);
14983 Ops.push_back(Mask);
14992 const MVT XLenVT = Subtarget.getXLenVT();
14996 SDVTList VTs = DAG.
getVTList(XLenVT, MVT::Other);
15003 static const int Table =
15022 const MVT XLenVT = Subtarget.getXLenVT();
15032 static const unsigned Table =
15047 return DAG.
getNode(RISCVISD::WRITE_CSR,
DL, MVT::Other, Chain, SysRegNo,
15053 const MVT XLenVT = Subtarget.getXLenVT();
15057 SDVTList VTs = DAG.
getVTList(XLenVT, MVT::Other);
15058 return DAG.
getNode(RISCVISD::READ_CSR,
DL, VTs, Chain, SysRegNo);
15063 const MVT XLenVT = Subtarget.getXLenVT();
15070 return DAG.
getNode(RISCVISD::WRITE_CSR,
DL, MVT::Other, Chain, SysRegNo,
15076 const MVT XLenVT = Subtarget.getXLenVT();
15082 return DAG.
getNode(RISCVISD::WRITE_CSR,
DL, MVT::Other, Chain, SysRegNo,
15096 SDValue Result = DAG.
getNode(RISCVISD::READ_CSR,
DL, VTs, Chain, SysRegNo);
15097 Chain = Result.getValue(1);
15103 const MVT XLenVT = Subtarget.getXLenVT();
15113 Chain = DAG.
getNode(RISCVISD::CLEAR_CSR,
DL, MVT::Other, Chain, SysRegNo,
15115 return DAG.
getNode(RISCVISD::SET_CSR,
DL, MVT::Other, Chain, SysRegNo,
15121 const MVT XLenVT = Subtarget.getXLenVT();
15128 return DAG.
getNode(RISCVISD::CLEAR_CSR,
DL, MVT::Other, Chain, SysRegNo,
15136 bool isRISCV64 = Subtarget.is64Bit();
15150 return RISCVISD::SLLW;
15152 return RISCVISD::SRAW;
15154 return RISCVISD::SRLW;
15156 return RISCVISD::DIVW;
15158 return RISCVISD::DIVUW;
15160 return RISCVISD::REMUW;
15162 return RISCVISD::ROLW;
15164 return RISCVISD::RORW;
15209 switch (
N->getOpcode()) {
15211 llvm_unreachable(
"Don't know how to custom type legalize this operation!");
15216 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
15217 "Unexpected custom legalisation");
15218 bool IsStrict =
N->isStrictFPOpcode();
15221 SDValue Op0 = IsStrict ?
N->getOperand(1) :
N->getOperand(0);
15230 !Subtarget.hasStdExtZfhOrZhinx()) {
15235 unsigned Opc = IsSigned ? RISCVISD::STRICT_FCVT_W_RV64
15236 : RISCVISD::STRICT_FCVT_WU_RV64;
15239 Opc,
DL, VTs, Chain, Op0,
15248 !Subtarget.hasStdExtZfhOrZhinx()) ||
15252 unsigned Opc = IsSigned ? RISCVISD::FCVT_W_RV64 : RISCVISD::FCVT_WU_RV64;
15273 std::tie(Result, Chain) =
15274 makeLibCall(DAG, LC,
N->getValueType(0), Op0, CallOptions,
DL, Chain);
15289 if (Op0.
getValueType() == MVT::f16 && !Subtarget.hasStdExtZfhOrZhinx())
15293 DAG.
getNode(RISCVISD::FCVT_W_RV64,
DL, MVT::i64, Op0,
15301 RTLIB::Libcall LC =
15302 Op0.
getValueType() == MVT::f64 ? RTLIB::LROUND_F64 : RTLIB::LROUND_F32;
15313 assert(!Subtarget.is64Bit() &&
"READCYCLECOUNTER/READSTEADYCOUNTER only "
15314 "has custom type legalization on riscv32");
15316 SDValue LoCounter, HiCounter;
15317 MVT XLenVT = Subtarget.getXLenVT();
15327 N->getOperand(0), LoCounter, HiCounter);
15342 if (
N->getValueType(0) == MVT::i64) {
15343 assert(Subtarget.hasStdExtZilsd() && !Subtarget.is64Bit() &&
15344 "Unexpected custom legalisation");
15346 if (Ld->
getAlign() < Subtarget.getZilsdAlign())
15351 RISCVISD::LD_RV32,
DL,
15352 DAG.
getVTList({MVT::i32, MVT::i32, MVT::Other}),
15353 {Ld->getChain(), Ld->getBasePtr()}, MVT::i64, Ld->
getMemOperand());
15357 Results.append({Pair, Result.getValue(2)});
15361 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
15362 "Unexpected custom legalisation");
15373 unsigned Size =
N->getSimpleValueType(0).getSizeInBits();
15374 unsigned XLen = Subtarget.getXLen();
15382 assert(
Size == (XLen * 2) &&
"Unexpected custom legalisation");
15385 unsigned LoHiOpc) {
15386 MVT XLenVT = Subtarget.getXLenVT();
15390 if (Subtarget.hasStdExtP() && !Subtarget.is64Bit()) {
15393 Hi =
Lo.getValue(1);
15407 if (LHSIsU && RHSIsU) {
15414 if (LHSIsS && RHSIsS)
15416 else if (RHSIsU && LHSIsS)
15418 MakeMULPair(LHS, RHS, RISCVISD::MULHSU, RISCVISD::WMULSU));
15419 else if (LHSIsU && RHSIsS)
15421 MakeMULPair(RHS, LHS, RISCVISD::MULHSU, RISCVISD::WMULSU));
15429 if (
N->getValueType(0) == MVT::i64) {
15430 assert(!Subtarget.is64Bit() && Subtarget.hasStdExtP() &&
15431 "Unexpected custom legalisation");
15434 auto [LHSLo, LHSHi] =
15436 auto [RHSLo, RHSHi] =
15439 N->getOpcode() ==
ISD::ADD ? RISCVISD::ADDD : RISCVISD::SUBD;
15441 LHSLo, LHSHi, RHSLo, RHSHi);
15447 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
15448 "Unexpected custom legalisation");
15454 EVT VT =
N->getValueType(0);
15456 assert(Subtarget.is64Bit() && (VT == MVT::v2i16 || VT == MVT::v4i8) &&
15457 "Unexpected vector type for P-extension shift");
15461 SDValue ShiftAmt =
N->getOperand(1);
15473 if (VT == MVT::i64) {
15474 assert(!Subtarget.is64Bit() && Subtarget.hasStdExtP() &&
15475 "Unexpected custom legalisation");
15480 unsigned WideOpc = 0;
15483 WideOpc = RISCVISD::WSLL;
15485 WideOpc = RISCVISD::WSLA;
15501 if (!ShAmtC || ShAmtC->getZExtValue() >= 32)
15515 uint64_t ShAmtVal = ShAmtC->getZExtValue();
15520 bool IsSRA =
N->getOpcode() ==
ISD::SRA;
15521 LoRes = DAG.
getNode(IsSRA ? RISCVISD::NSRA : RISCVISD::NSRL,
DL,
15522 MVT::i32,
Lo,
Hi, ShAmt);
15531 assert(VT == MVT::i32 && Subtarget.is64Bit() &&
15532 "Unexpected custom legalisation");
15535 if (
N->getOpcode() ==
ISD::SHL && Subtarget.hasStdExtZbs() &&
15561 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
15562 "Unexpected custom legalisation");
15563 assert((Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb() ||
15564 Subtarget.hasVendorXTHeadBb()) &&
15565 "Unexpected custom legalization");
15567 !(Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()))
15576 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
15577 "Unexpected custom legalisation");
15582 switch (
N->getOpcode()) {
15586 Opc = RISCVISD::CTZW;
15590 Opc = RISCVISD::CLZW;
15593 Opc = RISCVISD::CLSW;
15604 MVT VT =
N->getSimpleValueType(0);
15605 assert((VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) &&
15606 Subtarget.is64Bit() && Subtarget.hasStdExtM() &&
15607 "Unexpected custom legalisation");
15619 if (VT != MVT::i32)
15628 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
15629 "Unexpected custom legalisation");
15651 EVT OType =
N->getValueType(1);
15668 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
15669 "Unexpected custom legalisation");
15686 Overflow = DAG.
getSetCC(
DL,
N->getValueType(1), Res,
15690 Overflow = DAG.
getSetCC(
DL,
N->getValueType(1),
N->getOperand(0),
15697 Overflow = DAG.
getSetCC(
DL,
N->getValueType(1), Res, LHS,
15709 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
15710 "Unexpected custom legalisation");
15712 if (Subtarget.hasStdExtP()) {
15728 assert(!Subtarget.hasStdExtZbb() &&
"Unexpected custom legalisation");
15734 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
15735 "Unexpected custom legalisation");
15737 if (Subtarget.hasStdExtP()) {
15745 if (Subtarget.hasStdExtZbb()) {
15779 EVT VT =
N->getValueType(0);
15783 MVT XLenVT = Subtarget.getXLenVT();
15784 if (VT == MVT::i16 &&
15785 ((Op0VT == MVT::f16 && Subtarget.hasStdExtZfhminOrZhinxmin()) ||
15786 (Op0VT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()))) {
15789 }
else if (VT == MVT::i32 && Op0VT == MVT::f32 && Subtarget.is64Bit() &&
15790 Subtarget.hasStdExtFOrZfinx()) {
15792 DAG.
getNode(RISCVISD::FMV_X_ANYEXTW_RV64,
DL, MVT::i64, Op0);
15794 }
else if (VT == MVT::i64 && Op0VT == MVT::f64 && !Subtarget.is64Bit() &&
15795 Subtarget.hasStdExtDOrZdinx()) {
15797 DAG.
getVTList(MVT::i32, MVT::i32), Op0);
15801 if (!Subtarget.isLittleEndian())
15820 assert(
N->getValueType(0) == MVT::i8 && Subtarget.hasStdExtZbkb() &&
15821 "Unexpected custom legalisation");
15822 MVT XLenVT = Subtarget.getXLenVT();
15830 case RISCVISD::BREV8:
15831 case RISCVISD::ORC_B: {
15832 MVT VT =
N->getSimpleValueType(0);
15833 MVT XLenVT = Subtarget.getXLenVT();
15834 assert((VT == MVT::i16 || (VT == MVT::i32 && Subtarget.is64Bit())) &&
15835 "Unexpected custom legalisation");
15836 assert(((
N->getOpcode() == RISCVISD::BREV8 && Subtarget.hasStdExtZbkb()) ||
15837 (
N->getOpcode() == RISCVISD::ORC_B && Subtarget.hasStdExtZbb())) &&
15838 "Unexpected extension");
15846 case RISCVISD::ASUB:
15847 case RISCVISD::ASUBU:
15848 case RISCVISD::MULHSU:
15849 case RISCVISD::MULHR:
15850 case RISCVISD::MULHRU:
15851 case RISCVISD::MULHRSU: {
15852 MVT VT =
N->getSimpleValueType(0);
15855 unsigned Opcode =
N->getOpcode();
15857 [[maybe_unused]]
bool IsMulH =
15858 Opcode == RISCVISD::MULHSU || Opcode == RISCVISD::MULHR ||
15859 Opcode == RISCVISD::MULHRU || Opcode == RISCVISD::MULHRSU;
15860 assert(VT == MVT::v2i16 || (!IsMulH && VT == MVT::v4i8));
15861 MVT NewVT = MVT::v4i16;
15862 if (VT == MVT::v4i8)
15888 assert(!Subtarget.is64Bit() &&
N->getValueType(0) == MVT::i64 &&
15890 "Unexpected EXTRACT_VECTOR_ELT legalization");
15893 MVT ContainerVT = VecVT;
15899 MVT XLenVT = Subtarget.getXLenVT();
15908 DAG.
getUNDEF(ContainerVT), Vec, Idx, Mask, VL);
15920 DAG.
getNode(RISCVISD::SRL_VL,
DL, ContainerVT, Vec, ThirtyTwoV,
15921 DAG.
getUNDEF(ContainerVT), Mask, VL);
15929 unsigned IntNo =
N->getConstantOperandVal(0);
15933 "Don't know how to custom type legalize this intrinsic!");
15934 case Intrinsic::experimental_get_vector_length: {
15939 case Intrinsic::riscv_paadd:
15940 case Intrinsic::riscv_paaddu:
15941 case Intrinsic::riscv_pasub:
15942 case Intrinsic::riscv_pasubu:
15943 case Intrinsic::riscv_pabd:
15944 case Intrinsic::riscv_pabdu:
15945 case Intrinsic::riscv_pas:
15946 case Intrinsic::riscv_psa:
15947 case Intrinsic::riscv_psas:
15948 case Intrinsic::riscv_pssa:
15949 case Intrinsic::riscv_paas:
15950 case Intrinsic::riscv_pasa:
15951 case Intrinsic::riscv_pmerge:
15952 case Intrinsic::riscv_psabs: {
15953 EVT VT =
N->getValueType(0);
15954 if (!Subtarget.is64Bit() || (VT != MVT::v4i8 && VT != MVT::v2i16))
15959 case Intrinsic::riscv_paadd:
15962 case Intrinsic::riscv_paaddu:
15965 case Intrinsic::riscv_pasub:
15966 Opc = RISCVISD::ASUB;
15968 case Intrinsic::riscv_pasubu:
15969 Opc = RISCVISD::ASUBU;
15971 case Intrinsic::riscv_pabd:
15974 case Intrinsic::riscv_pabdu:
15977 case Intrinsic::riscv_psabs:
15978 Opc = RISCVISD::PSABS;
15987 EVT WideVT = VT == MVT::v4i8 ? MVT::v8i8 : MVT::v4i16;
15991 if (
Op.getValueType() == VT)
16003 case Intrinsic::riscv_predsum:
16004 case Intrinsic::riscv_predsumu: {
16005 bool IsSigned = IntNo == Intrinsic::riscv_predsum;
16019 if (!Subtarget.is64Bit() &&
N->getValueType(0) == MVT::i64) {
16022 if (VecVT == MVT::v2i32) {
16038 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
16042 if (VecVT == MVT::v4i8 || VecVT == MVT::v2i16)
16044 DAG,
DL, Vec, VecVT == MVT::v4i8 ? MVT::v8i8 : MVT::v4i16);
16050 SDValue Res = RedSum(MVT::i64, Vec, Acc);
16054 case Intrinsic::riscv_pabdsumu:
16055 case Intrinsic::riscv_pabdsumau: {
16056 bool IsAcc = IntNo == Intrinsic::riscv_pabdsumau;
16058 SDValue Rs1 =
N->getOperand(
N->getNumOperands() - 2);
16059 SDValue Rs2 =
N->getOperand(
N->getNumOperands() - 1);
16064 if (!Subtarget.is64Bit() &&
N->getValueType(0) == MVT::i64) {
16089 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
16091 if (VecVT == MVT::v4i8) {
16099 Ops.push_back(Rs1);
16100 Ops.push_back(Rs2);
16105 case Intrinsic::riscv_orc_b:
16106 case Intrinsic::riscv_brev8:
16107 case Intrinsic::riscv_sha256sig0:
16108 case Intrinsic::riscv_sha256sig1:
16109 case Intrinsic::riscv_sha256sum0:
16110 case Intrinsic::riscv_sha256sum1:
16111 case Intrinsic::riscv_sm3p0:
16112 case Intrinsic::riscv_sm3p1: {
16113 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
16117 case Intrinsic::riscv_orc_b:
Opc = RISCVISD::ORC_B;
break;
16118 case Intrinsic::riscv_brev8:
Opc = RISCVISD::BREV8;
break;
16119 case Intrinsic::riscv_sha256sig0:
Opc = RISCVISD::SHA256SIG0;
break;
16120 case Intrinsic::riscv_sha256sig1:
Opc = RISCVISD::SHA256SIG1;
break;
16121 case Intrinsic::riscv_sha256sum0:
Opc = RISCVISD::SHA256SUM0;
break;
16122 case Intrinsic::riscv_sha256sum1:
Opc = RISCVISD::SHA256SUM1;
break;
16123 case Intrinsic::riscv_sm3p0:
Opc = RISCVISD::SM3P0;
break;
16124 case Intrinsic::riscv_sm3p1:
Opc = RISCVISD::SM3P1;
break;
16133 case Intrinsic::riscv_sm4ks:
16134 case Intrinsic::riscv_sm4ed: {
16136 IntNo == Intrinsic::riscv_sm4ks ? RISCVISD::SM4KS : RISCVISD::SM4ED;
16142 DAG.
getNode(
Opc,
DL, MVT::i64, NewOp0, NewOp1,
N->getOperand(3));
16146 case Intrinsic::riscv_mopr: {
16147 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
16152 RISCVISD::MOP_R,
DL, MVT::i64, NewOp,
16157 case Intrinsic::riscv_moprr: {
16158 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
16165 RISCVISD::MOP_RR,
DL, MVT::i64, NewOp0, NewOp1,
16170 case Intrinsic::riscv_clmulh:
16171 case Intrinsic::riscv_clmulr: {
16172 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
16200 case Intrinsic::riscv_vmv_x_s: {
16201 EVT VT =
N->getValueType(0);
16202 MVT XLenVT = Subtarget.getXLenVT();
16203 if (VT.
bitsLT(XLenVT)) {
16206 Subtarget.getXLenVT(),
N->getOperand(1));
16211 assert(VT == MVT::i64 && !Subtarget.is64Bit() &&
16212 "Unexpected custom legalization");
16228 SDValue LShr32 = DAG.
getNode(RISCVISD::SRL_VL,
DL, VecVT, Vec, ThirtyTwoV,
16250 case ISD::VP_REDUCE_ADD:
16251 case ISD::VP_REDUCE_AND:
16252 case ISD::VP_REDUCE_OR:
16253 case ISD::VP_REDUCE_XOR:
16254 case ISD::VP_REDUCE_SMAX:
16255 case ISD::VP_REDUCE_UMAX:
16256 case ISD::VP_REDUCE_SMIN:
16257 case ISD::VP_REDUCE_UMIN:
16325 const EVT VT =
N->getValueType(0);
16326 const unsigned Opc =
N->getOpcode();
16336 if (!
N->getFlags().hasAllowReassociation())
16347 "Inconsistent mappings");
16351 if (!
LHS.hasOneUse() || !
RHS.hasOneUse())
16379 if (0 == std::min(LHSIdx, RHSIdx) && 1 == std::max(LHSIdx, RHSIdx)) {
16382 return DAG.
getNode(ReduceOpc,
DL, VT, Vec,
N->getFlags());
16389 if (
LHS.getOpcode() != ReduceOpc)
16403 return DAG.
getNode(ReduceOpc,
DL, VT, Vec,
16404 ReduceVec->
getFlags() &
N->getFlags());
16414 auto BinOpToRVVReduce = [](
unsigned Opc) {
16419 return RISCVISD::VECREDUCE_ADD_VL;
16421 return RISCVISD::VECREDUCE_UMAX_VL;
16423 return RISCVISD::VECREDUCE_SMAX_VL;
16425 return RISCVISD::VECREDUCE_UMIN_VL;
16427 return RISCVISD::VECREDUCE_SMIN_VL;
16429 return RISCVISD::VECREDUCE_AND_VL;
16431 return RISCVISD::VECREDUCE_OR_VL;
16433 return RISCVISD::VECREDUCE_XOR_VL;
16435 return RISCVISD::VECREDUCE_FADD_VL;
16437 return RISCVISD::VECREDUCE_FMAX_VL;
16439 return RISCVISD::VECREDUCE_FMIN_VL;
16443 auto IsReduction = [&BinOpToRVVReduce](
SDValue V,
unsigned Opc) {
16446 V.getOperand(0).getOpcode() == BinOpToRVVReduce(
Opc);
16449 unsigned Opc =
N->getOpcode();
16450 unsigned ReduceIdx;
16451 if (IsReduction(
N->getOperand(0),
Opc))
16453 else if (IsReduction(
N->getOperand(1),
Opc))
16459 if (
Opc ==
ISD::FADD && !
N->getFlags().hasAllowReassociation())
16462 SDValue Extract =
N->getOperand(ReduceIdx);
16475 if (ScalarV.
getOpcode() != RISCVISD::VFMV_S_F_VL &&
16476 ScalarV.
getOpcode() != RISCVISD::VMV_S_X_VL &&
16477 ScalarV.
getOpcode() != RISCVISD::VMV_V_X_VL)
16494 SDValue NewStart =
N->getOperand(1 - ReduceIdx);
16527 EVT VT =
N->getValueType(0);
16543 int64_t C0 = N0C->getSExtValue();
16544 int64_t C1 = N1C->getSExtValue();
16545 if (C0 <= 0 || C1 <= 0)
16548 int64_t Diff = std::abs(C0 - C1);
16554 int64_t Bits = std::min(C0, C1);
16586 if (VShift.
slt(1) || VShift.
sgt(3))
16590 EVT VT =
N->getValueType(0);
16610 EVT VT =
N->getValueType(0);
16638 EVT VT =
N->getValueType(0);
16659 Slct.
getOpcode() != RISCVISD::SELECT_CC) ||
16667 bool SwapSelectOps;
16668 unsigned OpOffset = Slct.
getOpcode() == RISCVISD::SELECT_CC ? 2 : 0;
16673 SwapSelectOps =
false;
16674 NonConstantVal = FalseVal;
16676 SwapSelectOps =
true;
16677 NonConstantVal = TrueVal;
16683 FalseVal = DAG.
getNode(
N->getOpcode(),
SDLoc(
N), VT, OtherOp, NonConstantVal);
16688 if (Slct.
getOpcode() == RISCVISD::SELECT_CC)
16731 EVT VT =
N->getValueType(0);
16746 if (!N0C->hasOneUse())
16748 int64_t C0 = N0C->getSExtValue();
16749 int64_t C1 = N1C->getSExtValue();
16756 if (C0 == -1 || C0 == 0 || C0 == 1 ||
16764 }
else if ((C1 / C0 + 1) != 0 &&
isInt<12>(C1 / C0 + 1) &&
16768 }
else if ((C1 / C0 - 1) != 0 &&
isInt<12>(C1 / C0 - 1) &&
16796 EVT VT =
N->getValueType(0);
16827 unsigned OuterExtend =
16831 OuterExtend,
SDLoc(
N), VT,
16839 EVT VT =
N->getValueType(0);
16873 EVT VT =
N->getValueType(0);
16875 bool IsPExtPackedDoubleType =
16878 !(Subtarget.hasStdExtP() && !Subtarget.
is64Bit() && VT == MVT::v4i8))
16903 if (IsPExtPackedDoubleType) {
16908 if (HalfVT == MVT::v4i8) {
16909 ResLo = MakePWMulSU(XLo, CLo);
16910 ResHi = MakePWMulSU(XHi, CHi);
16912 ResLo = DAG.
getNode(RISCVISD::MULHSU,
DL, HalfVT, XLo, CLo);
16913 ResHi = DAG.
getNode(RISCVISD::MULHSU,
DL, HalfVT, XHi, CHi);
16918 if (Subtarget.hasStdExtP() && !Subtarget.
is64Bit() && VT == MVT::v4i8)
16956 EVT VT =
N->getValueType(0);
16966 APInt ImmValMinus1 = N0C->getAPIntValue() - 1;
16976 if (!isIntEqualitySetCC(CCVal) || !SetCCOpVT.
isInteger())
16999 if (!Subtarget.hasStdExtZbb())
17002 EVT VT =
N->getValueType(0);
17004 if (VT != Subtarget.
getXLenVT() && VT != MVT::i32 && VT != MVT::i16)
17016 unsigned ShiftedAmount = 8 - ShAmtCLeft->getZExtValue();
17018 if (ShiftedAmount >= 8)
17022 SDValue RightShiftOperand = N1;
17024 if (ShiftedAmount != 0) {
17028 if (!ShAmtCRight || ShAmtCRight->getZExtValue() != ShiftedAmount)
17037 if (LeftShiftOperand != RightShiftOperand)
17041 Mask <<= ShiftedAmount;
17047 return DAG.
getNode(RISCVISD::ORC_B,
SDLoc(
N), VT, LeftShiftOperand);
17055 EVT VT =
N->getValueType(0);
17087 bool IsAnd =
N->getOpcode() ==
ISD::AND;
17111 EVT VT =
N->getValueType(0);
17135 EVT VT =
N->getValueType(0);
17162 if (CondLHS != True)
17169 if (!CondRHSC || CondRHSC->
getAPIntValue() != (1ULL << ScalarBits))
17181 if (!FalseRHSC || !FalseRHSC->
isZero())
17206 EVT VT =
N->getValueType(0);
17210 if (VT != MVT::v4i16 && VT != MVT::v2i16 && VT != MVT::v8i8 &&
17211 VT != MVT::v4i8 && VT != MVT::v2i32 && VT != MVT::i32)
17219 unsigned ShAmtVal =
C->getZExtValue();
17223 bool IsRounding =
false;
17224 if (
Op.getOpcode() ==
ISD::ADD && (EltBits == 16 || EltBits == 32)) {
17226 if (RndC && RndC->
getZExtValue() == (1ULL << (EltBits - 1)) &&
17228 Op =
Op.getOperand(0);
17234 if (
Op.getNumOperands() != 2)
17245 if (!(LHSIsSExt || LHSIsZExt) || !(RHSIsSExt || RHSIsZExt))
17251 if (
A.getValueType() != VT ||
B.getValueType() != VT)
17255 switch (
Op.getOpcode()) {
17262 if (LHSIsSExt && RHSIsSExt)
17263 Opc = RISCVISD::ASUB;
17264 else if (LHSIsZExt && RHSIsZExt)
17265 Opc = RISCVISD::ASUBU;
17271 if (ShAmtVal != EltBits || (EltBits != 16 && EltBits != 32))
17273 if (!Subtarget.
is64Bit() && (VT == MVT::v2i32 || VT == MVT::v4i16))
17276 if (LHSIsSExt && RHSIsSExt) {
17277 Opc = RISCVISD::MULHR;
17278 }
else if (LHSIsZExt && RHSIsZExt) {
17279 Opc = RISCVISD::MULHRU;
17280 }
else if ((LHSIsSExt && RHSIsZExt) || (LHSIsZExt && RHSIsSExt)) {
17281 Opc = RISCVISD::MULHRSU;
17283 if (LHSIsZExt && RHSIsSExt)
17292 if ((LHSIsSExt && RHSIsZExt) || (LHSIsZExt && RHSIsSExt)) {
17293 Opc = RISCVISD::MULHSU;
17295 if (LHSIsZExt && RHSIsSExt)
17309 EVT VT =
N->getValueType(0);
17312 if (Subtarget.hasStdExtP() &&
17321 if (Subtarget.
is64Bit() && Subtarget.hasStdExtZbs() && VT == MVT::i1 &&
17364 EVT VT =
N->getValueType(0);
17383 EVT WideVT =
X.getValueType();
17410 auto IsEqualCompZero = [](
SDValue &V) ->
bool {
17419 if (!IsEqualCompZero(N0) || !N0.
hasOneUse())
17421 if (!IsEqualCompZero(N0) || !N0.
hasOneUse())
17425 if (
Known.getMaxValue().ugt(1))
17428 unsigned CzeroOpcode =
17430 ? RISCVISD::CZERO_EQZ
17431 : RISCVISD::CZERO_NEZ;
17433 EVT VT =
N->getValueType(0);
17460 if (Mask != ExpectedMask)
17477 EVT VT =
N->getValueType(0);
17483 APInt MaskVal, ShiftVal;
17498 APInt InnerMask = MaskVal.
lshr(ShiftAmt);
17499 bool IsNarrowable =
17500 InnerMask == 0xff || InnerMask == 0xffff || InnerMask == 0xffffffff;
17528 if (Subtarget.
is64Bit() && Subtarget.hasStdExtZbs() &&
17570 if (N0.
getOpcode() != RISCVISD::CZERO_EQZ ||
17571 N1.
getOpcode() != RISCVISD::CZERO_NEZ ||
17589 EVT VT =
N->getValueType(0);
17607 if (!Subtarget.hasVendorXqcibm())
17619 if (
N->getValueType(0) != MVT::i32)
17621 unsigned Width, ShAmt;
17638 return DAG.
getNode(RISCVISD::QC_INSB,
DL, MVT::i32,
Ops);
17643 if (!Subtarget.hasVendorXqcibm())
17653 unsigned ShAmt, Width;
17657 if (
N->getValueType(0) != MVT::i32)
17662 if (Width == 1 && Subtarget.hasStdExtZbs())
17674 return DAG.
getNode(RISCVISD::QC_INSB,
DL, MVT::i32,
Ops);
17682 if (!Subtarget.hasVendorXqcibm())
17688 APInt MaskImm, OrImm;
17707 unsigned ShAmt, Width;
17709 if (!
Known.Zero.isShiftedMask(ShAmt, Width))
17720 return DAG.
getNode(RISCVISD::QC_INSB,
DL, MVT::i32,
Ops);
17763 if (Subtarget.
is64Bit() && Subtarget.hasStdExtZbs() &&
17778 if (N0.
getOpcode() == RISCVISD::SLLW &&
17782 return DAG.
getNode(RISCVISD::ROLW,
DL, MVT::i64,
17793 const APInt &Imm = ConstN00->getAPIntValue();
17794 if ((Imm + 1).isSignedIntN(12))
17818 EVT VT =
N->getValueType(0);
17827 bool IsAdd = (
E & 3) == 1;
17828 E -= IsAdd ? 1 : -1;
17832 Result = DAG.
getNode(AddSubOp,
DL, VT, Result, ShiftVal);
17842 uint64_t MulAmtLowBit = MulAmt & (-MulAmt);
17847 auto PreferSub = [
X, MulAmtLowBit]() {
17856 if (
isPowerOf2_64(MulAmt - MulAmtLowBit) && !(CanSub && PreferSub())) {
17858 ShiftAmt1 = MulAmt - MulAmtLowBit;
17859 }
else if (CanSub) {
17861 ShiftAmt1 = MulAmt + MulAmtLowBit;
17865 EVT VT =
N->getValueType(0);
17875 unsigned ShY,
bool AddX,
unsigned Shift) {
17877 EVT VT =
N->getValueType(0);
17892 ShlAdd = DAG.
getNode(RISCVISD::SHL_ADD,
DL, VT, ShlAdd,
17902 uint64_t MulAmt,
unsigned Shift) {
17928 assert(ShX != 0 &&
"MulAmt=4,6,10 handled before");
17935 EVT VT =
N->getValueType(0);
17952 EVT VT =
N->getValueType(0);
17961 bool ShouldExpandMul =
17963 !Subtarget.hasStdExtZmmul();
17964 if (!ShouldExpandMul)
17994 if (Shift >= 1 && Shift <= 3 &&
isPowerOf2_64(MulAmt & (MulAmt - 1))) {
17999 return DAG.
getNode(RISCVISD::SHL_ADD,
DL, VT,
X,
18006 if (MulAmt > 2 &&
isPowerOf2_64((MulAmt - 1) & (MulAmt - 2))) {
18008 if (ScaleShift >= 1 && ScaleShift < 4) {
18040 if (!Subtarget.hasStdExtZmmul())
18050 EVT VT =
N->getValueType(0);
18057 if (
N->getOperand(0).getOpcode() !=
ISD::AND ||
18058 N->getOperand(0).getOperand(0).getOpcode() !=
ISD::SRL)
18071 if (!
V1.isMask(HalfSize) || V2 != (1ULL | 1ULL << HalfSize) ||
18072 V3 != (HalfSize - 1))
18088 EVT VT =
N->getValueType(0);
18096 unsigned AddSubOpc;
18102 auto IsAddSubWith1 = [&](
SDValue V) ->
bool {
18103 AddSubOpc = V->getOpcode();
18115 if (IsAddSubWith1(N0)) {
18117 return DAG.
getNode(AddSubOpc,
DL, VT, N1, MulVal);
18120 if (IsAddSubWith1(N1)) {
18122 return DAG.
getNode(AddSubOpc,
DL, VT, N0, MulVal);
18137 if (isIndexTypeSigned(IndexType))
18140 if (!
N->hasOneUse())
18143 EVT VT =
N.getValueType();
18155 unsigned ActiveBits = std::max(8u,
Known.countMaxActiveBits());
18182 EVT SrcVT = Src.getValueType();
18190 NewElen = std::max(NewElen, 8U);
18219 EVT OpVT =
X.getValueType();
18227 if (OpSize <= Subtarget.
getXLen() ||
18233 auto IsVectorBitCastCheap = [](
SDValue X) {
18238 if (!IsVectorBitCastCheap(
X) || !IsVectorBitCastCheap(
Y))
18242 Attribute::NoImplicitFloat))
18250 auto GetPreferredEltVT = [](
SDValue V) ->
MVT {
18265 if (
Use.getResNo() != V.getResNo())
18270 EVT CastVT =
User->getValueType(0);
18281 auto IsValidEltVT = [&](
MVT VT) {
18288 if (OpSize % EltSize != 0)
18292 unsigned NumElts = OpSize / EltSize;
18298 MVT EltVT = GetPreferredEltVT(
X);
18299 if (!IsValidEltVT(EltVT))
18300 EltVT = GetPreferredEltVT(
Y);
18303 if (!IsValidEltVT(EltVT))
18307 unsigned NumElts = OpSize / EltSize;
18332 EVT VT =
N->getValueType(0);
18337 if (!isIntEqualitySetCC(
Cond))
18362 if (OpVT == MVT::i64 &&
isUInt<32>(AndRHSInt) &&
18366 if (NewC >= -2048 && NewC <= 2048) {
18372 return DAG.
getSetCC(dl, VT, Shift,
18383 if (N1Width <= TrailingOnes &&
isInt<12>(N1SExt) &&
18394 if (OpVT != MVT::i64 || !Subtarget.
is64Bit())
18414 const APInt &C1 = N1C->getAPIntValue();
18432 EVT VT =
N->getValueType(0);
18434 unsigned Opc = Src.getOpcode();
18439 if (
Opc == RISCVISD::FMV_X_ANYEXTH && SrcVT.
bitsGE(MVT::i16) &&
18440 Subtarget.hasStdExtZfhmin())
18441 return DAG.
getNode(RISCVISD::FMV_X_SIGNEXTH,
DL, VT, Src.getOperand(0));
18447 return DAG.
getNode(RISCVISD::SLLW,
DL, VT, Src.getOperand(0),
18448 Src.getOperand(1));
18467struct CombineResult;
18469enum ExtKind : uint8_t {
18501struct NodeExtensionHelper {
18510 bool SupportsFPExt;
18512 bool SupportsBF16Ext;
18515 bool EnforceOneUse;
18525 case RISCVISD::VSEXT_VL:
18526 case RISCVISD::VZEXT_VL:
18527 case RISCVISD::FP_EXTEND_VL:
18530 return OrigOperand;
18536 return OrigOperand.
getOpcode() == RISCVISD::VMV_V_X_VL ||
18541 unsigned getExtOpc(ExtKind SupportsExt)
const {
18542 switch (SupportsExt) {
18543 case ExtKind::SExt:
18544 return RISCVISD::VSEXT_VL;
18545 case ExtKind::ZExt:
18546 return RISCVISD::VZEXT_VL;
18547 case ExtKind::FPExt:
18548 case ExtKind::BF16Ext:
18549 return RISCVISD::FP_EXTEND_VL;
18557 SDValue getOrCreateExtendedOp(SDNode *Root, SelectionDAG &DAG,
18558 const RISCVSubtarget &Subtarget,
18559 std::optional<ExtKind> SupportsExt)
const {
18560 if (!SupportsExt.has_value())
18561 return OrigOperand;
18563 MVT NarrowVT = getNarrowType(Root, *SupportsExt);
18567 if (
Source.getValueType() == NarrowVT)
18570 unsigned ExtOpc = getExtOpc(*SupportsExt);
18573 SDLoc
DL(OrigOperand);
18574 auto [
Mask, VL] = getMaskAndVL(Root, DAG, Subtarget);
18578 case RISCVISD::VSEXT_VL:
18579 case RISCVISD::VZEXT_VL:
18580 case RISCVISD::FP_EXTEND_VL:
18581 return DAG.
getNode(ExtOpc,
DL, NarrowVT, Source, Mask, VL);
18584 case RISCVISD::VMV_V_X_VL:
18585 return DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, NarrowVT,
18587 case RISCVISD::VFMV_V_F_VL:
18592 return DAG.
getNode(RISCVISD::VFMV_V_F_VL,
DL, NarrowVT,
18593 DAG.
getUNDEF(NarrowVT), Source, VL);
18606 static MVT getNarrowType(
const SDNode *Root, ExtKind SupportsExt) {
18612 MVT EltVT = SupportsExt == ExtKind::BF16Ext ? MVT::bf16
18613 : SupportsExt == ExtKind::FPExt
18615 : MVT::getIntegerVT(NarrowSize);
18617 assert((
int)NarrowSize >= (SupportsExt == ExtKind::FPExt ? 16 : 8) &&
18618 "Trying to extend something we can't represent");
18625 static unsigned getSExtOpcode(
unsigned Opcode) {
18628 case RISCVISD::ADD_VL:
18629 case RISCVISD::VWADD_W_VL:
18630 case RISCVISD::VWADDU_W_VL:
18632 case RISCVISD::OR_VL:
18633 return RISCVISD::VWADD_VL;
18635 case RISCVISD::SUB_VL:
18636 case RISCVISD::VWSUB_W_VL:
18637 case RISCVISD::VWSUBU_W_VL:
18638 return RISCVISD::VWSUB_VL;
18640 case RISCVISD::MUL_VL:
18641 return RISCVISD::VWMUL_VL;
18649 static unsigned getZExtOpcode(
unsigned Opcode) {
18652 case RISCVISD::ADD_VL:
18653 case RISCVISD::VWADD_W_VL:
18654 case RISCVISD::VWADDU_W_VL:
18656 case RISCVISD::OR_VL:
18657 return RISCVISD::VWADDU_VL;
18659 case RISCVISD::SUB_VL:
18660 case RISCVISD::VWSUB_W_VL:
18661 case RISCVISD::VWSUBU_W_VL:
18662 return RISCVISD::VWSUBU_VL;
18664 case RISCVISD::MUL_VL:
18665 return RISCVISD::VWMULU_VL;
18667 case RISCVISD::SHL_VL:
18668 return RISCVISD::VWSLL_VL;
18676 static unsigned getFPExtOpcode(
unsigned Opcode) {
18678 case RISCVISD::FADD_VL:
18679 case RISCVISD::VFWADD_W_VL:
18680 return RISCVISD::VFWADD_VL;
18681 case RISCVISD::FSUB_VL:
18682 case RISCVISD::VFWSUB_W_VL:
18683 return RISCVISD::VFWSUB_VL;
18684 case RISCVISD::FMUL_VL:
18685 return RISCVISD::VFWMUL_VL;
18686 case RISCVISD::VFMADD_VL:
18687 return RISCVISD::VFWMADD_VL;
18688 case RISCVISD::VFMSUB_VL:
18689 return RISCVISD::VFWMSUB_VL;
18690 case RISCVISD::VFNMADD_VL:
18691 return RISCVISD::VFWNMADD_VL;
18692 case RISCVISD::VFNMSUB_VL:
18693 return RISCVISD::VFWNMSUB_VL;
18701 static unsigned getSUOpcode(
unsigned Opcode) {
18703 "SU is only supported for MUL");
18704 return RISCVISD::VWMULSU_VL;
18709 static unsigned getWOpcode(
unsigned Opcode, ExtKind SupportsExt) {
18712 case RISCVISD::ADD_VL:
18714 case RISCVISD::OR_VL:
18715 return SupportsExt == ExtKind::SExt ? RISCVISD::VWADD_W_VL
18716 : RISCVISD::VWADDU_W_VL;
18718 case RISCVISD::SUB_VL:
18719 return SupportsExt == ExtKind::SExt ? RISCVISD::VWSUB_W_VL
18720 : RISCVISD::VWSUBU_W_VL;
18721 case RISCVISD::FADD_VL:
18722 return RISCVISD::VFWADD_W_VL;
18723 case RISCVISD::FSUB_VL:
18724 return RISCVISD::VFWSUB_W_VL;
18730 using CombineToTry = std::function<std::optional<CombineResult>(
18731 SDNode * ,
const NodeExtensionHelper & ,
18732 const NodeExtensionHelper & , SelectionDAG &,
18733 const RISCVSubtarget &)>;
18736 bool needToPromoteOtherUsers()
const {
return EnforceOneUse; }
18738 void fillUpExtensionSupportForSplat(SDNode *Root, SelectionDAG &DAG,
18739 const RISCVSubtarget &Subtarget) {
18744 "Unexpected Opcode");
18757 unsigned ScalarBits =
Op.getValueSizeInBits();
18759 if (ScalarBits < EltBits) {
18761 assert(
Opc == RISCVISD::VMV_V_X_VL && EltBits == 64 && ScalarBits == 32 &&
18762 !Subtarget.
is64Bit() &&
"Unexpected splat");
18764 SupportsSExt =
true;
18768 SupportsZExt =
true;
18770 EnforceOneUse =
false;
18774 unsigned NarrowSize = EltBits / 2;
18777 if (NarrowSize < 8)
18781 SupportsSExt =
true;
18785 SupportsZExt =
true;
18787 EnforceOneUse =
false;
18790 bool isSupportedFPExtend(MVT NarrowEltVT,
const RISCVSubtarget &Subtarget) {
18791 return (NarrowEltVT == MVT::f32 ||
18795 bool isSupportedBF16Extend(MVT NarrowEltVT,
const RISCVSubtarget &Subtarget) {
18796 return NarrowEltVT == MVT::bf16 &&
18802 void fillUpExtensionSupport(SDNode *Root, SelectionDAG &DAG,
18803 const RISCVSubtarget &Subtarget) {
18804 SupportsZExt =
false;
18805 SupportsSExt =
false;
18806 SupportsFPExt =
false;
18807 SupportsBF16Ext =
false;
18808 EnforceOneUse =
true;
18830 case RISCVISD::VZEXT_VL:
18831 SupportsZExt =
true;
18833 case RISCVISD::VSEXT_VL:
18834 SupportsSExt =
true;
18836 case RISCVISD::FP_EXTEND_VL: {
18839 if (isSupportedFPExtend(NarrowEltVT, Subtarget))
18840 SupportsFPExt =
true;
18841 if (isSupportedBF16Extend(NarrowEltVT, Subtarget))
18842 SupportsBF16Ext =
true;
18847 case RISCVISD::VMV_V_X_VL:
18848 fillUpExtensionSupportForSplat(Root, DAG, Subtarget);
18850 case RISCVISD::VFMV_V_F_VL: {
18861 unsigned ScalarBits =
Op.getOperand(0).getValueSizeInBits();
18862 if (NarrowSize != ScalarBits)
18865 if (isSupportedFPExtend(
Op.getOperand(0).getSimpleValueType(), Subtarget))
18866 SupportsFPExt =
true;
18867 if (isSupportedBF16Extend(
Op.getOperand(0).getSimpleValueType(),
18869 SupportsBF16Ext =
true;
18878 static bool isSupportedRoot(
const SDNode *Root,
18879 const RISCVSubtarget &Subtarget) {
18891 case RISCVISD::ADD_VL:
18892 case RISCVISD::MUL_VL:
18893 case RISCVISD::VWADD_W_VL:
18894 case RISCVISD::VWADDU_W_VL:
18895 case RISCVISD::SUB_VL:
18896 case RISCVISD::VWSUB_W_VL:
18897 case RISCVISD::VWSUBU_W_VL:
18899 case RISCVISD::FADD_VL:
18900 case RISCVISD::FSUB_VL:
18901 case RISCVISD::FMUL_VL:
18902 case RISCVISD::VFWADD_W_VL:
18903 case RISCVISD::VFWSUB_W_VL:
18905 case RISCVISD::OR_VL:
18909 Subtarget.hasStdExtZvbb();
18910 case RISCVISD::SHL_VL:
18911 return Subtarget.hasStdExtZvbb();
18912 case RISCVISD::VFMADD_VL:
18913 case RISCVISD::VFNMSUB_VL:
18914 case RISCVISD::VFNMADD_VL:
18915 case RISCVISD::VFMSUB_VL:
18923 NodeExtensionHelper(SDNode *Root,
unsigned OperandIdx, SelectionDAG &DAG,
18924 const RISCVSubtarget &Subtarget) {
18925 assert(isSupportedRoot(Root, Subtarget) &&
18926 "Trying to build an helper with an "
18927 "unsupported root");
18928 assert(OperandIdx < 2 &&
"Requesting something else than LHS or RHS");
18938 case RISCVISD::VWADD_W_VL:
18939 case RISCVISD::VWADDU_W_VL:
18940 case RISCVISD::VWSUB_W_VL:
18941 case RISCVISD::VWSUBU_W_VL:
18942 case RISCVISD::VFWADD_W_VL:
18943 case RISCVISD::VFWSUB_W_VL:
18945 if (OperandIdx == 1)
18949 fillUpExtensionSupport(Root, DAG, Subtarget);
18955 static std::pair<SDValue, SDValue>
18956 getMaskAndVL(
const SDNode *Root, SelectionDAG &DAG,
18957 const RISCVSubtarget &Subtarget) {
18958 assert(isSupportedRoot(Root, Subtarget) &&
"Unexpected root");
18977 switch (
N->getOpcode()) {
18981 case RISCVISD::ADD_VL:
18982 case RISCVISD::MUL_VL:
18983 case RISCVISD::OR_VL:
18984 case RISCVISD::FADD_VL:
18985 case RISCVISD::FMUL_VL:
18986 case RISCVISD::VFMADD_VL:
18987 case RISCVISD::VFNMSUB_VL:
18988 case RISCVISD::VFNMADD_VL:
18989 case RISCVISD::VFMSUB_VL:
18991 case RISCVISD::VWADD_W_VL:
18992 case RISCVISD::VWADDU_W_VL:
18994 case RISCVISD::SUB_VL:
18995 case RISCVISD::VWSUB_W_VL:
18996 case RISCVISD::VWSUBU_W_VL:
18997 case RISCVISD::VFWADD_W_VL:
18998 case RISCVISD::FSUB_VL:
18999 case RISCVISD::VFWSUB_W_VL:
19001 case RISCVISD::SHL_VL:
19016 getSupportedFoldings(
const SDNode *Root,
const RISCVSubtarget &Subtarget);
19021struct CombineResult {
19023 unsigned TargetOpcode;
19025 std::optional<ExtKind> LHSExt;
19026 std::optional<ExtKind> RHSExt;
19030 NodeExtensionHelper
LHS;
19032 NodeExtensionHelper
RHS;
19034 CombineResult(
unsigned TargetOpcode, SDNode *Root,
19035 const NodeExtensionHelper &
LHS, std::optional<ExtKind> LHSExt,
19036 const NodeExtensionHelper &
RHS, std::optional<ExtKind> RHSExt)
19037 : TargetOpcode(TargetOpcode), LHSExt(LHSExt), RHSExt(RHSExt), Root(Root),
19043 SDValue materialize(SelectionDAG &DAG,
19044 const RISCVSubtarget &Subtarget)
const {
19046 std::tie(Mask, VL) =
19047 NodeExtensionHelper::getMaskAndVL(Root, DAG, Subtarget);
19061 LHS.getOrCreateExtendedOp(Root, DAG, Subtarget, LHSExt),
19062 RHS.getOrCreateExtendedOp(Root, DAG, Subtarget, RHSExt),
19063 Passthru, Mask, VL);
19077static std::optional<CombineResult>
19078canFoldToVWWithSameExtensionImpl(
SDNode *Root,
const NodeExtensionHelper &
LHS,
19079 const NodeExtensionHelper &
RHS,
19082 if ((AllowExtMask & ExtKind::ZExt) &&
LHS.SupportsZExt &&
RHS.SupportsZExt)
19083 return CombineResult(NodeExtensionHelper::getZExtOpcode(Root->
getOpcode()),
19084 Root,
LHS, {ExtKind::ZExt},
RHS,
19086 if ((AllowExtMask & ExtKind::SExt) &&
LHS.SupportsSExt &&
RHS.SupportsSExt)
19087 return CombineResult(NodeExtensionHelper::getSExtOpcode(Root->
getOpcode()),
19088 Root,
LHS, {ExtKind::SExt},
RHS,
19090 if ((AllowExtMask & ExtKind::FPExt) &&
LHS.SupportsFPExt &&
RHS.SupportsFPExt)
19091 return CombineResult(NodeExtensionHelper::getFPExtOpcode(Root->
getOpcode()),
19092 Root,
LHS, {ExtKind::FPExt},
RHS,
19094 if ((AllowExtMask & ExtKind::BF16Ext) &&
LHS.SupportsBF16Ext &&
19095 RHS.SupportsBF16Ext)
19096 return CombineResult(NodeExtensionHelper::getFPExtOpcode(Root->
getOpcode()),
19097 Root,
LHS, {ExtKind::BF16Ext},
RHS,
19098 {ExtKind::BF16Ext});
19099 return std::nullopt;
19108static std::optional<CombineResult>
19109canFoldToVWWithSameExtension(
SDNode *Root,
const NodeExtensionHelper &
LHS,
19112 return canFoldToVWWithSameExtensionImpl(
19113 Root,
LHS,
RHS, ExtKind::ZExt | ExtKind::SExt | ExtKind::FPExt, DAG,
19121static std::optional<CombineResult>
19122canFoldToVWWithSameExtZEXT(
SDNode *Root,
const NodeExtensionHelper &
LHS,
19125 return canFoldToVWWithSameExtensionImpl(Root,
LHS,
RHS, ExtKind::ZExt, DAG,
19133static std::optional<CombineResult>
19134canFoldToVWWithSameExtBF16(
SDNode *Root,
const NodeExtensionHelper &
LHS,
19137 return canFoldToVWWithSameExtensionImpl(Root,
LHS,
RHS, ExtKind::BF16Ext, DAG,
19145static std::optional<CombineResult>
19146canFoldToVW_W(
SDNode *Root,
const NodeExtensionHelper &
LHS,
19149 if (
RHS.SupportsFPExt)
19150 return CombineResult(
19151 NodeExtensionHelper::getWOpcode(Root->
getOpcode(), ExtKind::FPExt),
19152 Root,
LHS, std::nullopt,
RHS, {ExtKind::FPExt});
19159 return CombineResult(
19160 NodeExtensionHelper::getWOpcode(Root->
getOpcode(), ExtKind::ZExt), Root,
19161 LHS, std::nullopt,
RHS, {ExtKind::ZExt});
19163 return CombineResult(
19164 NodeExtensionHelper::getWOpcode(Root->
getOpcode(), ExtKind::SExt), Root,
19165 LHS, std::nullopt,
RHS, {ExtKind::SExt});
19166 return std::nullopt;
19173static std::optional<CombineResult>
19174canFoldToVWWithSEXT(
SDNode *Root,
const NodeExtensionHelper &
LHS,
19177 if (
LHS.SupportsSExt)
19178 return CombineResult(NodeExtensionHelper::getSExtOpcode(Root->
getOpcode()),
19179 Root,
LHS, {ExtKind::SExt},
RHS,
19181 return std::nullopt;
19188static std::optional<CombineResult>
19189canFoldToVWWithZEXT(
SDNode *Root,
const NodeExtensionHelper &
LHS,
19192 if (
LHS.SupportsZExt)
19193 return CombineResult(NodeExtensionHelper::getZExtOpcode(Root->
getOpcode()),
19194 Root,
LHS, {ExtKind::ZExt},
RHS,
19196 return std::nullopt;
19203static std::optional<CombineResult>
19204canFoldToVWWithFPEXT(
SDNode *Root,
const NodeExtensionHelper &
LHS,
19207 if (
LHS.SupportsFPExt)
19208 return CombineResult(NodeExtensionHelper::getFPExtOpcode(Root->
getOpcode()),
19209 Root,
LHS, {ExtKind::FPExt},
RHS,
19211 return std::nullopt;
19218static std::optional<CombineResult>
19219canFoldToVW_SU(
SDNode *Root,
const NodeExtensionHelper &
LHS,
19223 if (!
LHS.SupportsSExt || !
RHS.SupportsZExt)
19224 return std::nullopt;
19225 return CombineResult(NodeExtensionHelper::getSUOpcode(Root->
getOpcode()),
19226 Root,
LHS, {ExtKind::SExt},
RHS,
19231NodeExtensionHelper::getSupportedFoldings(
const SDNode *Root,
19238 case RISCVISD::ADD_VL:
19239 case RISCVISD::SUB_VL:
19240 case RISCVISD::OR_VL:
19241 case RISCVISD::FADD_VL:
19242 case RISCVISD::FSUB_VL:
19244 Strategies.
push_back(canFoldToVWWithSameExtension);
19246 Strategies.
push_back(canFoldToVWWithSameExtBF16);
19250 case RISCVISD::FMUL_VL:
19251 case RISCVISD::VFMADD_VL:
19252 case RISCVISD::VFMSUB_VL:
19253 case RISCVISD::VFNMADD_VL:
19254 case RISCVISD::VFNMSUB_VL:
19255 Strategies.
push_back(canFoldToVWWithSameExtension);
19257 (Subtarget.hasStdExtZvfbfwma() &&
19258 Root->
getOpcode() == RISCVISD::VFMADD_VL))
19259 Strategies.
push_back(canFoldToVWWithSameExtBF16);
19262 case RISCVISD::MUL_VL:
19264 Strategies.
push_back(canFoldToVWWithSameExtension);
19269 case RISCVISD::SHL_VL:
19271 Strategies.
push_back(canFoldToVWWithSameExtZEXT);
19273 case RISCVISD::VWADD_W_VL:
19274 case RISCVISD::VWSUB_W_VL:
19276 Strategies.
push_back(canFoldToVWWithSEXT);
19278 case RISCVISD::VWADDU_W_VL:
19279 case RISCVISD::VWSUBU_W_VL:
19281 Strategies.
push_back(canFoldToVWWithZEXT);
19283 case RISCVISD::VFWADD_W_VL:
19284 case RISCVISD::VFWSUB_W_VL:
19286 Strategies.
push_back(canFoldToVWWithFPEXT);
19297 assert(
N->getOpcode() == RISCVISD::ADD_VL);
19300 SDValue Passthru =
N->getOperand(2);
19334 if (!NodeExtensionHelper::isSupportedRoot(
N, Subtarget))
19341 Inserted.insert(
N);
19344 while (!Worklist.
empty()) {
19347 NodeExtensionHelper
LHS(Root, 0, DAG, Subtarget);
19348 NodeExtensionHelper
RHS(Root, 1, DAG, Subtarget);
19349 auto AppendUsersIfNeeded =
19350 [&Worklist, &Subtarget, &Inserted,
19351 &ExtensionsToRemove](
const NodeExtensionHelper &
Op) {
19352 if (
Op.needToPromoteOtherUsers()) {
19354 ExtensionsToRemove.
insert(
Op.OrigOperand.getNode());
19357 if (!NodeExtensionHelper::isSupportedRoot(TheUser, Subtarget))
19362 if (Inserted.insert(TheUser).second)
19375 NodeExtensionHelper::getSupportedFoldings(Root, Subtarget);
19377 assert(!FoldingStrategies.
empty() &&
"Nothing to be folded");
19378 bool Matched =
false;
19379 for (
int Attempt = 0;
19380 (Attempt != 1 + NodeExtensionHelper::isCommutative(Root)) && !Matched;
19383 for (NodeExtensionHelper::CombineToTry FoldingStrategy :
19384 FoldingStrategies) {
19385 std::optional<CombineResult> Res =
19386 FoldingStrategy(Root,
LHS,
RHS, DAG, Subtarget);
19390 if (!Res->LHSExt.has_value() &&
19391 ExtensionsToRemove.
contains(
LHS.OrigOperand.getNode()))
19393 if (!Res->RHSExt.has_value() &&
19394 ExtensionsToRemove.
contains(
RHS.OrigOperand.getNode()))
19402 if (Res->LHSExt.has_value())
19403 if (!AppendUsersIfNeeded(
LHS))
19405 if (Res->RHSExt.has_value())
19406 if (!AppendUsersIfNeeded(
RHS))
19418 SDValue InputRootReplacement;
19425 for (CombineResult Res : CombinesToApply) {
19426 SDValue NewValue = Res.materialize(DAG, Subtarget);
19427 if (!InputRootReplacement) {
19429 "First element is expected to be the current node");
19430 InputRootReplacement = NewValue;
19435 for (std::pair<SDValue, SDValue> OldNewValues : ValuesToReplace) {
19436 DCI.
CombineTo(OldNewValues.first.getNode(), OldNewValues.second);
19438 return InputRootReplacement;
19445 unsigned Opc =
N->getOpcode();
19446 assert(
Opc == RISCVISD::VWADD_W_VL ||
Opc == RISCVISD::VWADDU_W_VL ||
19447 Opc == RISCVISD::VWSUB_W_VL ||
Opc == RISCVISD::VWSUBU_W_VL);
19450 SDValue MergeOp =
N->getOperand(1);
19451 unsigned MergeOpc = MergeOp.
getOpcode();
19453 if (MergeOpc != RISCVISD::VMERGE_VL && MergeOpc !=
ISD::VSELECT)
19462 SDValue Passthru =
N->getOperand(2);
19468 if (Mask.getOpcode() != RISCVISD::VMSET_VL)
19476 Z = Z.getOperand(1);
19482 {Y, X, Y, MergeOp->getOperand(0), N->getOperand(4)},
19490 if (!Subtarget.hasStdExtZvabd())
19493 MVT VT =
N->getSimpleValueType(0);
19500 SDValue Passthru =
N->getOperand(2);
19507 if (
Op->getOpcode() != RISCVISD::ABDS_VL &&
19508 Op->getOpcode() != RISCVISD::ABDU_VL)
19514 Diff = Diff ? Diff : IsABD(Op1);
19517 SDValue Acc = Diff == Op0 ? Op1 : Op0;
19520 Acc = DAG.
getNode(RISCVISD::VZEXT_VL,
DL, VT, Acc, Mask, VL);
19522 Diff.
getOpcode() == RISCVISD::ABDS_VL ? RISCVISD::VWABDA_VL
19523 : RISCVISD::VWABDAU_VL,
19534 if (!Subtarget.hasStdExtZvabd())
19537 MVT VT =
N->getSimpleValueType(0);
19545 SDValue Passthru =
N->getOperand(2);
19551 unsigned ExtOpc = 0;
19554 unsigned Opc =
Op.getOpcode();
19555 if (
Opc == RISCVISD::VZEXT_VL) {
19557 unsigned SrcOpc = Src.getOpcode();
19562 case RISCVISD::ABDS_VL:
19563 ExtOpc = RISCVISD::VSEXT_VL;
19566 case RISCVISD::ABDU_VL:
19567 ExtOpc = RISCVISD::VZEXT_VL;
19570 ExtVT =
Op->getSimpleValueType(0);
19575 Opc != RISCVISD::ABDU_VL)
19583 Diff = GetDiff(Op0);
19593 DiffA = DAG.
getNode(ExtOpc,
DL, ExtVT, DiffA, Mask, VL);
19594 DiffB = DAG.
getNode(ExtOpc,
DL, ExtVT, DiffB, Mask, VL);
19598 ? RISCVISD::VWABDA_VL
19599 : RISCVISD::VWABDAU_VL,
19600 DL, VT, DiffA, DiffB, Acc, Mask, VL);
19607 [[maybe_unused]]
unsigned Opc =
N->getOpcode();
19608 assert(
Opc == RISCVISD::VWADD_W_VL ||
Opc == RISCVISD::VWADDU_W_VL ||
19609 Opc == RISCVISD::VWSUB_W_VL ||
Opc == RISCVISD::VWSUBU_W_VL);
19636 EVT NewMemVT = (MemVT == MVT::i32) ? MVT::i64 : MVT::i128;
19644 if (MemVT == MVT::i32)
19645 Opcode = (Ext ==
ISD::ZEXTLOAD) ? RISCVISD::TH_LWUD : RISCVISD::TH_LWD;
19647 Opcode = RISCVISD::TH_LDD;
19650 Opcode,
SDLoc(LSNode1), DAG.
getVTList({XLenVT, XLenVT, MVT::Other}),
19651 {LSNode1->getChain(), BasePtr,
19652 DAG.getConstant(Imm, SDLoc(LSNode1), XLenVT)},
19663 unsigned Opcode = (MemVT == MVT::i32) ? RISCVISD::TH_SWD : RISCVISD::TH_SDD;
19667 {LSNode1->getChain(), LSNode1->getOperand(1), LSNode2->getOperand(1),
19668 BasePtr, DAG.getConstant(Imm, SDLoc(LSNode1), XLenVT)},
19685 if (!Subtarget.hasVendorXTHeadMemPair())
19697 auto ExtractBaseAndOffset = [](
SDValue Ptr) -> std::pair<SDValue, uint64_t> {
19700 return {Ptr->
getOperand(0), C1->getZExtValue()};
19704 auto [Base1, Offset1] = ExtractBaseAndOffset(LSNode1->
getOperand(OpNum));
19725 auto [Base2, Offset2] = ExtractBaseAndOffset(LSNode2->
getOperand(OpNum));
19728 if (Base1 != Base2)
19732 bool Valid =
false;
19733 if (MemVT == MVT::i32) {
19737 }
else if (MemVT == MVT::i64) {
19773 if (Src->isStrictFPOpcode())
19781 if (Src.getValueType() == MVT::f16 && !Subtarget.hasStdExtZfh())
19791 EVT VT =
N->getValueType(0);
19794 MVT SrcVT = Src.getSimpleValueType();
19795 MVT SrcContainerVT = SrcVT;
19822 IsSigned ? RISCVISD::VFCVT_RTZ_X_F_VL : RISCVISD::VFCVT_RTZ_XU_F_VL;
19823 FpToInt = DAG.
getNode(
Opc,
DL, ContainerVT, XVal, Mask, VL);
19826 IsSigned ? RISCVISD::VFCVT_RM_X_F_VL : RISCVISD::VFCVT_RM_XU_F_VL;
19827 FpToInt = DAG.
getNode(
Opc,
DL, ContainerVT, XVal, Mask,
19840 if (VT != MVT::i32 && VT != XLenVT)
19845 Opc = IsSigned ? RISCVISD::FCVT_X : RISCVISD::FCVT_XU;
19847 Opc = IsSigned ? RISCVISD::FCVT_W_RV64 : RISCVISD::FCVT_WU_RV64;
19870 EVT DstVT =
N->getValueType(0);
19871 if (DstVT != XLenVT)
19877 if (Src->isStrictFPOpcode())
19885 if (Src.getValueType() == MVT::f16 && !Subtarget.hasStdExtZfh())
19897 if (SatVT == DstVT)
19898 Opc = IsSigned ? RISCVISD::FCVT_X : RISCVISD::FCVT_XU;
19899 else if (DstVT == MVT::i64 && SatVT == MVT::i32)
19900 Opc = IsSigned ? RISCVISD::FCVT_W_RV64 : RISCVISD::FCVT_WU_RV64;
19905 Src = Src.getOperand(0);
19913 if (
Opc == RISCVISD::FCVT_WU_RV64)
19926 assert(Subtarget.hasStdExtZbkb() &&
"Unexpected extension");
19932 EVT VT =
N->getValueType(0);
19938 return DAG.
getNode(RISCVISD::BREV8,
DL, VT, Src.getOperand(0));
19973 while (!Worklist.
empty()) {
19977 if (!
X.hasOneUser())
19980 if (VPLoad && VPLoad != VPL)
19984 X->getNumValues() == 1) {
20008 LoadMask = OrigMask;
20046 EVT VT =
N->getValueType(0);
20048 if (!Subtarget.
is64Bit() || VT != MVT::i32 ||
20049 (SrcVT != MVT::v4i8 && SrcVT != MVT::v2i16))
20068 SDValue EVL = VPStore->getVectorLength();
20072 if (!
sd_match(VPStore->getValue(),
20076 EVT ReverseVT = VPStore->getValue()->getValueType(0);
20082 SDValue StoreMask = VPStore->getMask();
20090 StoreMask = OrigMask;
20096 SDValue NumElem = VPStore->getVectorLength();
20110 PtrInfo, VPStore->getMemOperand()->getFlags(),
20114 VPStore->getChain(),
DL, Val,
Base, VPStore->getOffset(), Stride,
20115 StoreMask, VPStore->getVectorLength(), VPStore->getMemoryVT(), MMO,
20116 VPStore->getAddressingMode(), VPStore->isTruncatingStore(),
20117 VPStore->isCompressingStore());
20129 case RISCVISD::VFMADD_VL: Opcode = RISCVISD::VFNMSUB_VL;
break;
20130 case RISCVISD::VFNMSUB_VL: Opcode = RISCVISD::VFMADD_VL;
break;
20131 case RISCVISD::VFNMADD_VL: Opcode = RISCVISD::VFMSUB_VL;
break;
20132 case RISCVISD::VFMSUB_VL: Opcode = RISCVISD::VFNMADD_VL;
break;
20133 case RISCVISD::STRICT_VFMADD_VL: Opcode = RISCVISD::STRICT_VFNMSUB_VL;
break;
20134 case RISCVISD::STRICT_VFNMSUB_VL: Opcode = RISCVISD::STRICT_VFMADD_VL;
break;
20135 case RISCVISD::STRICT_VFNMADD_VL: Opcode = RISCVISD::STRICT_VFMSUB_VL;
break;
20136 case RISCVISD::STRICT_VFMSUB_VL: Opcode = RISCVISD::STRICT_VFNMADD_VL;
break;
20146 case RISCVISD::VFMADD_VL: Opcode = RISCVISD::VFMSUB_VL;
break;
20147 case RISCVISD::VFMSUB_VL: Opcode = RISCVISD::VFMADD_VL;
break;
20148 case RISCVISD::VFNMADD_VL: Opcode = RISCVISD::VFNMSUB_VL;
break;
20149 case RISCVISD::VFNMSUB_VL: Opcode = RISCVISD::VFNMADD_VL;
break;
20150 case RISCVISD::STRICT_VFMADD_VL: Opcode = RISCVISD::STRICT_VFMSUB_VL;
break;
20151 case RISCVISD::STRICT_VFMSUB_VL: Opcode = RISCVISD::STRICT_VFMADD_VL;
break;
20152 case RISCVISD::STRICT_VFNMADD_VL: Opcode = RISCVISD::STRICT_VFNMSUB_VL;
break;
20153 case RISCVISD::STRICT_VFNMSUB_VL: Opcode = RISCVISD::STRICT_VFNMADD_VL;
break;
20166 unsigned Offset = IsStrict ? 1 : 0;
20173 auto invertIfNegative = [&Mask, &VL](
SDValue &V) {
20174 if (V.getOpcode() == RISCVISD::FNEG_VL && V.getOperand(1) == Mask &&
20175 V.getOperand(2) == VL) {
20177 V = V.getOperand(0);
20184 bool NegA = invertIfNegative(
A);
20185 bool NegB = invertIfNegative(
B);
20186 bool NegC = invertIfNegative(
C);
20189 if (!NegA && !NegB && !NegC)
20195 {N->getOperand(0), A, B, C, Mask, VL});
20219 EVT VT =
N->getValueType(0);
20226 uint64_t ShAmt =
N->getConstantOperandVal(1);
20239 if (LShAmt < ExtSize) {
20252 if (ShAmt > 32 || VT != MVT::i64)
20282 U->getConstantOperandVal(1) > 32)
20337 if (!
Cond.hasOneUse())
20356 EVT VT =
Cond.getValueType();
20401 LHS =
LHS.getOperand(0);
20411 LHS.getOperand(0).getValueType() == Subtarget.
getXLenVT()) {
20419 RHS =
LHS.getOperand(1);
20420 LHS =
LHS.getOperand(0);
20433 if (!XorCnst || !
isInt<12>(XorCnst->getSExtValue()))
20444 const unsigned Opcode = UserNode->getOpcode();
20445 return Opcode == RISCVISD::SELECT_CC || Opcode == RISCVISD::BR_CC;
20449 if (isFoldableXorEq(
LHS,
RHS)) {
20450 RHS =
LHS.getOperand(1);
20451 LHS =
LHS.getOperand(0);
20477 if (Subtarget.hasVendorXAndesPerf()) {
20487 ShAmt =
LHS.getValueSizeInBits() - 1 - ShAmt;
20530 bool Commutative =
true;
20531 unsigned Opc = TrueVal.getOpcode();
20541 Commutative =
false;
20551 if (!TrueVal.hasOneUse())
20555 if (FalseVal == TrueVal.getOperand(0))
20557 else if (Commutative && FalseVal == TrueVal.getOperand(1))
20562 EVT VT =
N->getValueType(0);
20564 SDValue OtherOp = TrueVal.getOperand(1 - OpToFold);
20570 assert(IdentityOperand &&
"No identity operand!");
20575 DAG.
getSelect(
DL, OtherOpVT,
N->getOperand(0), OtherOp, IdentityOperand);
20576 return DAG.
getNode(TrueVal.getOpcode(),
DL, VT, FalseVal, NewSel);
20597 CountZeroes =
N->getOperand(2);
20598 ValOnZero =
N->getOperand(1);
20600 CountZeroes =
N->getOperand(1);
20601 ValOnZero =
N->getOperand(2);
20620 if (
Cond->getOperand(0) != CountZeroesArgument)
20639 CountZeroes, BitWidthMinusOne);
20649 EVT VT =
N->getValueType(0);
20650 EVT CondVT =
Cond.getValueType();
20658 (Subtarget.
hasCZEROLike() || Subtarget.hasVendorXTHeadCondMov())) {
20664 const APInt &MaskVal =
LHS.getConstantOperandAPInt(1);
20678 SDValue TrueVal =
N->getOperand(1);
20679 SDValue FalseVal =
N->getOperand(2);
20682 !FalseVal.hasOneUse())
20687 if (!isIntEqualitySetCC(CCVal))
20693 TrueVal.getOpcode() == RISCVISD::VMV_V_X_VL ||
20694 FalseVal.getOpcode() == RISCVISD::VMV_V_X_VL)
20706 if (!TrueVal.hasOneUse() || !FalseVal.hasOneUse())
20710 if (TrueVal.getOpcode() ==
ISD::SUB && FalseVal.getOpcode() ==
ISD::ADD) {
20718 SDValue A = FalseVal.getOperand(0);
20719 SDValue B = FalseVal.getOperand(1);
20721 return ((TrueVal.getOperand(0) ==
A && TrueVal.getOperand(1) ==
B) ||
20722 (TrueVal.getOperand(1) ==
A && TrueVal.getOperand(0) ==
B));
20728 EVT VT =
N->getValueType(0);
20730 SDValue TrueVal =
N->getOperand(1);
20731 SDValue FalseVal =
N->getOperand(2);
20774 if (!Subtarget.hasStdExtP())
20777 EVT VT =
N->getValueType(0);
20785 uint64_t MaxVal = (1ULL << SatWidth) - 1;
20789 SDValue Src, InnerSetCC, FalseSrc;
20797 if (Src.getValueType().bitsGT(XLenVT))
20814 if (CmpSrc != FalseSrc)
20839 SDValue TrueVal =
N->getOperand(1);
20840 SDValue FalseVal =
N->getOperand(2);
20855 EVT VT =
N->getValueType(0);
20862 const unsigned Opcode =
N->op_begin()->getNode()->getOpcode();
20877 if (
Op.isUndef()) {
20890 if (
Op.getOpcode() != Opcode || !
Op.hasOneUse())
20899 if (
Op.getOperand(0).getValueType() !=
Op.getOperand(1).getValueType())
20923 EVT AVT =
A.getValueType();
20924 EVT BVT =
B.getValueType();
20954 if (AOpt || BOpt) {
20972 EVT OpVT =
A.getValueType();