1//===- RISCVInstrInfoVVLPatterns.td - RVV VL patterns ------*- tablegen -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// This file contains the required infrastructure and VL patterns to
10/// support code generation for the standard 'V' (Vector) extension, version
11/// 0.10.  This version is still experimental as the 'V' extension hasn't been
12/// ratified yet.
13///
14/// This file is included from and depends upon RISCVInstrInfoVPseudos.td
15///
16/// Note: the patterns for RVV intrinsics are found in
17/// RISCVInstrInfoVPseudos.td.
18///
19//===----------------------------------------------------------------------===//
20
21//===----------------------------------------------------------------------===//
22// Helpers to define the VL patterns.
23//===----------------------------------------------------------------------===//
24
25def SDT_RISCVVLE_VL : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisPtrTy<1>,
26                                           SDTCisVT<2, XLenVT>]>;
27def SDT_RISCVVSE_VL : SDTypeProfile<0, 3, [SDTCisVec<0>, SDTCisPtrTy<1>,
28                                           SDTCisVT<2, XLenVT>]>;
29
30def SDT_RISCVIntBinOp_VL : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>,
31                                                SDTCisSameAs<0, 2>,
32                                                SDTCisVec<0>, SDTCisInt<0>,
33                                                SDTCVecEltisVT<3, i1>,
34                                                SDTCisSameNumEltsAs<0, 3>,
35                                                SDTCisVT<4, XLenVT>]>;
36
37def SDT_RISCVFPUnOp_VL : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>,
38                                              SDTCisVec<0>, SDTCisFP<0>,
39                                              SDTCVecEltisVT<2, i1>,
40                                              SDTCisSameNumEltsAs<0, 2>,
41                                              SDTCisVT<3, XLenVT>]>;
42def SDT_RISCVFPBinOp_VL : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>,
43                                               SDTCisSameAs<0, 2>,
44                                               SDTCisVec<0>, SDTCisFP<0>,
45                                               SDTCVecEltisVT<3, i1>,
46                                               SDTCisSameNumEltsAs<0, 3>,
47                                               SDTCisVT<4, XLenVT>]>;
48
49def riscv_vmv_v_x_vl : SDNode<"RISCVISD::VMV_V_X_VL",
50                              SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisInt<0>,
51                                                   SDTCisVT<1, XLenVT>,
52                                                   SDTCisVT<2, XLenVT>]>>;
53def riscv_vfmv_v_f_vl : SDNode<"RISCVISD::VFMV_V_F_VL",
54                               SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisFP<0>,
55                                                    SDTCisEltOfVec<1, 0>,
56                                                    SDTCisVT<2, XLenVT>]>>;
57def riscv_vmv_s_x_vl : SDNode<"RISCVISD::VMV_S_X_VL",
58                              SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>,
59                                                   SDTCisInt<0>,
60                                                   SDTCisVT<2, XLenVT>,
61                                                   SDTCisVT<3, XLenVT>]>>;
62def riscv_vfmv_s_f_vl : SDNode<"RISCVISD::VFMV_S_F_VL",
63                               SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>,
64                                                    SDTCisFP<0>,
65                                                    SDTCisEltOfVec<2, 0>,
66                                                    SDTCisVT<3, XLenVT>]>>;
67
68def riscv_vle_vl : SDNode<"RISCVISD::VLE_VL", SDT_RISCVVLE_VL,
69                          [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
70def riscv_vse_vl : SDNode<"RISCVISD::VSE_VL", SDT_RISCVVSE_VL,
71                          [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
72
73def riscv_add_vl   : SDNode<"RISCVISD::ADD_VL",   SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
74def riscv_sub_vl   : SDNode<"RISCVISD::SUB_VL",   SDT_RISCVIntBinOp_VL>;
75def riscv_mul_vl   : SDNode<"RISCVISD::MUL_VL",   SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
76def riscv_mulhs_vl : SDNode<"RISCVISD::MULHS_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
77def riscv_mulhu_vl : SDNode<"RISCVISD::MULHU_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
78def riscv_and_vl   : SDNode<"RISCVISD::AND_VL",   SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
79def riscv_or_vl    : SDNode<"RISCVISD::OR_VL",    SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
80def riscv_xor_vl   : SDNode<"RISCVISD::XOR_VL",   SDT_RISCVIntBinOp_VL, [SDNPCommutative]>;
81def riscv_sdiv_vl  : SDNode<"RISCVISD::SDIV_VL",  SDT_RISCVIntBinOp_VL>;
82def riscv_srem_vl  : SDNode<"RISCVISD::SREM_VL",  SDT_RISCVIntBinOp_VL>;
83def riscv_udiv_vl  : SDNode<"RISCVISD::UDIV_VL",  SDT_RISCVIntBinOp_VL>;
84def riscv_urem_vl  : SDNode<"RISCVISD::UREM_VL",  SDT_RISCVIntBinOp_VL>;
85def riscv_shl_vl   : SDNode<"RISCVISD::SHL_VL",   SDT_RISCVIntBinOp_VL>;
86def riscv_sra_vl   : SDNode<"RISCVISD::SRA_VL",   SDT_RISCVIntBinOp_VL>;
87def riscv_srl_vl   : SDNode<"RISCVISD::SRL_VL",   SDT_RISCVIntBinOp_VL>;
88def riscv_smin_vl  : SDNode<"RISCVISD::SMIN_VL",  SDT_RISCVIntBinOp_VL>;
89def riscv_smax_vl  : SDNode<"RISCVISD::SMAX_VL",  SDT_RISCVIntBinOp_VL>;
90def riscv_umin_vl  : SDNode<"RISCVISD::UMIN_VL",  SDT_RISCVIntBinOp_VL>;
91def riscv_umax_vl  : SDNode<"RISCVISD::UMAX_VL",  SDT_RISCVIntBinOp_VL>;
92def riscv_fadd_vl  : SDNode<"RISCVISD::FADD_VL",  SDT_RISCVFPBinOp_VL, [SDNPCommutative]>;
93def riscv_fsub_vl  : SDNode<"RISCVISD::FSUB_VL",  SDT_RISCVFPBinOp_VL>;
94def riscv_fmul_vl  : SDNode<"RISCVISD::FMUL_VL",  SDT_RISCVFPBinOp_VL, [SDNPCommutative]>;
95def riscv_fdiv_vl  : SDNode<"RISCVISD::FDIV_VL",  SDT_RISCVFPBinOp_VL>;
96def riscv_fneg_vl  : SDNode<"RISCVISD::FNEG_VL",  SDT_RISCVFPUnOp_VL>;
97def riscv_fabs_vl  : SDNode<"RISCVISD::FABS_VL",  SDT_RISCVFPUnOp_VL>;
98def riscv_fsqrt_vl : SDNode<"RISCVISD::FSQRT_VL", SDT_RISCVFPUnOp_VL>;
99def riscv_fcopysign_vl : SDNode<"RISCVISD::FCOPYSIGN_VL",  SDT_RISCVFPBinOp_VL>;
100def riscv_fminnum_vl   : SDNode<"RISCVISD::FMINNUM_VL",  SDT_RISCVFPBinOp_VL>;
101def riscv_fmaxnum_vl   : SDNode<"RISCVISD::FMAXNUM_VL",  SDT_RISCVFPBinOp_VL>;
102
103def SDT_RISCVVecFMA_VL : SDTypeProfile<1, 5, [SDTCisSameAs<0, 1>,
104                                              SDTCisSameAs<0, 2>,
105                                              SDTCisSameAs<0, 3>,
106                                              SDTCisVec<0>, SDTCisFP<0>,
107                                              SDTCVecEltisVT<4, i1>,
108                                              SDTCisSameNumEltsAs<0, 4>,
109                                              SDTCisVT<5, XLenVT>]>;
110def riscv_fma_vl : SDNode<"RISCVISD::FMA_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative]>;
111
112def SDT_RISCVFPRoundOp_VL  : SDTypeProfile<1, 3, [
113  SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<0, 1>, SDTCisSameNumEltsAs<0, 1>,
114  SDTCVecEltisVT<2, i1>, SDTCisSameNumEltsAs<1, 2>, SDTCisVT<3, XLenVT>
115]>;
116def SDT_RISCVFPExtendOp_VL  : SDTypeProfile<1, 3, [
117  SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0>, SDTCisSameNumEltsAs<0, 1>,
118  SDTCVecEltisVT<2, i1>, SDTCisSameNumEltsAs<1, 2>, SDTCisVT<3, XLenVT>
119]>;
120
121def riscv_fpround_vl : SDNode<"RISCVISD::FP_ROUND_VL", SDT_RISCVFPRoundOp_VL>;
122def riscv_fpextend_vl : SDNode<"RISCVISD::FP_EXTEND_VL", SDT_RISCVFPExtendOp_VL>;
123def riscv_fncvt_rod_vl : SDNode<"RISCVISD::VFNCVT_ROD_VL", SDT_RISCVFPRoundOp_VL>;
124
125def SDT_RISCVFP2IOp_VL  : SDTypeProfile<1, 3, [
126  SDTCisInt<0>, SDTCisFP<1>, SDTCisSameNumEltsAs<0, 1>,
127  SDTCVecEltisVT<2, i1>, SDTCisSameNumEltsAs<1, 2>, SDTCisVT<3, XLenVT>
128]>;
129def SDT_RISCVI2FPOp_VL  : SDTypeProfile<1, 3, [
130  SDTCisFP<0>, SDTCisInt<1>, SDTCisSameNumEltsAs<0, 1>,
131  SDTCVecEltisVT<2, i1>, SDTCisSameNumEltsAs<1, 2>, SDTCisVT<3, XLenVT>
132]>;
133
134def riscv_fp_to_sint_vl : SDNode<"RISCVISD::FP_TO_SINT_VL", SDT_RISCVFP2IOp_VL>;
135def riscv_fp_to_uint_vl : SDNode<"RISCVISD::FP_TO_UINT_VL", SDT_RISCVFP2IOp_VL>;
136def riscv_sint_to_fp_vl : SDNode<"RISCVISD::SINT_TO_FP_VL", SDT_RISCVI2FPOp_VL>;
137def riscv_uint_to_fp_vl : SDNode<"RISCVISD::UINT_TO_FP_VL", SDT_RISCVI2FPOp_VL>;
138
139def riscv_setcc_vl : SDNode<"RISCVISD::SETCC_VL",
140                            SDTypeProfile<1, 5, [SDTCVecEltisVT<0, i1>,
141                                                 SDTCisVec<1>,
142                                                 SDTCisSameNumEltsAs<0, 1>,
143                                                 SDTCisSameAs<1, 2>,
144                                                 SDTCisVT<3, OtherVT>,
145                                                 SDTCisSameAs<0, 4>,
146                                                 SDTCisVT<5, XLenVT>]>>;
147
148def riscv_vrgather_vx_vl : SDNode<"RISCVISD::VRGATHER_VX_VL",
149                                  SDTypeProfile<1, 4, [SDTCisVec<0>,
150                                                       SDTCisSameAs<0, 1>,
151                                                       SDTCisVT<2, XLenVT>,
152                                                       SDTCVecEltisVT<3, i1>,
153                                                       SDTCisSameNumEltsAs<0, 3>,
154                                                       SDTCisVT<4, XLenVT>]>>;
155def riscv_vrgather_vv_vl : SDNode<"RISCVISD::VRGATHER_VV_VL",
156                                  SDTypeProfile<1, 4, [SDTCisVec<0>,
157                                                       SDTCisSameAs<0, 1>,
158                                                       SDTCisInt<2>,
159                                                       SDTCisSameNumEltsAs<0, 2>,
160                                                       SDTCisSameSizeAs<0, 2>,
161                                                       SDTCVecEltisVT<3, i1>,
162                                                       SDTCisSameNumEltsAs<0, 3>,
163                                                       SDTCisVT<4, XLenVT>]>>;
164def riscv_vrgatherei16_vv_vl : SDNode<"RISCVISD::VRGATHEREI16_VV_VL",
165                                      SDTypeProfile<1, 4, [SDTCisVec<0>,
166                                                           SDTCisSameAs<0, 1>,
167                                                           SDTCisInt<2>,
168                                                           SDTCVecEltisVT<2, i16>,
169                                                           SDTCisSameNumEltsAs<0, 2>,
170                                                           SDTCVecEltisVT<3, i1>,
171                                                           SDTCisSameNumEltsAs<0, 3>,
172                                                           SDTCisVT<4, XLenVT>]>>;
173
174def riscv_vselect_vl : SDNode<"RISCVISD::VSELECT_VL",
175                              SDTypeProfile<1, 4, [SDTCisVec<0>,
176                                                   SDTCisVec<1>,
177                                                   SDTCisSameNumEltsAs<0, 1>,
178                                                   SDTCVecEltisVT<1, i1>,
179                                                   SDTCisSameAs<0, 2>,
180                                                   SDTCisSameAs<2, 3>,
181                                                   SDTCisVT<4, XLenVT>]>>;
182
183def SDT_RISCVMaskBinOp_VL : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>,
184                                                 SDTCisSameAs<0, 2>,
185                                                 SDTCVecEltisVT<0, i1>,
186                                                 SDTCisVT<3, XLenVT>]>;
187def riscv_vmand_vl : SDNode<"RISCVISD::VMAND_VL", SDT_RISCVMaskBinOp_VL, [SDNPCommutative]>;
188def riscv_vmor_vl  : SDNode<"RISCVISD::VMOR_VL",  SDT_RISCVMaskBinOp_VL, [SDNPCommutative]>;
189def riscv_vmxor_vl : SDNode<"RISCVISD::VMXOR_VL", SDT_RISCVMaskBinOp_VL, [SDNPCommutative]>;
190
191def true_mask : PatLeaf<(riscv_vmset_vl (XLenVT srcvalue))>;
192
193def riscv_vmnot_vl : PatFrag<(ops node:$rs, node:$vl),
194                             (riscv_vmxor_vl node:$rs, true_mask, node:$vl)>;
195
196def riscv_vpopc_vl : SDNode<"RISCVISD::VPOPC_VL",
197                            SDTypeProfile<1, 3, [SDTCisVT<0, XLenVT>,
198                                                 SDTCisVec<1>, SDTCisInt<1>,
199                                                 SDTCVecEltisVT<2, i1>,
200                                                 SDTCisSameNumEltsAs<1, 2>,
201                                                 SDTCisVT<3, XLenVT>]>>;
202
203def SDT_RISCVVEXTEND_VL : SDTypeProfile<1, 3, [SDTCisVec<0>,
204                                               SDTCisSameNumEltsAs<0, 1>,
205                                               SDTCisSameNumEltsAs<1, 2>,
206                                               SDTCVecEltisVT<2, i1>,
207                                               SDTCisVT<3, XLenVT>]>;
208def riscv_sext_vl : SDNode<"RISCVISD::VSEXT_VL", SDT_RISCVVEXTEND_VL>;
209def riscv_zext_vl : SDNode<"RISCVISD::VZEXT_VL", SDT_RISCVVEXTEND_VL>;
210
211def riscv_trunc_vector_vl : SDNode<"RISCVISD::TRUNCATE_VECTOR_VL",
212                                   SDTypeProfile<1, 3, [SDTCisVec<0>,
213                                                        SDTCisVec<1>,
214                                                        SDTCisSameNumEltsAs<0, 2>,
215                                                        SDTCVecEltisVT<2, i1>,
216                                                        SDTCisVT<3, XLenVT>]>>;
217
218def SDTRVVVecReduce : SDTypeProfile<1, 4, [
219  SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<0, 2>, SDTCVecEltisVT<3, i1>,
220  SDTCisSameNumEltsAs<1, 3>, SDTCisVT<4, XLenVT>
221]>;
222
223foreach kind = ["ADD", "UMAX", "SMAX", "UMIN", "SMIN", "AND", "OR", "XOR",
224                "FADD", "SEQ_FADD", "FMIN", "FMAX"] in
225  def rvv_vecreduce_#kind#_vl : SDNode<"RISCVISD::VECREDUCE_"#kind#"_VL", SDTRVVVecReduce>;
226
227// Ignore the vl operand.
228def SplatFPOp : PatFrag<(ops node:$op),
229                        (riscv_vfmv_v_f_vl node:$op, srcvalue)>;
230
231def sew8simm5  : ComplexPattern<XLenVT, 1, "selectRVVSimm5<8>",  []>;
232def sew16simm5 : ComplexPattern<XLenVT, 1, "selectRVVSimm5<16>", []>;
233def sew32simm5 : ComplexPattern<XLenVT, 1, "selectRVVSimm5<32>", []>;
234def sew64simm5 : ComplexPattern<XLenVT, 1, "selectRVVSimm5<64>", []>;
235
236multiclass VPatBinaryVL_VV<SDNode vop,
237                           string instruction_name,
238                           ValueType result_type,
239                           ValueType op_type,
240                           ValueType mask_type,
241                           int sew,
242                           LMULInfo vlmul,
243                           VReg RetClass,
244                           VReg op_reg_class> {
245  def : Pat<(result_type (vop
246                         (op_type op_reg_class:$rs1),
247                         (op_type op_reg_class:$rs2),
248                         (mask_type true_mask),
249                         VLOpFrag)),
250            (!cast<Instruction>(instruction_name#"_VV_"# vlmul.MX)
251                         op_reg_class:$rs1,
252                         op_reg_class:$rs2,
253                         GPR:$vl, sew)>;
254  def : Pat<(result_type (vop
255                         (op_type op_reg_class:$rs1),
256                         (op_type op_reg_class:$rs2),
257                         (mask_type VMV0:$vm),
258                         VLOpFrag)),
259        (!cast<Instruction>(instruction_name#"_VV_"# vlmul.MX#"_MASK")
260                     (result_type (IMPLICIT_DEF)),
261                     op_reg_class:$rs1,
262                     op_reg_class:$rs2,
263                     VMV0:$vm, GPR:$vl, sew)>;
264}
265
266multiclass VPatBinaryVL_XI<SDNode vop,
267                           string instruction_name,
268                           string suffix,
269                           ValueType result_type,
270                           ValueType vop_type,
271                           ValueType mask_type,
272                           int sew,
273                           LMULInfo vlmul,
274                           VReg RetClass,
275                           VReg vop_reg_class,
276                           ComplexPattern SplatPatKind,
277                           DAGOperand xop_kind> {
278  def : Pat<(result_type (vop
279                     (vop_type vop_reg_class:$rs1),
280                     (vop_type (SplatPatKind (XLenVT xop_kind:$rs2))),
281                     (mask_type true_mask),
282                     VLOpFrag)),
283        (!cast<Instruction>(instruction_name#_#suffix#_# vlmul.MX)
284                     vop_reg_class:$rs1,
285                     xop_kind:$rs2,
286                     GPR:$vl, sew)>;
287  def : Pat<(result_type (vop
288                     (vop_type vop_reg_class:$rs1),
289                     (vop_type (SplatPatKind (XLenVT xop_kind:$rs2))),
290                     (mask_type VMV0:$vm),
291                     VLOpFrag)),
292        (!cast<Instruction>(instruction_name#_#suffix#_# vlmul.MX#"_MASK")
293                     (result_type (IMPLICIT_DEF)),
294                     vop_reg_class:$rs1,
295                     xop_kind:$rs2,
296                     VMV0:$vm, GPR:$vl, sew)>;
297}
298
299multiclass VPatBinaryVL_VV_VX<SDNode vop, string instruction_name> {
300  foreach vti = AllIntegerVectors in {
301    defm : VPatBinaryVL_VV<vop, instruction_name,
302                           vti.Vector, vti.Vector, vti.Mask, vti.Log2SEW,
303                           vti.LMul, vti.RegClass, vti.RegClass>;
304    defm : VPatBinaryVL_XI<vop, instruction_name, "VX",
305                           vti.Vector, vti.Vector, vti.Mask, vti.Log2SEW,
306                           vti.LMul, vti.RegClass, vti.RegClass,
307                           SplatPat, GPR>;
308  }
309}
310
311multiclass VPatBinaryVL_VV_VX_VI<SDNode vop, string instruction_name,
312                                 Operand ImmType = simm5>
313    : VPatBinaryVL_VV_VX<vop, instruction_name> {
314  foreach vti = AllIntegerVectors in {
315    defm : VPatBinaryVL_XI<vop, instruction_name, "VI",
316                           vti.Vector, vti.Vector, vti.Mask, vti.Log2SEW,
317                           vti.LMul, vti.RegClass, vti.RegClass,
318                           !cast<ComplexPattern>(SplatPat#_#ImmType),
319                           ImmType>;
320  }
321}
322
323class VPatBinaryVL_VF<SDNode vop,
324                      string instruction_name,
325                      ValueType result_type,
326                      ValueType vop_type,
327                      ValueType mask_type,
328                      int sew,
329                      LMULInfo vlmul,
330                      VReg RetClass,
331                      VReg vop_reg_class,
332                      RegisterClass scalar_reg_class> :
333    Pat<(result_type (vop (vop_type vop_reg_class:$rs1),
334                          (vop_type (SplatFPOp scalar_reg_class:$rs2)),
335                          (mask_type true_mask),
336                          VLOpFrag)),
337        (!cast<Instruction>(instruction_name#"_"#vlmul.MX)
338                     vop_reg_class:$rs1,
339                     scalar_reg_class:$rs2,
340                     GPR:$vl, sew)>;
341
342multiclass VPatBinaryFPVL_VV_VF<SDNode vop, string instruction_name> {
343  foreach vti = AllFloatVectors in {
344    defm : VPatBinaryVL_VV<vop, instruction_name,
345                           vti.Vector, vti.Vector, vti.Mask, vti.Log2SEW,
346                           vti.LMul, vti.RegClass, vti.RegClass>;
347    def : VPatBinaryVL_VF<vop, instruction_name#"_V"#vti.ScalarSuffix,
348                          vti.Vector, vti.Vector, vti.Mask, vti.Log2SEW,
349                          vti.LMul, vti.RegClass, vti.RegClass,
350                          vti.ScalarRegClass>;
351  }
352}
353
354multiclass VPatBinaryFPVL_R_VF<SDNode vop, string instruction_name> {
355  foreach fvti = AllFloatVectors in
356    def : Pat<(fvti.Vector (vop (SplatFPOp fvti.ScalarRegClass:$rs2),
357                                fvti.RegClass:$rs1,
358                                (fvti.Mask true_mask),
359                                VLOpFrag)),
360              (!cast<Instruction>(instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX)
361                           fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2,
362                           GPR:$vl, fvti.Log2SEW)>;
363}
364
365multiclass VPatIntegerSetCCVL_VV<VTypeInfo vti, string instruction_name,
366                                 CondCode cc> {
367  def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs1),
368                                      vti.RegClass:$rs2, cc,
369                                      (vti.Mask true_mask),
370                                      VLOpFrag)),
371            (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX)
372                         vti.RegClass:$rs1, vti.RegClass:$rs2, GPR:$vl,
373                         vti.Log2SEW)>;
374}
375
376// Inherits from VPatIntegerSetCCVL_VV and adds a pattern with operands swapped.
377multiclass VPatIntegerSetCCVL_VV_Swappable<VTypeInfo vti, string instruction_name,
378                                           CondCode cc, CondCode invcc> :
379  VPatIntegerSetCCVL_VV<vti, instruction_name, cc> {
380  def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs2),
381                                      vti.RegClass:$rs1, invcc,
382                                      (vti.Mask true_mask),
383                                      VLOpFrag)),
384            (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX)
385                         vti.RegClass:$rs1, vti.RegClass:$rs2, GPR:$vl,
386                         vti.Log2SEW)>;
387}
388
389multiclass VPatIntegerSetCCVL_VX_Swappable<VTypeInfo vti, string instruction_name,
390                                           CondCode cc, CondCode invcc> {
391  defvar instruction = !cast<Instruction>(instruction_name#"_VX_"#vti.LMul.MX);
392  def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs1),
393                                      (SplatPat (XLenVT GPR:$rs2)), cc,
394                                      (vti.Mask true_mask),
395                                      VLOpFrag)),
396            (instruction vti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.Log2SEW)>;
397  def : Pat<(vti.Mask (riscv_setcc_vl (SplatPat (XLenVT GPR:$rs2)),
398                                      (vti.Vector vti.RegClass:$rs1), invcc,
399                                      (vti.Mask true_mask),
400                                      VLOpFrag)),
401            (instruction vti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.Log2SEW)>;
402}
403
404multiclass VPatIntegerSetCCVL_VI_Swappable<VTypeInfo vti, string instruction_name,
405                                           CondCode cc, CondCode invcc> {
406  defvar instruction = !cast<Instruction>(instruction_name#"_VI_"#vti.LMul.MX);
407  def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs1),
408                                      (SplatPat_simm5 simm5:$rs2), cc,
409                                      (vti.Mask true_mask),
410                                      VLOpFrag)),
411            (instruction vti.RegClass:$rs1, XLenVT:$rs2, GPR:$vl, vti.Log2SEW)>;
412  def : Pat<(vti.Mask (riscv_setcc_vl (SplatPat_simm5 simm5:$rs2),
413                                      (vti.Vector vti.RegClass:$rs1), invcc,
414                                      (vti.Mask true_mask),
415                                      VLOpFrag)),
416            (instruction vti.RegClass:$rs1, simm5:$rs2, GPR:$vl, vti.Log2SEW)>;
417}
418
419multiclass VPatIntegerSetCCVL_VIPlus1<VTypeInfo vti, string instruction_name,
420                                      CondCode cc, ComplexPattern splatpat_kind> {
421  defvar instruction = !cast<Instruction>(instruction_name#"_VI_"#vti.LMul.MX);
422  def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs1),
423                                      (splatpat_kind simm5:$rs2), cc,
424                                      (vti.Mask true_mask),
425                                      VLOpFrag)),
426            (instruction vti.RegClass:$rs1, (DecImm simm5:$rs2),
427                         GPR:$vl, vti.Log2SEW)>;
428}
429
430multiclass VPatFPSetCCVL_VV_VF_FV<CondCode cc,
431                                  string inst_name,
432                                  string swapped_op_inst_name> {
433  foreach fvti = AllFloatVectors in {
434    def : Pat<(fvti.Mask (riscv_setcc_vl (fvti.Vector fvti.RegClass:$rs1),
435                                         fvti.RegClass:$rs2,
436                                         cc,
437                                         (fvti.Mask true_mask),
438                                         VLOpFrag)),
439              (!cast<Instruction>(inst_name#"_VV_"#fvti.LMul.MX)
440                  fvti.RegClass:$rs1, fvti.RegClass:$rs2, GPR:$vl, fvti.Log2SEW)>;
441    def : Pat<(fvti.Mask (riscv_setcc_vl (fvti.Vector fvti.RegClass:$rs1),
442                                         (SplatFPOp fvti.ScalarRegClass:$rs2),
443                                         cc,
444                                         (fvti.Mask true_mask),
445                                         VLOpFrag)),
446              (!cast<Instruction>(inst_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX)
447                  fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2,
448                  GPR:$vl, fvti.Log2SEW)>;
449    def : Pat<(fvti.Mask (riscv_setcc_vl (SplatFPOp fvti.ScalarRegClass:$rs2),
450                                         (fvti.Vector fvti.RegClass:$rs1),
451                                         cc,
452                                         (fvti.Mask true_mask),
453                                         VLOpFrag)),
454              (!cast<Instruction>(swapped_op_inst_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX)
455                  fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2,
456                  GPR:$vl, fvti.Log2SEW)>;
457  }
458}
459
460multiclass VPatExtendSDNode_V_VL<SDNode vop, string inst_name, string suffix,
461                                 list <VTypeInfoToFraction> fraction_list> {
462  foreach vtiTofti = fraction_list in {
463    defvar vti = vtiTofti.Vti;
464    defvar fti = vtiTofti.Fti;
465    def : Pat<(vti.Vector (vop (fti.Vector fti.RegClass:$rs2),
466                               true_mask, VLOpFrag)),
467              (!cast<Instruction>(inst_name#"_"#suffix#"_"#vti.LMul.MX)
468                  fti.RegClass:$rs2, GPR:$vl, vti.Log2SEW)>;
469  }
470}
471
472multiclass VPatConvertFP2ISDNode_V_VL<SDNode vop, string instruction_name> {
473  foreach fvti = AllFloatVectors in {
474    defvar ivti = GetIntVTypeInfo<fvti>.Vti;
475    def : Pat<(ivti.Vector (vop (fvti.Vector fvti.RegClass:$rs1),
476                                (fvti.Mask true_mask),
477                                VLOpFrag)),
478              (!cast<Instruction>(instruction_name#"_"#ivti.LMul.MX)
479                  fvti.RegClass:$rs1, GPR:$vl, ivti.Log2SEW)>;
480  }
481}
482
483multiclass VPatConvertI2FPSDNode_V_VL<SDNode vop, string instruction_name> {
484  foreach fvti = AllFloatVectors in {
485    defvar ivti = GetIntVTypeInfo<fvti>.Vti;
486    def : Pat<(fvti.Vector (vop (ivti.Vector ivti.RegClass:$rs1),
487                                (ivti.Mask true_mask),
488                                VLOpFrag)),
489              (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX)
490                  ivti.RegClass:$rs1, GPR:$vl, fvti.Log2SEW)>;
491  }
492}
493
494multiclass VPatWConvertFP2ISDNode_V_VL<SDNode vop, string instruction_name> {
495  foreach fvtiToFWti = AllWidenableFloatVectors in {
496    defvar fvti = fvtiToFWti.Vti;
497    defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti;
498    def : Pat<(iwti.Vector (vop (fvti.Vector fvti.RegClass:$rs1),
499                                (fvti.Mask true_mask),
500                                VLOpFrag)),
501              (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX)
502                  fvti.RegClass:$rs1, GPR:$vl, fvti.Log2SEW)>;
503  }
504}
505
506multiclass VPatWConvertI2FPSDNode_V_VL<SDNode vop, string instruction_name> {
507  foreach vtiToWti = AllWidenableIntToFloatVectors in {
508    defvar ivti = vtiToWti.Vti;
509    defvar fwti = vtiToWti.Wti;
510    def : Pat<(fwti.Vector (vop (ivti.Vector ivti.RegClass:$rs1),
511                                (ivti.Mask true_mask),
512                                VLOpFrag)),
513              (!cast<Instruction>(instruction_name#"_"#ivti.LMul.MX)
514                  ivti.RegClass:$rs1, GPR:$vl, ivti.Log2SEW)>;
515  }
516}
517
518multiclass VPatNConvertFP2ISDNode_V_VL<SDNode vop, string instruction_name> {
519  foreach vtiToWti = AllWidenableIntToFloatVectors in {
520    defvar vti = vtiToWti.Vti;
521    defvar fwti = vtiToWti.Wti;
522    def : Pat<(vti.Vector (vop (fwti.Vector fwti.RegClass:$rs1),
523                               (fwti.Mask true_mask),
524                               VLOpFrag)),
525              (!cast<Instruction>(instruction_name#"_"#vti.LMul.MX)
526                  fwti.RegClass:$rs1, GPR:$vl, vti.Log2SEW)>;
527  }
528}
529
530multiclass VPatNConvertI2FPSDNode_V_VL<SDNode vop, string instruction_name> {
531  foreach fvtiToFWti = AllWidenableFloatVectors in {
532    defvar fvti = fvtiToFWti.Vti;
533    defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti;
534    def : Pat<(fvti.Vector (vop (iwti.Vector iwti.RegClass:$rs1),
535                                (iwti.Mask true_mask),
536                                VLOpFrag)),
537              (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX)
538                  iwti.RegClass:$rs1, GPR:$vl, fvti.Log2SEW)>;
539  }
540}
541
542multiclass VPatReductionVL<SDNode vop, string instruction_name, bit is_float> {
543  foreach vti = !if(is_float, AllFloatVectors, AllIntegerVectors) in {
544    defvar vti_m1 = !cast<VTypeInfo>(!if(is_float, "VF", "VI") # vti.SEW # "M1");
545    def: Pat<(vti_m1.Vector (vop (vti.Vector vti.RegClass:$rs1), VR:$rs2,
546                                 (vti.Mask true_mask),
547                                 VLOpFrag)),
548        (!cast<Instruction>(instruction_name#"_VS_"#vti.LMul.MX)
549            (vti_m1.Vector (IMPLICIT_DEF)),
550            (vti.Vector vti.RegClass:$rs1),
551            (vti_m1.Vector VR:$rs2),
552            GPR:$vl, vti.Log2SEW)>;
553  }
554}
555
556//===----------------------------------------------------------------------===//
557// Patterns.
558//===----------------------------------------------------------------------===//
559
560let Predicates = [HasStdExtV] in {
561
562// 7.4. Vector Unit-Stride Instructions
563foreach vti = AllVectors in {
564  defvar load_instr = !cast<Instruction>("PseudoVLE"#vti.SEW#"_V_"#vti.LMul.MX);
565  defvar store_instr = !cast<Instruction>("PseudoVSE"#vti.SEW#"_V_"#vti.LMul.MX);
566  // Load
567  def : Pat<(vti.Vector (riscv_vle_vl BaseAddr:$rs1, VLOpFrag)),
568            (load_instr BaseAddr:$rs1, GPR:$vl, vti.Log2SEW)>;
569  // Store
570  def : Pat<(riscv_vse_vl (vti.Vector vti.RegClass:$rs2), BaseAddr:$rs1,
571                          VLOpFrag),
572            (store_instr vti.RegClass:$rs2, BaseAddr:$rs1, GPR:$vl, vti.Log2SEW)>;
573}
574
575foreach mti = AllMasks in {
576  defvar load_instr = !cast<Instruction>("PseudoVLE1_V_"#mti.BX);
577  defvar store_instr = !cast<Instruction>("PseudoVSE1_V_"#mti.BX);
578  def : Pat<(mti.Mask (riscv_vle_vl BaseAddr:$rs1, VLOpFrag)),
579            (load_instr BaseAddr:$rs1, GPR:$vl, mti.Log2SEW)>;
580  def : Pat<(riscv_vse_vl (mti.Mask VR:$rs2), BaseAddr:$rs1,
581                          VLOpFrag),
582            (store_instr VR:$rs2, BaseAddr:$rs1, GPR:$vl, mti.Log2SEW)>;
583}
584
585// 12.1. Vector Single-Width Integer Add and Subtract
586defm : VPatBinaryVL_VV_VX_VI<riscv_add_vl, "PseudoVADD">;
587defm : VPatBinaryVL_VV_VX<riscv_sub_vl, "PseudoVSUB">;
588// Handle VRSUB specially since it's the only integer binary op with reversed
589// pattern operands
590foreach vti = AllIntegerVectors in {
591  def : Pat<(riscv_sub_vl (vti.Vector (SplatPat (XLenVT GPR:$rs2))),
592                          (vti.Vector vti.RegClass:$rs1), (vti.Mask true_mask),
593                          VLOpFrag),
594            (!cast<Instruction>("PseudoVRSUB_VX_"# vti.LMul.MX)
595                 vti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.Log2SEW)>;
596  def : Pat<(riscv_sub_vl (vti.Vector (SplatPat (XLenVT GPR:$rs2))),
597                          (vti.Vector vti.RegClass:$rs1), (vti.Mask VMV0:$vm),
598                          VLOpFrag),
599            (!cast<Instruction>("PseudoVRSUB_VX_"# vti.LMul.MX#"_MASK")
600                 (vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, GPR:$rs2,
601                 VMV0:$vm, GPR:$vl, vti.Log2SEW)>;
602  def : Pat<(riscv_sub_vl (vti.Vector (SplatPat_simm5 simm5:$rs2)),
603                          (vti.Vector vti.RegClass:$rs1), (vti.Mask true_mask),
604                          VLOpFrag),
605            (!cast<Instruction>("PseudoVRSUB_VI_"# vti.LMul.MX)
606                 vti.RegClass:$rs1, simm5:$rs2, GPR:$vl, vti.Log2SEW)>;
607  def : Pat<(riscv_sub_vl (vti.Vector (SplatPat_simm5 simm5:$rs2)),
608                          (vti.Vector vti.RegClass:$rs1), (vti.Mask VMV0:$vm),
609                          VLOpFrag),
610            (!cast<Instruction>("PseudoVRSUB_VI_"# vti.LMul.MX#"_MASK")
611                 (vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, simm5:$rs2,
612                 VMV0:$vm, GPR:$vl, vti.Log2SEW)>;
613}
614
615// 12.3. Vector Integer Extension
616defm : VPatExtendSDNode_V_VL<riscv_zext_vl, "PseudoVZEXT", "VF2",
617                             AllFractionableVF2IntVectors>;
618defm : VPatExtendSDNode_V_VL<riscv_sext_vl, "PseudoVSEXT", "VF2",
619                             AllFractionableVF2IntVectors>;
620defm : VPatExtendSDNode_V_VL<riscv_zext_vl, "PseudoVZEXT", "VF4",
621                             AllFractionableVF4IntVectors>;
622defm : VPatExtendSDNode_V_VL<riscv_sext_vl, "PseudoVSEXT", "VF4",
623                             AllFractionableVF4IntVectors>;
624defm : VPatExtendSDNode_V_VL<riscv_zext_vl, "PseudoVZEXT", "VF8",
625                             AllFractionableVF8IntVectors>;
626defm : VPatExtendSDNode_V_VL<riscv_sext_vl, "PseudoVSEXT", "VF8",
627                                AllFractionableVF8IntVectors>;
628
629// 12.5. Vector Bitwise Logical Instructions
630defm : VPatBinaryVL_VV_VX_VI<riscv_and_vl, "PseudoVAND">;
631defm : VPatBinaryVL_VV_VX_VI<riscv_or_vl,  "PseudoVOR">;
632defm : VPatBinaryVL_VV_VX_VI<riscv_xor_vl, "PseudoVXOR">;
633
634// 12.6. Vector Single-Width Bit Shift Instructions
635defm : VPatBinaryVL_VV_VX_VI<riscv_shl_vl, "PseudoVSLL", uimm5>;
636defm : VPatBinaryVL_VV_VX_VI<riscv_srl_vl, "PseudoVSRL", uimm5>;
637defm : VPatBinaryVL_VV_VX_VI<riscv_sra_vl, "PseudoVSRA", uimm5>;
638
639
640
641// 12.7. Vector Narrowing Integer Right Shift Instructions
642foreach vtiTowti = AllWidenableIntVectors in {
643  defvar vti = vtiTowti.Vti;
644  defvar wti = vtiTowti.Wti;
645  def : Pat<(vti.Vector (riscv_trunc_vector_vl (wti.Vector wti.RegClass:$rs1),
646                                               (vti.Mask true_mask),
647                                               VLOpFrag)),
648            (!cast<Instruction>("PseudoVNSRL_WI_"#vti.LMul.MX)
649                wti.RegClass:$rs1, 0, GPR:$vl, vti.Log2SEW)>;
650
651  def : Pat<(vti.Vector
652             (riscv_trunc_vector_vl
653              (wti.Vector
654               (riscv_sra_vl wti.RegClass:$rs1, (SplatPat XLenVT:$rs2),
655                             true_mask, VLOpFrag)), true_mask, VLOpFrag)),
656            (!cast<Instruction>("PseudoVNSRA_WX_"#vti.LMul.MX)
657                wti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.Log2SEW)>;
658  def : Pat<(vti.Vector
659             (riscv_trunc_vector_vl
660              (wti.Vector
661               (riscv_sra_vl wti.RegClass:$rs1, (SplatPat_uimm5 uimm5:$rs2),
662                             true_mask, VLOpFrag)), true_mask, VLOpFrag)),
663            (!cast<Instruction>("PseudoVNSRA_WI_"#vti.LMul.MX)
664                wti.RegClass:$rs1, uimm5:$rs2, GPR:$vl, vti.Log2SEW)>;
665
666  def : Pat<(vti.Vector
667             (riscv_trunc_vector_vl
668              (wti.Vector
669               (riscv_srl_vl wti.RegClass:$rs1, (SplatPat XLenVT:$rs2),
670                             true_mask, VLOpFrag)), true_mask, VLOpFrag)),
671            (!cast<Instruction>("PseudoVNSRL_WX_"#vti.LMul.MX)
672                wti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.Log2SEW)>;
673  def : Pat<(vti.Vector
674             (riscv_trunc_vector_vl
675              (wti.Vector
676               (riscv_srl_vl wti.RegClass:$rs1, (SplatPat_uimm5 uimm5:$rs2),
677                             true_mask, VLOpFrag)), true_mask, VLOpFrag)),
678            (!cast<Instruction>("PseudoVNSRL_WI_"#vti.LMul.MX)
679                wti.RegClass:$rs1, uimm5:$rs2, GPR:$vl, vti.Log2SEW)>;
680}
681
682// 12.8. Vector Integer Comparison Instructions
683foreach vti = AllIntegerVectors in {
684  defm : VPatIntegerSetCCVL_VV<vti, "PseudoVMSEQ", SETEQ>;
685  defm : VPatIntegerSetCCVL_VV<vti, "PseudoVMSNE", SETNE>;
686
687  defm : VPatIntegerSetCCVL_VV_Swappable<vti, "PseudoVMSLT",  SETLT,  SETGT>;
688  defm : VPatIntegerSetCCVL_VV_Swappable<vti, "PseudoVMSLTU", SETULT, SETUGT>;
689  defm : VPatIntegerSetCCVL_VV_Swappable<vti, "PseudoVMSLE",  SETLE,  SETGE>;
690  defm : VPatIntegerSetCCVL_VV_Swappable<vti, "PseudoVMSLEU", SETULE, SETUGE>;
691
692  defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSEQ",  SETEQ,  SETEQ>;
693  defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSNE",  SETNE,  SETNE>;
694  defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSLT",  SETLT,  SETGT>;
695  defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSLTU", SETULT, SETUGT>;
696  defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSLE",  SETLE,  SETGE>;
697  defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSLEU", SETULE, SETUGE>;
698  defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSGT",  SETGT,  SETLT>;
699  defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSGTU", SETUGT, SETULT>;
700  // There is no VMSGE(U)_VX instruction
701
702  defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSEQ",  SETEQ,  SETEQ>;
703  defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSNE",  SETNE,  SETNE>;
704  defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSLE",  SETLE,  SETGE>;
705  defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSLEU", SETULE, SETUGE>;
706
707  defm : VPatIntegerSetCCVL_VIPlus1<vti, "PseudoVMSLE",  SETLT,
708                                    SplatPat_simm5_plus1>;
709  defm : VPatIntegerSetCCVL_VIPlus1<vti, "PseudoVMSLEU", SETULT,
710                                    SplatPat_simm5_plus1_nonzero>;
711  defm : VPatIntegerSetCCVL_VIPlus1<vti, "PseudoVMSGT",  SETGE,
712                                    SplatPat_simm5_plus1>;
713  defm : VPatIntegerSetCCVL_VIPlus1<vti, "PseudoVMSGTU", SETUGE,
714                                    SplatPat_simm5_plus1_nonzero>;
715} // foreach vti = AllIntegerVectors
716
717// 12.9. Vector Integer Min/Max Instructions
718defm : VPatBinaryVL_VV_VX<riscv_umin_vl, "PseudoVMINU">;
719defm : VPatBinaryVL_VV_VX<riscv_smin_vl, "PseudoVMIN">;
720defm : VPatBinaryVL_VV_VX<riscv_umax_vl, "PseudoVMAXU">;
721defm : VPatBinaryVL_VV_VX<riscv_smax_vl, "PseudoVMAX">;
722
723// 12.10. Vector Single-Width Integer Multiply Instructions
724defm : VPatBinaryVL_VV_VX<riscv_mul_vl, "PseudoVMUL">;
725defm : VPatBinaryVL_VV_VX<riscv_mulhs_vl, "PseudoVMULH">;
726defm : VPatBinaryVL_VV_VX<riscv_mulhu_vl, "PseudoVMULHU">;
727
728// 12.11. Vector Integer Divide Instructions
729defm : VPatBinaryVL_VV_VX<riscv_udiv_vl, "PseudoVDIVU">;
730defm : VPatBinaryVL_VV_VX<riscv_sdiv_vl, "PseudoVDIV">;
731defm : VPatBinaryVL_VV_VX<riscv_urem_vl, "PseudoVREMU">;
732defm : VPatBinaryVL_VV_VX<riscv_srem_vl, "PseudoVREM">;
733
734// 12.15. Vector Integer Merge Instructions
735foreach vti = AllIntegerVectors in {
736  def : Pat<(vti.Vector (riscv_vselect_vl (vti.Mask VMV0:$vm),
737                                          vti.RegClass:$rs1,
738                                          vti.RegClass:$rs2,
739                                          VLOpFrag)),
740            (!cast<Instruction>("PseudoVMERGE_VVM_"#vti.LMul.MX)
741                 vti.RegClass:$rs2, vti.RegClass:$rs1, VMV0:$vm,
742                 GPR:$vl, vti.Log2SEW)>;
743
744  def : Pat<(vti.Vector (riscv_vselect_vl (vti.Mask VMV0:$vm),
745                                          (SplatPat XLenVT:$rs1),
746                                          vti.RegClass:$rs2,
747                                          VLOpFrag)),
748            (!cast<Instruction>("PseudoVMERGE_VXM_"#vti.LMul.MX)
749                 vti.RegClass:$rs2, GPR:$rs1, VMV0:$vm, GPR:$vl, vti.Log2SEW)>;
750
751  def : Pat<(vti.Vector (riscv_vselect_vl (vti.Mask VMV0:$vm),
752                                          (SplatPat_simm5 simm5:$rs1),
753                                          vti.RegClass:$rs2,
754                                          VLOpFrag)),
755            (!cast<Instruction>("PseudoVMERGE_VIM_"#vti.LMul.MX)
756                 vti.RegClass:$rs2, simm5:$rs1, VMV0:$vm, GPR:$vl, vti.Log2SEW)>;
757}
758
759// 12.16. Vector Integer Move Instructions
760foreach vti = AllIntegerVectors in {
761  def : Pat<(vti.Vector (riscv_vmv_v_x_vl GPR:$rs2, VLOpFrag)),
762            (!cast<Instruction>("PseudoVMV_V_X_"#vti.LMul.MX)
763             $rs2, GPR:$vl, vti.Log2SEW)>;
764  defvar ImmPat = !cast<ComplexPattern>("sew"#vti.SEW#"simm5");
765  def : Pat<(vti.Vector (riscv_vmv_v_x_vl (ImmPat XLenVT:$imm5),
766                                          VLOpFrag)),
767            (!cast<Instruction>("PseudoVMV_V_I_"#vti.LMul.MX)
768             XLenVT:$imm5, GPR:$vl, vti.Log2SEW)>;
769}
770
771} // Predicates = [HasStdExtV]
772
773// 15.1. Vector Single-Width Integer Reduction Instructions
774let Predicates = [HasStdExtV] in {
775defm : VPatReductionVL<rvv_vecreduce_ADD_vl,  "PseudoVREDSUM", /*is_float*/0>;
776defm : VPatReductionVL<rvv_vecreduce_UMAX_vl, "PseudoVREDMAXU", /*is_float*/0>;
777defm : VPatReductionVL<rvv_vecreduce_SMAX_vl, "PseudoVREDMAX", /*is_float*/0>;
778defm : VPatReductionVL<rvv_vecreduce_UMIN_vl, "PseudoVREDMINU", /*is_float*/0>;
779defm : VPatReductionVL<rvv_vecreduce_SMIN_vl, "PseudoVREDMIN", /*is_float*/0>;
780defm : VPatReductionVL<rvv_vecreduce_AND_vl,  "PseudoVREDAND", /*is_float*/0>;
781defm : VPatReductionVL<rvv_vecreduce_OR_vl,   "PseudoVREDOR", /*is_float*/0>;
782defm : VPatReductionVL<rvv_vecreduce_XOR_vl,  "PseudoVREDXOR", /*is_float*/0>;
783} // Predicates = [HasStdExtV]
784
785// 15.3. Vector Single-Width Floating-Point Reduction Instructions
786let Predicates = [HasStdExtV, HasStdExtF] in {
787defm : VPatReductionVL<rvv_vecreduce_SEQ_FADD_vl, "PseudoVFREDOSUM", /*is_float*/1>;
788defm : VPatReductionVL<rvv_vecreduce_FADD_vl,     "PseudoVFREDSUM", /*is_float*/1>;
789defm : VPatReductionVL<rvv_vecreduce_FMIN_vl,     "PseudoVFREDMIN", /*is_float*/1>;
790defm : VPatReductionVL<rvv_vecreduce_FMAX_vl,     "PseudoVFREDMAX", /*is_float*/1>;
791} // Predicates = [HasStdExtV, HasStdExtF]
792
793let Predicates = [HasStdExtV, HasStdExtF] in {
794
795// 14.2. Vector Single-Width Floating-Point Add/Subtract Instructions
796defm : VPatBinaryFPVL_VV_VF<riscv_fadd_vl, "PseudoVFADD">;
797defm : VPatBinaryFPVL_VV_VF<riscv_fsub_vl, "PseudoVFSUB">;
798defm : VPatBinaryFPVL_R_VF<riscv_fsub_vl, "PseudoVFRSUB">;
799
800// 14.4. Vector Single-Width Floating-Point Multiply/Divide Instructions
801defm : VPatBinaryFPVL_VV_VF<riscv_fmul_vl, "PseudoVFMUL">;
802defm : VPatBinaryFPVL_VV_VF<riscv_fdiv_vl, "PseudoVFDIV">;
803defm : VPatBinaryFPVL_R_VF<riscv_fdiv_vl, "PseudoVFRDIV">;
804
805// 14.6 Vector Single-Width Floating-Point Fused Multiply-Add Instructions.
806foreach vti = AllFloatVectors in {
807  // NOTE: We choose VFMADD because it has the most commuting freedom. So it
808  // works best with how TwoAddressInstructionPass tries commuting.
809  defvar suffix = vti.LMul.MX # "_COMMUTABLE";
810  def : Pat<(vti.Vector (riscv_fma_vl vti.RegClass:$rs1, vti.RegClass:$rd,
811                                      vti.RegClass:$rs2, (vti.Mask true_mask),
812                                      VLOpFrag)),
813            (!cast<Instruction>("PseudoVFMADD_VV_"# suffix)
814                 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2,
815                 GPR:$vl, vti.Log2SEW)>;
816  def : Pat<(vti.Vector (riscv_fma_vl vti.RegClass:$rs1, vti.RegClass:$rd,
817                                      (riscv_fneg_vl vti.RegClass:$rs2,
818                                                     (vti.Mask true_mask),
819                                                     VLOpFrag),
820                                      (vti.Mask true_mask),
821                                      VLOpFrag)),
822            (!cast<Instruction>("PseudoVFMSUB_VV_"# suffix)
823                 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2,
824                 GPR:$vl, vti.Log2SEW)>;
825  def : Pat<(vti.Vector (riscv_fma_vl (riscv_fneg_vl vti.RegClass:$rs1,
826                                                     (vti.Mask true_mask),
827                                                     VLOpFrag),
828                                      vti.RegClass:$rd,
829                                      (riscv_fneg_vl vti.RegClass:$rs2,
830                                                     (vti.Mask true_mask),
831                                                     VLOpFrag),
832                                      (vti.Mask true_mask),
833                                      VLOpFrag)),
834            (!cast<Instruction>("PseudoVFNMADD_VV_"# suffix)
835                 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2,
836                 GPR:$vl, vti.Log2SEW)>;
837  def : Pat<(vti.Vector (riscv_fma_vl (riscv_fneg_vl vti.RegClass:$rs1,
838                                                     (vti.Mask true_mask),
839                                                     VLOpFrag),
840                                      vti.RegClass:$rd, vti.RegClass:$rs2,
841                                      (vti.Mask true_mask),
842                                      VLOpFrag)),
843            (!cast<Instruction>("PseudoVFNMSUB_VV_"# suffix)
844                 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2,
845                 GPR:$vl, vti.Log2SEW)>;
846
847  // The choice of VFMADD here is arbitrary, vfmadd.vf and vfmacc.vf are equally
848  // commutable.
849  def : Pat<(vti.Vector (riscv_fma_vl (SplatFPOp vti.ScalarRegClass:$rs1),
850                                       vti.RegClass:$rd, vti.RegClass:$rs2,
851                                       (vti.Mask true_mask),
852                                       VLOpFrag)),
853            (!cast<Instruction>("PseudoVFMADD_V" # vti.ScalarSuffix # "_" # suffix)
854                 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2,
855                 GPR:$vl, vti.Log2SEW)>;
856  def : Pat<(vti.Vector (riscv_fma_vl (SplatFPOp vti.ScalarRegClass:$rs1),
857                                       vti.RegClass:$rd,
858                                       (riscv_fneg_vl vti.RegClass:$rs2,
859                                                      (vti.Mask true_mask),
860                                                      VLOpFrag),
861                                       (vti.Mask true_mask),
862                                       VLOpFrag)),
863            (!cast<Instruction>("PseudoVFMSUB_V" # vti.ScalarSuffix # "_" # suffix)
864                 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2,
865                 GPR:$vl, vti.Log2SEW)>;
866  def : Pat<(vti.Vector (riscv_fma_vl (SplatFPOp vti.ScalarRegClass:$rs1),
867                                       (riscv_fneg_vl vti.RegClass:$rd,
868                                                      (vti.Mask true_mask),
869                                                      VLOpFrag),
870                                       (riscv_fneg_vl vti.RegClass:$rs2,
871                                                      (vti.Mask true_mask),
872                                                      VLOpFrag),
873                                       (vti.Mask true_mask),
874                                       VLOpFrag)),
875            (!cast<Instruction>("PseudoVFNMADD_V" # vti.ScalarSuffix # "_" # suffix)
876                 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2,
877                 GPR:$vl, vti.Log2SEW)>;
878  def : Pat<(vti.Vector (riscv_fma_vl (SplatFPOp vti.ScalarRegClass:$rs1),
879                                       (riscv_fneg_vl vti.RegClass:$rd,
880                                                      (vti.Mask true_mask),
881                                                      VLOpFrag),
882                                       vti.RegClass:$rs2,
883                                       (vti.Mask true_mask),
884                                       VLOpFrag)),
885            (!cast<Instruction>("PseudoVFNMSUB_V" # vti.ScalarSuffix # "_" # suffix)
886                 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2,
887                 GPR:$vl, vti.Log2SEW)>;
888
889  // The splat might be negated.
890  def : Pat<(vti.Vector (riscv_fma_vl (riscv_fneg_vl (SplatFPOp vti.ScalarRegClass:$rs1),
891                                                     (vti.Mask true_mask),
892                                                     VLOpFrag),
893                                       vti.RegClass:$rd,
894                                       (riscv_fneg_vl vti.RegClass:$rs2,
895                                                      (vti.Mask true_mask),
896                                                      VLOpFrag),
897                                       (vti.Mask true_mask),
898                                       VLOpFrag)),
899            (!cast<Instruction>("PseudoVFNMADD_V" # vti.ScalarSuffix # "_" # suffix)
900                 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2,
901                 GPR:$vl, vti.Log2SEW)>;
902  def : Pat<(vti.Vector (riscv_fma_vl (riscv_fneg_vl (SplatFPOp vti.ScalarRegClass:$rs1),
903                                                     (vti.Mask true_mask),
904                                                     VLOpFrag),
905                                       vti.RegClass:$rd, vti.RegClass:$rs2,
906                                       (vti.Mask true_mask),
907                                       VLOpFrag)),
908            (!cast<Instruction>("PseudoVFNMSUB_V" # vti.ScalarSuffix # "_" # suffix)
909                 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2,
910                 GPR:$vl, vti.Log2SEW)>;
911}
912
913// 14.11. Vector Floating-Point MIN/MAX Instructions
914defm : VPatBinaryFPVL_VV_VF<riscv_fminnum_vl, "PseudoVFMIN">;
915defm : VPatBinaryFPVL_VV_VF<riscv_fmaxnum_vl, "PseudoVFMAX">;
916
917// 14.13. Vector Floating-Point Compare Instructions
918defm : VPatFPSetCCVL_VV_VF_FV<SETEQ,  "PseudoVMFEQ", "PseudoVMFEQ">;
919defm : VPatFPSetCCVL_VV_VF_FV<SETOEQ, "PseudoVMFEQ", "PseudoVMFEQ">;
920
921defm : VPatFPSetCCVL_VV_VF_FV<SETNE,  "PseudoVMFNE", "PseudoVMFNE">;
922defm : VPatFPSetCCVL_VV_VF_FV<SETUNE, "PseudoVMFNE", "PseudoVMFNE">;
923
924defm : VPatFPSetCCVL_VV_VF_FV<SETLT,  "PseudoVMFLT", "PseudoVMFGT">;
925defm : VPatFPSetCCVL_VV_VF_FV<SETOLT, "PseudoVMFLT", "PseudoVMFGT">;
926
927defm : VPatFPSetCCVL_VV_VF_FV<SETLE,  "PseudoVMFLE", "PseudoVMFGE">;
928defm : VPatFPSetCCVL_VV_VF_FV<SETOLE, "PseudoVMFLE", "PseudoVMFGE">;
929
930foreach vti = AllFloatVectors in {
931  // 14.8. Vector Floating-Point Square-Root Instruction
932  def : Pat<(riscv_fsqrt_vl (vti.Vector vti.RegClass:$rs2), (vti.Mask true_mask),
933                            VLOpFrag),
934            (!cast<Instruction>("PseudoVFSQRT_V_"# vti.LMul.MX)
935                 vti.RegClass:$rs2, GPR:$vl, vti.Log2SEW)>;
936
937  // 14.12. Vector Floating-Point Sign-Injection Instructions
938  def : Pat<(riscv_fabs_vl (vti.Vector vti.RegClass:$rs), (vti.Mask true_mask),
939                           VLOpFrag),
940            (!cast<Instruction>("PseudoVFSGNJX_VV_"# vti.LMul.MX)
941                 vti.RegClass:$rs, vti.RegClass:$rs, GPR:$vl, vti.Log2SEW)>;
942  // Handle fneg with VFSGNJN using the same input for both operands.
943  def : Pat<(riscv_fneg_vl (vti.Vector vti.RegClass:$rs), (vti.Mask true_mask),
944                           VLOpFrag),
945            (!cast<Instruction>("PseudoVFSGNJN_VV_"# vti.LMul.MX)
946                 vti.RegClass:$rs, vti.RegClass:$rs, GPR:$vl, vti.Log2SEW)>;
947  def : Pat<(riscv_fcopysign_vl (vti.Vector vti.RegClass:$rs1),
948                                (vti.Vector vti.RegClass:$rs2),
949                                (vti.Mask true_mask),
950                                VLOpFrag),
951            (!cast<Instruction>("PseudoVFSGNJ_VV_"# vti.LMul.MX)
952                 vti.RegClass:$rs1, vti.RegClass:$rs2, GPR:$vl, vti.Log2SEW)>;
953  def : Pat<(riscv_fcopysign_vl (vti.Vector vti.RegClass:$rs1),
954                                (riscv_fneg_vl vti.RegClass:$rs2,
955                                               (vti.Mask true_mask),
956                                               VLOpFrag),
957                                (vti.Mask true_mask),
958                                VLOpFrag),
959            (!cast<Instruction>("PseudoVFSGNJN_VV_"# vti.LMul.MX)
960                 vti.RegClass:$rs1, vti.RegClass:$rs2, GPR:$vl, vti.Log2SEW)>;
961
962  def : Pat<(riscv_fcopysign_vl (vti.Vector vti.RegClass:$rs1),
963                                (SplatFPOp vti.ScalarRegClass:$rs2),
964                                (vti.Mask true_mask),
965                                VLOpFrag),
966            (!cast<Instruction>("PseudoVFSGNJ_V"#vti.ScalarSuffix#"_"# vti.LMul.MX)
967                 vti.RegClass:$rs1, vti.ScalarRegClass:$rs2, GPR:$vl, vti.Log2SEW)>;
968}
969
970foreach fvti = AllFloatVectors in {
971  // Floating-point vselects:
972  // 12.15. Vector Integer Merge Instructions
973  // 14.15. Vector Floating-Point Merge Instruction
974  def : Pat<(fvti.Vector (riscv_vselect_vl (fvti.Mask VMV0:$vm),
975                                           fvti.RegClass:$rs1,
976                                           fvti.RegClass:$rs2,
977                                           VLOpFrag)),
978            (!cast<Instruction>("PseudoVMERGE_VVM_"#fvti.LMul.MX)
979                 fvti.RegClass:$rs2, fvti.RegClass:$rs1, VMV0:$vm,
980                 GPR:$vl, fvti.Log2SEW)>;
981
982  def : Pat<(fvti.Vector (riscv_vselect_vl (fvti.Mask VMV0:$vm),
983                                           (SplatFPOp fvti.ScalarRegClass:$rs1),
984                                           fvti.RegClass:$rs2,
985                                           VLOpFrag)),
986            (!cast<Instruction>("PseudoVFMERGE_V"#fvti.ScalarSuffix#"M_"#fvti.LMul.MX)
987                 fvti.RegClass:$rs2,
988                 (fvti.Scalar fvti.ScalarRegClass:$rs1),
989                 VMV0:$vm, GPR:$vl, fvti.Log2SEW)>;
990
991  def : Pat<(fvti.Vector (riscv_vselect_vl (fvti.Mask VMV0:$vm),
992                                           (SplatFPOp (fvti.Scalar fpimm0)),
993                                           fvti.RegClass:$rs2,
994                                           VLOpFrag)),
995            (!cast<Instruction>("PseudoVMERGE_VIM_"#fvti.LMul.MX)
996                 fvti.RegClass:$rs2, 0, VMV0:$vm, GPR:$vl, fvti.Log2SEW)>;
997
998  // 14.16. Vector Floating-Point Move Instruction
999  // If we're splatting fpimm0, use vmv.v.x vd, x0.
1000  def : Pat<(fvti.Vector (riscv_vfmv_v_f_vl
1001                         (fvti.Scalar (fpimm0)), VLOpFrag)),
1002            (!cast<Instruction>("PseudoVMV_V_I_"#fvti.LMul.MX)
1003             0, GPR:$vl, fvti.Log2SEW)>;
1004
1005  def : Pat<(fvti.Vector (riscv_vfmv_v_f_vl
1006                         (fvti.Scalar fvti.ScalarRegClass:$rs2), VLOpFrag)),
1007            (!cast<Instruction>("PseudoVFMV_V_" # fvti.ScalarSuffix # "_" #
1008                                fvti.LMul.MX)
1009             (fvti.Scalar fvti.ScalarRegClass:$rs2),
1010             GPR:$vl, fvti.Log2SEW)>;
1011
1012  // 14.17. Vector Single-Width Floating-Point/Integer Type-Convert Instructions
1013  defm : VPatConvertFP2ISDNode_V_VL<riscv_fp_to_sint_vl, "PseudoVFCVT_RTZ_X_F_V">;
1014  defm : VPatConvertFP2ISDNode_V_VL<riscv_fp_to_uint_vl, "PseudoVFCVT_RTZ_XU_F_V">;
1015  defm : VPatConvertI2FPSDNode_V_VL<riscv_sint_to_fp_vl, "PseudoVFCVT_F_X_V">;
1016  defm : VPatConvertI2FPSDNode_V_VL<riscv_uint_to_fp_vl, "PseudoVFCVT_F_XU_V">;
1017
1018  // 14.18. Widening Floating-Point/Integer Type-Convert Instructions
1019  defm : VPatWConvertFP2ISDNode_V_VL<riscv_fp_to_sint_vl, "PseudoVFWCVT_RTZ_X_F_V">;
1020  defm : VPatWConvertFP2ISDNode_V_VL<riscv_fp_to_uint_vl, "PseudoVFWCVT_RTZ_XU_F_V">;
1021  defm : VPatWConvertI2FPSDNode_V_VL<riscv_sint_to_fp_vl, "PseudoVFWCVT_F_X_V">;
1022  defm : VPatWConvertI2FPSDNode_V_VL<riscv_uint_to_fp_vl, "PseudoVFWCVT_F_XU_V">;
1023  foreach fvtiToFWti = AllWidenableFloatVectors in {
1024    defvar fvti = fvtiToFWti.Vti;
1025    defvar fwti = fvtiToFWti.Wti;
1026    def : Pat<(fwti.Vector (riscv_fpextend_vl (fvti.Vector fvti.RegClass:$rs1),
1027                                              (fvti.Mask true_mask),
1028                                              VLOpFrag)),
1029              (!cast<Instruction>("PseudoVFWCVT_F_F_V_"#fvti.LMul.MX)
1030                  fvti.RegClass:$rs1, GPR:$vl, fvti.Log2SEW)>;
1031  }
1032
1033  // 14.19 Narrowing Floating-Point/Integer Type-Convert Instructions
1034  defm : VPatNConvertFP2ISDNode_V_VL<riscv_fp_to_sint_vl, "PseudoVFNCVT_RTZ_X_F_W">;
1035  defm : VPatNConvertFP2ISDNode_V_VL<riscv_fp_to_uint_vl, "PseudoVFNCVT_RTZ_XU_F_W">;
1036  defm : VPatNConvertI2FPSDNode_V_VL<riscv_sint_to_fp_vl, "PseudoVFNCVT_F_X_W">;
1037  defm : VPatNConvertI2FPSDNode_V_VL<riscv_uint_to_fp_vl, "PseudoVFNCVT_F_XU_W">;
1038  foreach fvtiToFWti = AllWidenableFloatVectors in {
1039    defvar fvti = fvtiToFWti.Vti;
1040    defvar fwti = fvtiToFWti.Wti;
1041    def : Pat<(fvti.Vector (riscv_fpround_vl (fwti.Vector fwti.RegClass:$rs1),
1042                                             (fwti.Mask true_mask),
1043                                             VLOpFrag)),
1044              (!cast<Instruction>("PseudoVFNCVT_F_F_W_"#fvti.LMul.MX)
1045                  fwti.RegClass:$rs1, GPR:$vl, fvti.Log2SEW)>;
1046
1047    def : Pat<(fvti.Vector (riscv_fncvt_rod_vl (fwti.Vector fwti.RegClass:$rs1),
1048                                               (fwti.Mask true_mask),
1049                                               VLOpFrag)),
1050              (!cast<Instruction>("PseudoVFNCVT_ROD_F_F_W_"#fvti.LMul.MX)
1051                  fwti.RegClass:$rs1, GPR:$vl, fvti.Log2SEW)>;
1052  }
1053}
1054
1055} // Predicates = [HasStdExtV, HasStdExtF]
1056
1057let Predicates = [HasStdExtV] in {
1058
1059foreach mti = AllMasks in {
1060  // 16.1 Vector Mask-Register Logical Instructions
1061  def : Pat<(mti.Mask (riscv_vmset_vl VLOpFrag)),
1062            (!cast<Instruction>("PseudoVMSET_M_" # mti.BX) GPR:$vl, mti.Log2SEW)>;
1063  def : Pat<(mti.Mask (riscv_vmclr_vl VLOpFrag)),
1064            (!cast<Instruction>("PseudoVMCLR_M_" # mti.BX) GPR:$vl, mti.Log2SEW)>;
1065
1066  def : Pat<(mti.Mask (riscv_vmand_vl VR:$rs1, VR:$rs2, VLOpFrag)),
1067            (!cast<Instruction>("PseudoVMAND_MM_" # mti.LMul.MX)
1068                 VR:$rs1, VR:$rs2, GPR:$vl, mti.Log2SEW)>;
1069  def : Pat<(mti.Mask (riscv_vmor_vl VR:$rs1, VR:$rs2, VLOpFrag)),
1070            (!cast<Instruction>("PseudoVMOR_MM_" # mti.LMul.MX)
1071                 VR:$rs1, VR:$rs2, GPR:$vl, mti.Log2SEW)>;
1072  def : Pat<(mti.Mask (riscv_vmxor_vl VR:$rs1, VR:$rs2, VLOpFrag)),
1073            (!cast<Instruction>("PseudoVMXOR_MM_" # mti.LMul.MX)
1074                 VR:$rs1, VR:$rs2, GPR:$vl, mti.Log2SEW)>;
1075
1076  def : Pat<(mti.Mask (riscv_vmand_vl VR:$rs1,
1077                                      (riscv_vmnot_vl VR:$rs2, VLOpFrag),
1078                                      VLOpFrag)),
1079            (!cast<Instruction>("PseudoVMANDNOT_MM_" # mti.LMul.MX)
1080                 VR:$rs1, VR:$rs2, GPR:$vl, mti.Log2SEW)>;
1081  def : Pat<(mti.Mask (riscv_vmor_vl VR:$rs1,
1082                                     (riscv_vmnot_vl VR:$rs2, VLOpFrag),
1083                                     VLOpFrag)),
1084            (!cast<Instruction>("PseudoVMORNOT_MM_" # mti.LMul.MX)
1085                 VR:$rs1, VR:$rs2, GPR:$vl, mti.Log2SEW)>;
1086  // XOR is associative so we need 2 patterns for VMXNOR.
1087  def : Pat<(mti.Mask (riscv_vmxor_vl (riscv_vmnot_vl VR:$rs1,
1088                                                      VLOpFrag),
1089                                     VR:$rs2, VLOpFrag)),
1090            (!cast<Instruction>("PseudoVMXNOR_MM_" # mti.LMul.MX)
1091                 VR:$rs1, VR:$rs2, GPR:$vl, mti.Log2SEW)>;
1092
1093  def : Pat<(mti.Mask (riscv_vmnot_vl (riscv_vmand_vl VR:$rs1, VR:$rs2,
1094                                                      VLOpFrag),
1095                                      VLOpFrag)),
1096            (!cast<Instruction>("PseudoVMNAND_MM_" # mti.LMul.MX)
1097                 VR:$rs1, VR:$rs2, GPR:$vl, mti.Log2SEW)>;
1098  def : Pat<(mti.Mask (riscv_vmnot_vl (riscv_vmor_vl VR:$rs1, VR:$rs2,
1099                                                     VLOpFrag),
1100                                      VLOpFrag)),
1101            (!cast<Instruction>("PseudoVMNOR_MM_" # mti.LMul.MX)
1102                 VR:$rs1, VR:$rs2, GPR:$vl, mti.Log2SEW)>;
1103  def : Pat<(mti.Mask (riscv_vmnot_vl (riscv_vmxor_vl VR:$rs1, VR:$rs2,
1104                                                      VLOpFrag),
1105                                      VLOpFrag)),
1106            (!cast<Instruction>("PseudoVMXNOR_MM_" # mti.LMul.MX)
1107                 VR:$rs1, VR:$rs2, GPR:$vl, mti.Log2SEW)>;
1108
1109  // Match the not idiom to the vmnot.m pseudo.
1110  def : Pat<(mti.Mask (riscv_vmnot_vl VR:$rs, VLOpFrag)),
1111            (!cast<Instruction>("PseudoVMNAND_MM_" # mti.LMul.MX)
1112                 VR:$rs, VR:$rs, GPR:$vl, mti.Log2SEW)>;
1113
1114  // 16.2 Vector Mask Population Count vpopc
1115  def : Pat<(XLenVT (riscv_vpopc_vl (mti.Mask VR:$rs2), (mti.Mask true_mask),
1116                                    VLOpFrag)),
1117            (!cast<Instruction>("PseudoVPOPC_M_" # mti.BX)
1118                 VR:$rs2, GPR:$vl, mti.Log2SEW)>;
1119}
1120
1121} // Predicates = [HasStdExtV]
1122
1123let Predicates = [HasStdExtV] in {
1124// 17.1. Integer Scalar Move Instructions
1125// 17.4. Vector Register Gather Instruction
1126foreach vti = AllIntegerVectors in {
1127  def : Pat<(vti.Vector (riscv_vmv_s_x_vl (vti.Vector vti.RegClass:$merge),
1128                                          vti.ScalarRegClass:$rs1,
1129                                          VLOpFrag)),
1130            (!cast<Instruction>("PseudoVMV_S_X_"#vti.LMul.MX)
1131                vti.RegClass:$merge,
1132                (vti.Scalar vti.ScalarRegClass:$rs1), GPR:$vl, vti.Log2SEW)>;
1133  def : Pat<(vti.Vector (riscv_vrgather_vv_vl vti.RegClass:$rs2,
1134                                              (vti.Vector vti.RegClass:$rs1),
1135                                              (vti.Mask true_mask),
1136                                              VLOpFrag)),
1137            (!cast<Instruction>("PseudoVRGATHER_VV_"# vti.LMul.MX)
1138                 vti.RegClass:$rs2, vti.RegClass:$rs1, GPR:$vl, vti.Log2SEW)>;
1139  def : Pat<(vti.Vector (riscv_vrgather_vx_vl vti.RegClass:$rs2, GPR:$rs1,
1140                                              (vti.Mask true_mask),
1141                                              VLOpFrag)),
1142            (!cast<Instruction>("PseudoVRGATHER_VX_"# vti.LMul.MX)
1143                 vti.RegClass:$rs2, GPR:$rs1, GPR:$vl, vti.Log2SEW)>;
1144  def : Pat<(vti.Vector (riscv_vrgather_vx_vl vti.RegClass:$rs2, uimm5:$imm,
1145                                              (vti.Mask true_mask),
1146                                              VLOpFrag)),
1147            (!cast<Instruction>("PseudoVRGATHER_VI_"# vti.LMul.MX)
1148                 vti.RegClass:$rs2, uimm5:$imm, GPR:$vl, vti.Log2SEW)>;
1149
1150  def : Pat<(vti.Vector (riscv_vselect_vl (vti.Mask VMV0:$vm),
1151                                          (riscv_vrgather_vv_vl
1152                                            vti.RegClass:$rs2,
1153                                            vti.RegClass:$rs1,
1154                                            (vti.Mask true_mask),
1155                                            VLOpFrag),
1156                                          vti.RegClass:$merge,
1157                                          VLOpFrag)),
1158            (!cast<Instruction>("PseudoVRGATHER_VV_"# vti.LMul.MX#"_MASK")
1159                 vti.RegClass:$merge, vti.RegClass:$rs2, vti.RegClass:$rs1,
1160                 vti.Mask:$vm, GPR:$vl, vti.Log2SEW)>;
1161
1162  // emul = lmul * 16 / sew
1163  defvar vlmul = vti.LMul;
1164  defvar octuple_lmul = vlmul.octuple;
1165  defvar octuple_emul = !srl(!mul(octuple_lmul, 16), vti.Log2SEW);
1166  if !and(!ge(octuple_emul, 1), !le(octuple_emul, 64)) then {
1167    defvar emul_str = octuple_to_str<octuple_emul>.ret;
1168    defvar ivti = !cast<VTypeInfo>("VI16" # emul_str);
1169    defvar inst = "PseudoVRGATHEREI16_VV_" # vti.LMul.MX # "_" # emul_str;
1170    def : Pat<(vti.Vector (riscv_vrgatherei16_vv_vl vti.RegClass:$rs2,
1171                                                    (ivti.Vector ivti.RegClass:$rs1),
1172                                                    (vti.Mask true_mask),
1173                                                    VLOpFrag)),
1174              (!cast<Instruction>(inst)
1175                   vti.RegClass:$rs2, ivti.RegClass:$rs1, GPR:$vl, vti.Log2SEW)>;
1176
1177    def : Pat<(vti.Vector (riscv_vselect_vl (vti.Mask VMV0:$vm),
1178                                            (riscv_vrgatherei16_vv_vl
1179                                              vti.RegClass:$rs2,
1180                                              (ivti.Vector ivti.RegClass:$rs1),
1181                                              (vti.Mask true_mask),
1182                                              VLOpFrag),
1183                                            vti.RegClass:$merge,
1184                                            VLOpFrag)),
1185              (!cast<Instruction>(inst#"_MASK")
1186                   vti.RegClass:$merge, vti.RegClass:$rs2, ivti.RegClass:$rs1,
1187                   vti.Mask:$vm, GPR:$vl, vti.Log2SEW)>;
1188  }
1189}
1190
1191} // Predicates = [HasStdExtV]
1192
1193let Predicates = [HasStdExtV, HasStdExtF] in {
1194
1195// 17.2. Floating-Point Scalar Move Instructions
1196foreach vti = AllFloatVectors in {
1197  def : Pat<(vti.Vector (riscv_vfmv_s_f_vl (vti.Vector vti.RegClass:$merge),
1198                                           vti.ScalarRegClass:$rs1,
1199                                           VLOpFrag)),
1200            (!cast<Instruction>("PseudoVFMV_S_"#vti.ScalarSuffix#"_"#vti.LMul.MX)
1201                vti.RegClass:$merge,
1202                (vti.Scalar vti.ScalarRegClass:$rs1), GPR:$vl, vti.Log2SEW)>;
1203  defvar ivti = GetIntVTypeInfo<vti>.Vti;
1204  def : Pat<(vti.Vector (riscv_vrgather_vv_vl vti.RegClass:$rs2,
1205                                              (ivti.Vector vti.RegClass:$rs1),
1206                                              (vti.Mask true_mask),
1207                                              VLOpFrag)),
1208            (!cast<Instruction>("PseudoVRGATHER_VV_"# vti.LMul.MX)
1209                 vti.RegClass:$rs2, vti.RegClass:$rs1, GPR:$vl, vti.Log2SEW)>;
1210  def : Pat<(vti.Vector (riscv_vrgather_vx_vl vti.RegClass:$rs2, GPR:$rs1,
1211                                              (vti.Mask true_mask),
1212                                              VLOpFrag)),
1213            (!cast<Instruction>("PseudoVRGATHER_VX_"# vti.LMul.MX)
1214                 vti.RegClass:$rs2, GPR:$rs1, GPR:$vl, vti.Log2SEW)>;
1215  def : Pat<(vti.Vector (riscv_vrgather_vx_vl vti.RegClass:$rs2, uimm5:$imm,
1216                                              (vti.Mask true_mask),
1217                                              VLOpFrag)),
1218            (!cast<Instruction>("PseudoVRGATHER_VI_"# vti.LMul.MX)
1219                 vti.RegClass:$rs2, uimm5:$imm, GPR:$vl, vti.Log2SEW)>;
1220
1221  def : Pat<(vti.Vector (riscv_vselect_vl (vti.Mask VMV0:$vm),
1222                                          (riscv_vrgather_vv_vl
1223                                            vti.RegClass:$rs2,
1224                                            (ivti.Vector vti.RegClass:$rs1),
1225                                            (vti.Mask true_mask),
1226                                            VLOpFrag),
1227                                          vti.RegClass:$merge,
1228                                          VLOpFrag)),
1229            (!cast<Instruction>("PseudoVRGATHER_VV_"# vti.LMul.MX#"_MASK")
1230                 vti.RegClass:$merge, vti.RegClass:$rs2, vti.RegClass:$rs1,
1231                 vti.Mask:$vm, GPR:$vl, vti.Log2SEW)>;
1232
1233  defvar vlmul = vti.LMul;
1234  defvar octuple_lmul = vlmul.octuple;
1235  defvar octuple_emul = !srl(!mul(octuple_lmul, 16), vti.Log2SEW);
1236  if !and(!ge(octuple_emul, 1), !le(octuple_emul, 64)) then {
1237    defvar emul_str = octuple_to_str<octuple_emul>.ret;
1238    defvar ivti = !cast<VTypeInfo>("VI16" # emul_str);
1239    defvar inst = "PseudoVRGATHEREI16_VV_" # vti.LMul.MX # "_" # emul_str;
1240    def : Pat<(vti.Vector (riscv_vrgatherei16_vv_vl vti.RegClass:$rs2,
1241                                                    (ivti.Vector ivti.RegClass:$rs1),
1242                                                    (vti.Mask true_mask),
1243                                                    VLOpFrag)),
1244              (!cast<Instruction>(inst)
1245                   vti.RegClass:$rs2, ivti.RegClass:$rs1, GPR:$vl, vti.Log2SEW)>;
1246
1247    def : Pat<(vti.Vector (riscv_vselect_vl (vti.Mask VMV0:$vm),
1248                                            (riscv_vrgatherei16_vv_vl
1249                                              vti.RegClass:$rs2,
1250                                              (ivti.Vector ivti.RegClass:$rs1),
1251                                              (vti.Mask true_mask),
1252                                              VLOpFrag),
1253                                            vti.RegClass:$merge,
1254                                            VLOpFrag)),
1255              (!cast<Instruction>(inst#"_MASK")
1256                   vti.RegClass:$merge, vti.RegClass:$rs2, ivti.RegClass:$rs1,
1257                   vti.Mask:$vm, GPR:$vl, vti.Log2SEW)>;
1258  }
1259}
1260
1261} // Predicates = [HasStdExtV, HasStdExtF]
1262
1263//===----------------------------------------------------------------------===//
1264// Miscellaneous RISCVISD SDNodes
1265//===----------------------------------------------------------------------===//
1266
1267def riscv_vid_vl : SDNode<"RISCVISD::VID_VL", SDTypeProfile<1, 2,
1268                          [SDTCisVec<0>, SDTCVecEltisVT<1, i1>,
1269                           SDTCisSameNumEltsAs<0, 1>, SDTCisVT<2, XLenVT>]>, []>;
1270
1271def SDTRVVSlide : SDTypeProfile<1, 5, [
1272  SDTCisVec<0>, SDTCisSameAs<1, 0>, SDTCisSameAs<2, 0>, SDTCisVT<3, XLenVT>,
1273  SDTCVecEltisVT<4, i1>, SDTCisSameNumEltsAs<0, 4>, SDTCisVT<5, XLenVT>
1274]>;
1275def SDTRVVSlide1 : SDTypeProfile<1, 4, [
1276  SDTCisVec<0>, SDTCisSameAs<1, 0>, SDTCisInt<0>, SDTCisVT<2, XLenVT>,
1277  SDTCVecEltisVT<3, i1>, SDTCisSameNumEltsAs<0, 3>, SDTCisVT<4, XLenVT>
1278]>;
1279
1280def riscv_slideup_vl   : SDNode<"RISCVISD::VSLIDEUP_VL", SDTRVVSlide, []>;
1281def riscv_slide1up_vl  : SDNode<"RISCVISD::VSLIDE1UP_VL", SDTRVVSlide1, []>;
1282def riscv_slidedown_vl : SDNode<"RISCVISD::VSLIDEDOWN_VL", SDTRVVSlide, []>;
1283def riscv_slide1down_vl  : SDNode<"RISCVISD::VSLIDE1DOWN_VL", SDTRVVSlide1, []>;
1284
1285let Predicates = [HasStdExtV] in {
1286
1287foreach vti = AllIntegerVectors in {
1288  def : Pat<(vti.Vector (riscv_vid_vl (vti.Mask true_mask),
1289                                      VLOpFrag)),
1290            (!cast<Instruction>("PseudoVID_V_"#vti.LMul.MX) GPR:$vl, vti.Log2SEW)>;
1291
1292  def : Pat<(vti.Vector (riscv_slide1up_vl (vti.Vector vti.RegClass:$rs1),
1293                                           GPR:$rs2, (vti.Mask true_mask),
1294                                           VLOpFrag)),
1295            (!cast<Instruction>("PseudoVSLIDE1UP_VX_"#vti.LMul.MX)
1296                vti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.Log2SEW)>;
1297  def : Pat<(vti.Vector (riscv_slide1down_vl (vti.Vector vti.RegClass:$rs1),
1298                                           GPR:$rs2, (vti.Mask true_mask),
1299                                           VLOpFrag)),
1300            (!cast<Instruction>("PseudoVSLIDE1DOWN_VX_"#vti.LMul.MX)
1301                vti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.Log2SEW)>;
1302}
1303
1304foreach vti = !listconcat(AllIntegerVectors, AllFloatVectors) in {
1305  def : Pat<(vti.Vector (riscv_slideup_vl (vti.Vector vti.RegClass:$rs3),
1306                                          (vti.Vector vti.RegClass:$rs1),
1307                                          uimm5:$rs2, (vti.Mask true_mask),
1308                                          VLOpFrag)),
1309            (!cast<Instruction>("PseudoVSLIDEUP_VI_"#vti.LMul.MX)
1310                vti.RegClass:$rs3, vti.RegClass:$rs1, uimm5:$rs2,
1311                GPR:$vl, vti.Log2SEW)>;
1312
1313  def : Pat<(vti.Vector (riscv_slideup_vl (vti.Vector vti.RegClass:$rs3),
1314                                          (vti.Vector vti.RegClass:$rs1),
1315                                          GPR:$rs2, (vti.Mask true_mask),
1316                                          VLOpFrag)),
1317            (!cast<Instruction>("PseudoVSLIDEUP_VX_"#vti.LMul.MX)
1318                vti.RegClass:$rs3, vti.RegClass:$rs1, GPR:$rs2,
1319                GPR:$vl, vti.Log2SEW)>;
1320
1321  def : Pat<(vti.Vector (riscv_slidedown_vl (vti.Vector vti.RegClass:$rs3),
1322                                            (vti.Vector vti.RegClass:$rs1),
1323                                            uimm5:$rs2, (vti.Mask true_mask),
1324                                            VLOpFrag)),
1325            (!cast<Instruction>("PseudoVSLIDEDOWN_VI_"#vti.LMul.MX)
1326                vti.RegClass:$rs3, vti.RegClass:$rs1, uimm5:$rs2,
1327                GPR:$vl, vti.Log2SEW)>;
1328
1329  def : Pat<(vti.Vector (riscv_slidedown_vl (vti.Vector vti.RegClass:$rs3),
1330                                            (vti.Vector vti.RegClass:$rs1),
1331                                            GPR:$rs2, (vti.Mask true_mask),
1332                                            VLOpFrag)),
1333            (!cast<Instruction>("PseudoVSLIDEDOWN_VX_"#vti.LMul.MX)
1334                vti.RegClass:$rs3, vti.RegClass:$rs1, GPR:$rs2,
1335                GPR:$vl, vti.Log2SEW)>;
1336}
1337
1338} // Predicates = [HasStdExtV]
1339