xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td (revision 5956d97f4b3204318ceb6aa9c77bd0bc6ea87a41)
1//===- RISCVInstrInfoVSDPatterns.td - RVV SDNode 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 SDNode 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 SDNode patterns.
23//===----------------------------------------------------------------------===//
24
25def SDTSplatI64 : SDTypeProfile<1, 1, [
26  SDTCVecEltisVT<0, i64>, SDTCisVT<1, i32>
27]>;
28
29def rv32_splat_i64 : SDNode<"RISCVISD::SPLAT_VECTOR_I64", SDTSplatI64>;
30
31def SDT_RISCVVMSETCLR_VL : SDTypeProfile<1, 1, [SDTCVecEltisVT<0, i1>,
32                                                SDTCisVT<1, XLenVT>]>;
33def riscv_vmclr_vl : SDNode<"RISCVISD::VMCLR_VL", SDT_RISCVVMSETCLR_VL>;
34def riscv_vmset_vl : SDNode<"RISCVISD::VMSET_VL", SDT_RISCVVMSETCLR_VL>;
35
36def rvv_vnot : PatFrag<(ops node:$in),
37                       (xor node:$in, (riscv_vmset_vl (XLenVT srcvalue)))>;
38
39// Give explicit Complexity to prefer simm5/uimm5.
40def SplatPat       : ComplexPattern<vAny, 1, "selectVSplat",      [splat_vector, rv32_splat_i64], [], 1>;
41def SplatPat_simm5 : ComplexPattern<vAny, 1, "selectVSplatSimm5", [splat_vector, rv32_splat_i64], [], 2>;
42def SplatPat_uimm5 : ComplexPattern<vAny, 1, "selectVSplatUimm5", [splat_vector, rv32_splat_i64], [], 2>;
43def SplatPat_simm5_plus1
44    : ComplexPattern<vAny, 1, "selectVSplatSimm5Plus1",
45                     [splat_vector, rv32_splat_i64], [], 2>;
46def SplatPat_simm5_plus1_nonzero
47    : ComplexPattern<vAny, 1, "selectVSplatSimm5Plus1NonZero",
48                     [splat_vector, rv32_splat_i64], [], 2>;
49
50class SwapHelper<dag Prefix, dag A, dag B, dag Suffix, bit swap> {
51   dag Value = !con(Prefix, !if(swap, B, A), !if(swap, A, B), Suffix);
52}
53
54multiclass VPatUSLoadStoreSDNode<ValueType type,
55                                 int log2sew,
56                                 LMULInfo vlmul,
57                                 OutPatFrag avl,
58                                 VReg reg_class,
59                                 int sew = !shl(1, log2sew)>
60{
61  defvar load_instr = !cast<Instruction>("PseudoVLE"#sew#"_V_"#vlmul.MX);
62  defvar store_instr = !cast<Instruction>("PseudoVSE"#sew#"_V_"#vlmul.MX);
63  // Load
64  def : Pat<(type (load BaseAddr:$rs1)),
65            (load_instr BaseAddr:$rs1, avl, log2sew)>;
66  // Store
67  def : Pat<(store type:$rs2, BaseAddr:$rs1),
68            (store_instr reg_class:$rs2, BaseAddr:$rs1, avl, log2sew)>;
69}
70
71multiclass VPatUSLoadStoreWholeVRSDNode<ValueType type,
72                                        int log2sew,
73                                        LMULInfo vlmul,
74                                        VReg reg_class,
75                                        int sew = !shl(1, log2sew)>
76{
77  defvar load_instr =
78    !cast<Instruction>("VL"#!substr(vlmul.MX, 1)#"RE"#sew#"_V");
79  defvar store_instr =
80    !cast<Instruction>("VS"#!substr(vlmul.MX, 1)#"R_V");
81
82  // Load
83  def : Pat<(type (load BaseAddr:$rs1)),
84            (load_instr BaseAddr:$rs1)>;
85  // Store
86  def : Pat<(store type:$rs2, BaseAddr:$rs1),
87            (store_instr reg_class:$rs2, BaseAddr:$rs1)>;
88}
89
90multiclass VPatUSLoadStoreMaskSDNode<MTypeInfo m>
91{
92  defvar load_instr = !cast<Instruction>("PseudoVLM_V_"#m.BX);
93  defvar store_instr = !cast<Instruction>("PseudoVSM_V_"#m.BX);
94  // Load
95  def : Pat<(m.Mask (load BaseAddr:$rs1)),
96            (load_instr BaseAddr:$rs1, m.AVL, m.Log2SEW)>;
97  // Store
98  def : Pat<(store m.Mask:$rs2, BaseAddr:$rs1),
99            (store_instr VR:$rs2, BaseAddr:$rs1, m.AVL, m.Log2SEW)>;
100}
101
102class VPatBinarySDNode_VV<SDNode vop,
103                          string instruction_name,
104                          ValueType result_type,
105                          ValueType op_type,
106                          int sew,
107                          LMULInfo vlmul,
108                          OutPatFrag avl,
109                          VReg op_reg_class> :
110    Pat<(result_type (vop
111                     (op_type op_reg_class:$rs1),
112                     (op_type op_reg_class:$rs2))),
113        (!cast<Instruction>(instruction_name#"_VV_"# vlmul.MX)
114                     op_reg_class:$rs1,
115                     op_reg_class:$rs2,
116                     avl, sew)>;
117
118class VPatBinarySDNode_XI<SDNode vop,
119                          string instruction_name,
120                          string suffix,
121                          ValueType result_type,
122                          ValueType vop_type,
123                          int sew,
124                          LMULInfo vlmul,
125                          OutPatFrag avl,
126                          VReg vop_reg_class,
127                          ComplexPattern SplatPatKind,
128                          DAGOperand xop_kind> :
129    Pat<(result_type (vop
130                     (vop_type vop_reg_class:$rs1),
131                     (vop_type (SplatPatKind xop_kind:$rs2)))),
132        (!cast<Instruction>(instruction_name#_#suffix#_# vlmul.MX)
133                     vop_reg_class:$rs1,
134                     xop_kind:$rs2,
135                     avl, sew)>;
136
137multiclass VPatBinarySDNode_VV_VX<SDNode vop, string instruction_name> {
138  foreach vti = AllIntegerVectors in {
139    def : VPatBinarySDNode_VV<vop, instruction_name,
140                              vti.Vector, vti.Vector, vti.Log2SEW,
141                              vti.LMul, vti.AVL, vti.RegClass>;
142    def : VPatBinarySDNode_XI<vop, instruction_name, "VX",
143                              vti.Vector, vti.Vector, vti.Log2SEW,
144                              vti.LMul, vti.AVL, vti.RegClass,
145                              SplatPat, GPR>;
146  }
147}
148
149multiclass VPatBinarySDNode_VV_VX_VI<SDNode vop, string instruction_name,
150                                     Operand ImmType = simm5>
151    : VPatBinarySDNode_VV_VX<vop, instruction_name> {
152  foreach vti = AllIntegerVectors in {
153    def : VPatBinarySDNode_XI<vop, instruction_name, "VI",
154                              vti.Vector, vti.Vector, vti.Log2SEW,
155                              vti.LMul, vti.AVL, vti.RegClass,
156                              !cast<ComplexPattern>(SplatPat#_#ImmType),
157                              ImmType>;
158  }
159}
160
161class VPatBinarySDNode_VF<SDNode vop,
162                          string instruction_name,
163                          ValueType result_type,
164                          ValueType vop_type,
165                          ValueType xop_type,
166                          int sew,
167                          LMULInfo vlmul,
168                          OutPatFrag avl,
169                          VReg vop_reg_class,
170                          DAGOperand xop_kind> :
171    Pat<(result_type (vop (vop_type vop_reg_class:$rs1),
172                          (vop_type (splat_vector xop_kind:$rs2)))),
173        (!cast<Instruction>(instruction_name#"_"#vlmul.MX)
174                     vop_reg_class:$rs1,
175                     (xop_type xop_kind:$rs2),
176                     avl, sew)>;
177
178multiclass VPatBinaryFPSDNode_VV_VF<SDNode vop, string instruction_name> {
179  foreach vti = AllFloatVectors in {
180    def : VPatBinarySDNode_VV<vop, instruction_name,
181                              vti.Vector, vti.Vector, vti.Log2SEW,
182                              vti.LMul, vti.AVL, vti.RegClass>;
183    def : VPatBinarySDNode_VF<vop, instruction_name#"_V"#vti.ScalarSuffix,
184                              vti.Vector, vti.Vector, vti.Scalar,
185                              vti.Log2SEW, vti.LMul, vti.AVL, vti.RegClass,
186                              vti.ScalarRegClass>;
187  }
188}
189
190multiclass VPatBinaryFPSDNode_R_VF<SDNode vop, string instruction_name> {
191  foreach fvti = AllFloatVectors in
192    def : Pat<(fvti.Vector (vop (fvti.Vector (splat_vector fvti.Scalar:$rs2)),
193                                (fvti.Vector fvti.RegClass:$rs1))),
194              (!cast<Instruction>(instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX)
195                           fvti.RegClass:$rs1,
196                           (fvti.Scalar fvti.ScalarRegClass:$rs2),
197                           fvti.AVL, fvti.Log2SEW)>;
198}
199
200multiclass VPatIntegerSetCCSDNode_VV<CondCode cc,
201                                     string instruction_name,
202                                     bit swap = 0> {
203  foreach vti = AllIntegerVectors in {
204    defvar instruction = !cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX);
205    def : Pat<(vti.Mask (setcc (vti.Vector vti.RegClass:$rs1),
206                               (vti.Vector vti.RegClass:$rs2), cc)),
207              SwapHelper<(instruction),
208                         (instruction vti.RegClass:$rs1),
209                         (instruction vti.RegClass:$rs2),
210                         (instruction vti.AVL, vti.Log2SEW),
211                         swap>.Value>;
212  }
213}
214
215multiclass VPatIntegerSetCCSDNode_XI<CondCode cc,
216                                     string instruction_name,
217                                     string kind,
218                                     ComplexPattern SplatPatKind,
219                                     DAGOperand xop_kind,
220                                     bit swap = 0> {
221  foreach vti = AllIntegerVectors in {
222    defvar instruction = !cast<Instruction>(instruction_name#_#kind#_#vti.LMul.MX);
223    def : Pat<(vti.Mask (setcc (vti.Vector vti.RegClass:$rs1),
224                               (vti.Vector (SplatPatKind xop_kind:$rs2)), cc)),
225              SwapHelper<(instruction),
226                         (instruction vti.RegClass:$rs1),
227                         (instruction xop_kind:$rs2),
228                         (instruction vti.AVL, vti.Log2SEW),
229                         swap>.Value>;
230  }
231}
232
233multiclass VPatIntegerSetCCSDNode_VV_VX_VI<CondCode cc,
234                                           string instruction_name,
235                                           bit swap = 0> {
236  defm : VPatIntegerSetCCSDNode_VV<cc, instruction_name, swap>;
237  defm : VPatIntegerSetCCSDNode_XI<cc, instruction_name, "VX",
238                                   SplatPat, GPR, swap>;
239  defm : VPatIntegerSetCCSDNode_XI<cc, instruction_name, "VI",
240                                   SplatPat_simm5, simm5, swap>;
241}
242
243multiclass VPatIntegerSetCCSDNode_VV_VX<CondCode cc,
244                                        string instruction_name,
245                                        bit swap = 0> {
246  defm : VPatIntegerSetCCSDNode_VV<cc, instruction_name, swap>;
247  defm : VPatIntegerSetCCSDNode_XI<cc, instruction_name, "VX",
248                                   SplatPat, GPR, swap>;
249}
250
251multiclass VPatIntegerSetCCSDNode_VX_VI<CondCode cc,
252                                        string instruction_name,
253                                        bit swap = 0> {
254  defm : VPatIntegerSetCCSDNode_XI<cc, instruction_name, "VX",
255                                   SplatPat, GPR, swap>;
256  defm : VPatIntegerSetCCSDNode_XI<cc, instruction_name, "VI",
257                                   SplatPat_simm5, simm5, swap>;
258}
259
260multiclass VPatIntegerSetCCSDNode_VIPlus1<CondCode cc, string instruction_name,
261                                          ComplexPattern splatpat_kind> {
262  foreach vti = AllIntegerVectors in {
263    defvar instruction = !cast<Instruction>(instruction_name#"_VI_"#vti.LMul.MX);
264    def : Pat<(vti.Mask (setcc (vti.Vector vti.RegClass:$rs1),
265                               (vti.Vector (splatpat_kind simm5:$rs2)),
266                               cc)),
267              (instruction vti.RegClass:$rs1, (DecImm simm5:$rs2),
268                           vti.AVL, vti.Log2SEW)>;
269  }
270}
271
272multiclass VPatFPSetCCSDNode_VV_VF_FV<CondCode cc,
273                                      string inst_name,
274                                      string swapped_op_inst_name> {
275  foreach fvti = AllFloatVectors in {
276    def : Pat<(fvti.Mask (setcc (fvti.Vector fvti.RegClass:$rs1),
277                                (fvti.Vector fvti.RegClass:$rs2),
278                                cc)),
279              (!cast<Instruction>(inst_name#"_VV_"#fvti.LMul.MX)
280                  fvti.RegClass:$rs1, fvti.RegClass:$rs2, fvti.AVL, fvti.Log2SEW)>;
281    def : Pat<(fvti.Mask (setcc (fvti.Vector fvti.RegClass:$rs1),
282                                (splat_vector fvti.ScalarRegClass:$rs2),
283                                cc)),
284              (!cast<Instruction>(inst_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX)
285                  fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2,
286                  fvti.AVL, fvti.Log2SEW)>;
287    def : Pat<(fvti.Mask (setcc (splat_vector fvti.ScalarRegClass:$rs2),
288                                (fvti.Vector fvti.RegClass:$rs1),
289                                cc)),
290              (!cast<Instruction>(swapped_op_inst_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX)
291                  fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2,
292                  fvti.AVL, fvti.Log2SEW)>;
293  }
294}
295
296multiclass VPatExtendSDNode_V<list<SDNode> ops, string inst_name, string suffix,
297                              list <VTypeInfoToFraction> fraction_list> {
298  foreach vtiTofti = fraction_list in {
299    defvar vti = vtiTofti.Vti;
300    defvar fti = vtiTofti.Fti;
301    foreach op = ops in
302      def : Pat<(vti.Vector (op (fti.Vector fti.RegClass:$rs2))),
303                (!cast<Instruction>(inst_name#"_"#suffix#"_"#vti.LMul.MX)
304                    fti.RegClass:$rs2, fti.AVL, vti.Log2SEW)>;
305  }
306}
307
308multiclass VPatConvertI2FPSDNode_V<SDNode vop, string instruction_name> {
309  foreach fvti = AllFloatVectors in {
310    defvar ivti = GetIntVTypeInfo<fvti>.Vti;
311    def : Pat<(fvti.Vector (vop (ivti.Vector ivti.RegClass:$rs1))),
312              (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX)
313                  ivti.RegClass:$rs1, fvti.AVL, fvti.Log2SEW)>;
314  }
315}
316
317multiclass VPatConvertFP2ISDNode_V<SDNode vop, string instruction_name> {
318  foreach fvti = AllFloatVectors in {
319    defvar ivti = GetIntVTypeInfo<fvti>.Vti;
320    def : Pat<(ivti.Vector (vop (fvti.Vector fvti.RegClass:$rs1))),
321              (!cast<Instruction>(instruction_name#"_"#ivti.LMul.MX)
322                  fvti.RegClass:$rs1, ivti.AVL, ivti.Log2SEW)>;
323  }
324}
325
326multiclass VPatWConvertI2FPSDNode_V<SDNode vop, string instruction_name> {
327  foreach vtiToWti = AllWidenableIntToFloatVectors in {
328    defvar ivti = vtiToWti.Vti;
329    defvar fwti = vtiToWti.Wti;
330    def : Pat<(fwti.Vector (vop (ivti.Vector ivti.RegClass:$rs1))),
331              (!cast<Instruction>(instruction_name#"_"#ivti.LMul.MX)
332                  ivti.RegClass:$rs1, ivti.AVL, ivti.Log2SEW)>;
333  }
334}
335
336multiclass VPatWConvertFP2ISDNode_V<SDNode vop, string instruction_name> {
337  foreach fvtiToFWti = AllWidenableFloatVectors in {
338    defvar fvti = fvtiToFWti.Vti;
339    defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti;
340    def : Pat<(iwti.Vector (vop (fvti.Vector fvti.RegClass:$rs1))),
341              (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX)
342                  fvti.RegClass:$rs1, fvti.AVL, fvti.Log2SEW)>;
343  }
344}
345
346multiclass VPatNConvertI2FPSDNode_V<SDNode vop, string instruction_name> {
347  foreach fvtiToFWti = AllWidenableFloatVectors in {
348    defvar fvti = fvtiToFWti.Vti;
349    defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti;
350    def : Pat<(fvti.Vector (vop (iwti.Vector iwti.RegClass:$rs1))),
351              (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX)
352                  iwti.RegClass:$rs1, fvti.AVL, fvti.Log2SEW)>;
353  }
354}
355
356multiclass VPatNConvertFP2ISDNode_V<SDNode vop, string instruction_name> {
357  foreach vtiToWti = AllWidenableIntToFloatVectors in {
358    defvar vti = vtiToWti.Vti;
359    defvar fwti = vtiToWti.Wti;
360    def : Pat<(vti.Vector (vop (fwti.Vector fwti.RegClass:$rs1))),
361              (!cast<Instruction>(instruction_name#"_"#vti.LMul.MX)
362                  fwti.RegClass:$rs1, vti.AVL, vti.Log2SEW)>;
363  }
364}
365
366multiclass VPatWidenBinarySDNode_VV_VX_WV_WX<SDNode op, PatFrags extop, string instruction_name> {
367  foreach vti = AllWidenableIntVectors in {
368    def : Pat<(op (vti.Wti.Vector (extop (vti.Vti.Vector vti.Vti.RegClass:$rs2))),
369                  (vti.Wti.Vector (extop (vti.Vti.Vector vti.Vti.RegClass:$rs1)))),
370              (!cast<Instruction>(instruction_name#"_VV_"#vti.Vti.LMul.MX)
371                 vti.Vti.RegClass:$rs2, vti.Vti.RegClass:$rs1,
372                 vti.Vti.AVL, vti.Vti.Log2SEW)>;
373    def : Pat<(op (vti.Wti.Vector (extop (vti.Vti.Vector vti.Vti.RegClass:$rs2))),
374                  (vti.Wti.Vector (extop (vti.Vti.Vector (SplatPat GPR:$rs1))))),
375              (!cast<Instruction>(instruction_name#"_VX_"#vti.Vti.LMul.MX)
376                 vti.Vti.RegClass:$rs2, GPR:$rs1,
377                 vti.Vti.AVL, vti.Vti.Log2SEW)>;
378    def : Pat<(op (vti.Wti.Vector vti.Wti.RegClass:$rs2),
379                  (vti.Wti.Vector (extop (vti.Vti.Vector vti.Vti.RegClass:$rs1)))),
380              (!cast<Instruction>(instruction_name#"_WV_"#vti.Vti.LMul.MX)
381                 vti.Wti.RegClass:$rs2, vti.Vti.RegClass:$rs1,
382                 vti.Vti.AVL, vti.Vti.Log2SEW)>;
383    def : Pat<(op (vti.Wti.Vector vti.Wti.RegClass:$rs2),
384                  (vti.Wti.Vector (extop (vti.Vti.Vector (SplatPat GPR:$rs1))))),
385              (!cast<Instruction>(instruction_name#"_WX_"#vti.Vti.LMul.MX)
386                 vti.Wti.RegClass:$rs2, GPR:$rs1,
387                 vti.Vti.AVL, vti.Vti.Log2SEW)>;
388  }
389}
390
391multiclass VPatWidenMulAddSDNode_VV<PatFrags extop1, PatFrags extop2, string instruction_name> {
392  foreach vti = AllWidenableIntVectors in {
393    def : Pat<
394      (add (vti.Wti.Vector vti.Wti.RegClass:$rd),
395        (mul_oneuse (vti.Wti.Vector (extop1 (vti.Vti.Vector vti.Vti.RegClass:$rs1))),
396                    (vti.Wti.Vector (extop2 (vti.Vti.Vector vti.Vti.RegClass:$rs2))))),
397      (!cast<Instruction>(instruction_name#"_VV_"#vti.Vti.LMul.MX)
398        vti.Wti.RegClass:$rd, vti.Vti.RegClass:$rs1, vti.Vti.RegClass:$rs2,
399        vti.Vti.AVL, vti.Vti.Log2SEW, TAIL_AGNOSTIC
400      )>;
401  }
402}
403multiclass VPatWidenMulAddSDNode_VX<PatFrags extop1, PatFrags extop2, string instruction_name> {
404  foreach vti = AllWidenableIntVectors in {
405    def : Pat<
406      (add (vti.Wti.Vector vti.Wti.RegClass:$rd),
407        (mul_oneuse (vti.Wti.Vector (extop1 (vti.Vti.Vector (SplatPat GPR:$rs1)))),
408                    (vti.Wti.Vector (extop2 (vti.Vti.Vector vti.Vti.RegClass:$rs2))))),
409      (!cast<Instruction>(instruction_name#"_VX_"#vti.Vti.LMul.MX)
410        vti.Wti.RegClass:$rd, GPR:$rs1, vti.Vti.RegClass:$rs2,
411        vti.Vti.AVL, vti.Vti.Log2SEW, TAIL_AGNOSTIC
412      )>;
413  }
414}
415
416multiclass VPatWidenBinaryFPSDNode_VV_VF<SDNode op, string instruction_name> {
417  foreach vti = AllWidenableFloatVectors in {
418    def : Pat<(op (vti.Wti.Vector (fpext_oneuse (vti.Vti.Vector vti.Vti.RegClass:$rs2))),
419                  (vti.Wti.Vector (fpext_oneuse (vti.Vti.Vector vti.Vti.RegClass:$rs1)))),
420              (!cast<Instruction>(instruction_name#"_VV_"#vti.Vti.LMul.MX)
421                 vti.Vti.RegClass:$rs2, vti.Vti.RegClass:$rs1,
422                 vti.Vti.AVL, vti.Vti.Log2SEW)>;
423    def : Pat<(op (vti.Wti.Vector (fpext_oneuse (vti.Vti.Vector vti.Vti.RegClass:$rs2))),
424                  (vti.Wti.Vector (fpext_oneuse (vti.Vti.Vector (SplatPat vti.Vti.ScalarRegClass:$rs1))))),
425              (!cast<Instruction>(instruction_name#"_V"#vti.Vti.ScalarSuffix#"_"#vti.Vti.LMul.MX)
426                 vti.Vti.RegClass:$rs2, vti.Vti.ScalarRegClass:$rs1,
427                 vti.Vti.AVL, vti.Vti.Log2SEW)>;
428  }
429}
430
431multiclass VPatWidenBinaryFPSDNode_WV_WF<SDNode op, string instruction_name> {
432  foreach vti = AllWidenableFloatVectors in {
433    def : Pat<(op (vti.Wti.Vector vti.Wti.RegClass:$rs2),
434                  (vti.Wti.Vector (fpext_oneuse (vti.Vti.Vector vti.Vti.RegClass:$rs1)))),
435              (!cast<Instruction>(instruction_name#"_WV_"#vti.Vti.LMul.MX)
436                 vti.Wti.RegClass:$rs2, vti.Vti.RegClass:$rs1,
437                 vti.Vti.AVL, vti.Vti.Log2SEW)>;
438    def : Pat<(op (vti.Wti.Vector vti.Wti.RegClass:$rs2),
439                  (vti.Wti.Vector (fpext_oneuse (vti.Vti.Vector (SplatPat vti.Vti.ScalarRegClass:$rs1))))),
440              (!cast<Instruction>(instruction_name#"_W"#vti.Vti.ScalarSuffix#"_"#vti.Vti.LMul.MX)
441                 vti.Wti.RegClass:$rs2, vti.Vti.ScalarRegClass:$rs1,
442                 vti.Vti.AVL, vti.Vti.Log2SEW)>;
443  }
444}
445
446multiclass VPatWidenBinaryFPSDNode_VV_VF_WV_WF<SDNode op, string instruction_name> {
447  defm : VPatWidenBinaryFPSDNode_VV_VF<op, instruction_name>;
448  defm : VPatWidenBinaryFPSDNode_WV_WF<op, instruction_name>;
449}
450
451//===----------------------------------------------------------------------===//
452// Patterns.
453//===----------------------------------------------------------------------===//
454
455let Predicates = [HasVInstructions] in {
456
457// 7.4. Vector Unit-Stride Instructions
458foreach vti = !listconcat(FractionalGroupIntegerVectors,
459                          FractionalGroupFloatVectors) in
460  defm : VPatUSLoadStoreSDNode<vti.Vector, vti.Log2SEW, vti.LMul,
461                               vti.AVL, vti.RegClass>;
462foreach vti = [VI8M1, VI16M1, VI32M1, VI64M1, VF16M1, VF32M1, VF64M1] in
463  defm : VPatUSLoadStoreWholeVRSDNode<vti.Vector, vti.Log2SEW, vti.LMul,
464                                      vti.RegClass>;
465foreach vti = !listconcat(GroupIntegerVectors, GroupFloatVectors) in
466  defm : VPatUSLoadStoreWholeVRSDNode<vti.Vector, vti.Log2SEW, vti.LMul,
467                                      vti.RegClass>;
468foreach mti = AllMasks in
469  defm : VPatUSLoadStoreMaskSDNode<mti>;
470
471// 12.1. Vector Single-Width Integer Add and Subtract
472defm : VPatBinarySDNode_VV_VX_VI<add, "PseudoVADD">;
473defm : VPatBinarySDNode_VV_VX<sub, "PseudoVSUB">;
474// Handle VRSUB specially since it's the only integer binary op with reversed
475// pattern operands
476foreach vti = AllIntegerVectors in {
477  def : Pat<(sub (vti.Vector (SplatPat GPR:$rs2)),
478                 (vti.Vector vti.RegClass:$rs1)),
479            (!cast<Instruction>("PseudoVRSUB_VX_"# vti.LMul.MX)
480                 vti.RegClass:$rs1, GPR:$rs2, vti.AVL, vti.Log2SEW)>;
481  def : Pat<(sub (vti.Vector (SplatPat_simm5 simm5:$rs2)),
482                 (vti.Vector vti.RegClass:$rs1)),
483            (!cast<Instruction>("PseudoVRSUB_VI_"# vti.LMul.MX)
484                 vti.RegClass:$rs1, simm5:$rs2, vti.AVL, vti.Log2SEW)>;
485}
486
487// 12.2. Vector Widening Integer Add and Subtract
488defm : VPatWidenBinarySDNode_VV_VX_WV_WX<add, sext_oneuse, "PseudoVWADD">;
489defm : VPatWidenBinarySDNode_VV_VX_WV_WX<add, zext_oneuse, "PseudoVWADDU">;
490defm : VPatWidenBinarySDNode_VV_VX_WV_WX<add, anyext_oneuse, "PseudoVWADDU">;
491
492defm : VPatWidenBinarySDNode_VV_VX_WV_WX<sub, sext_oneuse, "PseudoVWSUB">;
493defm : VPatWidenBinarySDNode_VV_VX_WV_WX<sub, zext_oneuse, "PseudoVWSUBU">;
494defm : VPatWidenBinarySDNode_VV_VX_WV_WX<sub, anyext_oneuse, "PseudoVWSUBU">;
495
496// 12.3. Vector Integer Extension
497defm : VPatExtendSDNode_V<[zext, anyext], "PseudoVZEXT", "VF2",
498                          AllFractionableVF2IntVectors>;
499defm : VPatExtendSDNode_V<[sext],         "PseudoVSEXT", "VF2",
500                          AllFractionableVF2IntVectors>;
501defm : VPatExtendSDNode_V<[zext, anyext], "PseudoVZEXT", "VF4",
502                          AllFractionableVF4IntVectors>;
503defm : VPatExtendSDNode_V<[sext],         "PseudoVSEXT", "VF4",
504                          AllFractionableVF4IntVectors>;
505defm : VPatExtendSDNode_V<[zext, anyext], "PseudoVZEXT", "VF8",
506                          AllFractionableVF8IntVectors>;
507defm : VPatExtendSDNode_V<[sext],         "PseudoVSEXT", "VF8",
508                          AllFractionableVF8IntVectors>;
509
510// 12.5. Vector Bitwise Logical Instructions
511defm : VPatBinarySDNode_VV_VX_VI<and, "PseudoVAND">;
512defm : VPatBinarySDNode_VV_VX_VI<or, "PseudoVOR">;
513defm : VPatBinarySDNode_VV_VX_VI<xor, "PseudoVXOR">;
514
515// 12.6. Vector Single-Width Bit Shift Instructions
516defm : VPatBinarySDNode_VV_VX_VI<shl, "PseudoVSLL", uimm5>;
517defm : VPatBinarySDNode_VV_VX_VI<srl, "PseudoVSRL", uimm5>;
518defm : VPatBinarySDNode_VV_VX_VI<sra, "PseudoVSRA", uimm5>;
519
520foreach vti = AllIntegerVectors in {
521  // Emit shift by 1 as an add since it might be faster.
522  def : Pat<(shl (vti.Vector vti.RegClass:$rs1),
523                 (vti.Vector (splat_vector (XLenVT 1)))),
524            (!cast<Instruction>("PseudoVADD_VV_"# vti.LMul.MX)
525                 vti.RegClass:$rs1, vti.RegClass:$rs1, vti.AVL, vti.Log2SEW)>;
526}
527foreach vti = [VI64M1, VI64M2, VI64M4, VI64M8] in {
528  def : Pat<(shl (vti.Vector vti.RegClass:$rs1),
529                 (vti.Vector (rv32_splat_i64 (XLenVT 1)))),
530            (!cast<Instruction>("PseudoVADD_VV_"# vti.LMul.MX)
531                 vti.RegClass:$rs1, vti.RegClass:$rs1, vti.AVL, vti.Log2SEW)>;
532
533}
534
535// 12.8. Vector Integer Comparison Instructions
536defm : VPatIntegerSetCCSDNode_VV_VX_VI<SETEQ,  "PseudoVMSEQ">;
537defm : VPatIntegerSetCCSDNode_VV_VX_VI<SETNE,  "PseudoVMSNE">;
538
539defm : VPatIntegerSetCCSDNode_VV_VX<SETLT,  "PseudoVMSLT">;
540defm : VPatIntegerSetCCSDNode_VV_VX<SETULT, "PseudoVMSLTU">;
541defm : VPatIntegerSetCCSDNode_VIPlus1<SETLT, "PseudoVMSLE",
542                                      SplatPat_simm5_plus1_nonzero>;
543defm : VPatIntegerSetCCSDNode_VIPlus1<SETULT, "PseudoVMSLEU",
544                                      SplatPat_simm5_plus1_nonzero>;
545
546defm : VPatIntegerSetCCSDNode_VV<SETGT,  "PseudoVMSLT", /*swap*/1>;
547defm : VPatIntegerSetCCSDNode_VV<SETUGT, "PseudoVMSLTU", /*swap*/1>;
548defm : VPatIntegerSetCCSDNode_VX_VI<SETGT,  "PseudoVMSGT">;
549defm : VPatIntegerSetCCSDNode_VX_VI<SETUGT, "PseudoVMSGTU">;
550
551defm : VPatIntegerSetCCSDNode_VV_VX_VI<SETLE,  "PseudoVMSLE">;
552defm : VPatIntegerSetCCSDNode_VV_VX_VI<SETULE, "PseudoVMSLEU">;
553
554defm : VPatIntegerSetCCSDNode_VV<SETGE,  "PseudoVMSLE", /*swap*/1>;
555defm : VPatIntegerSetCCSDNode_VV<SETUGE, "PseudoVMSLEU", /*swap*/1>;
556defm : VPatIntegerSetCCSDNode_VIPlus1<SETGE, "PseudoVMSGT",
557                                      SplatPat_simm5_plus1>;
558defm : VPatIntegerSetCCSDNode_VIPlus1<SETUGE, "PseudoVMSGTU",
559                                      SplatPat_simm5_plus1_nonzero>;
560
561// 12.9. Vector Integer Min/Max Instructions
562defm : VPatBinarySDNode_VV_VX<umin, "PseudoVMINU">;
563defm : VPatBinarySDNode_VV_VX<smin, "PseudoVMIN">;
564defm : VPatBinarySDNode_VV_VX<umax, "PseudoVMAXU">;
565defm : VPatBinarySDNode_VV_VX<smax, "PseudoVMAX">;
566
567// 12.10. Vector Single-Width Integer Multiply Instructions
568defm : VPatBinarySDNode_VV_VX<mul, "PseudoVMUL">;
569defm : VPatBinarySDNode_VV_VX<mulhs, "PseudoVMULH">;
570defm : VPatBinarySDNode_VV_VX<mulhu, "PseudoVMULHU">;
571
572// 12.11. Vector Integer Divide Instructions
573defm : VPatBinarySDNode_VV_VX<udiv, "PseudoVDIVU">;
574defm : VPatBinarySDNode_VV_VX<sdiv, "PseudoVDIV">;
575defm : VPatBinarySDNode_VV_VX<urem, "PseudoVREMU">;
576defm : VPatBinarySDNode_VV_VX<srem, "PseudoVREM">;
577
578// 12.13 Vector Single-Width Integer Multiply-Add Instructions.
579foreach vti = AllIntegerVectors in {
580  // NOTE: We choose VMADD because it has the most commuting freedom. So it
581  // works best with how TwoAddressInstructionPass tries commuting.
582  defvar suffix = vti.LMul.MX;
583  def : Pat<(vti.Vector (add vti.RegClass:$rs2,
584                              (mul_oneuse vti.RegClass:$rs1, vti.RegClass:$rd))),
585            (!cast<Instruction>("PseudoVMADD_VV_"# suffix)
586                 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2,
587                 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>;
588  def : Pat<(vti.Vector (sub vti.RegClass:$rs2,
589                              (mul_oneuse vti.RegClass:$rs1, vti.RegClass:$rd))),
590            (!cast<Instruction>("PseudoVNMSUB_VV_"# suffix)
591                 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2,
592                 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>;
593
594  // The choice of VMADD here is arbitrary, vmadd.vx and vmacc.vx are equally
595  // commutable.
596  def : Pat<(vti.Vector (add vti.RegClass:$rs2,
597                              (mul_oneuse (SplatPat XLenVT:$rs1),
598                                          vti.RegClass:$rd))),
599            (!cast<Instruction>("PseudoVMADD_VX_" # suffix)
600                 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2,
601                 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>;
602  def : Pat<(vti.Vector (sub vti.RegClass:$rs2,
603                              (mul_oneuse (SplatPat XLenVT:$rs1),
604                                          vti.RegClass:$rd))),
605            (!cast<Instruction>("PseudoVNMSUB_VX_" # suffix)
606                 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2,
607                 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>;
608}
609
610// 12.14 Vector Widening Integer Multiply-Add Instructions
611defm : VPatWidenMulAddSDNode_VV<sext_oneuse, sext_oneuse, "PseudoVWMACC">;
612defm : VPatWidenMulAddSDNode_VX<sext_oneuse, sext_oneuse, "PseudoVWMACC">;
613defm : VPatWidenMulAddSDNode_VV<zext_oneuse, zext_oneuse, "PseudoVWMACCU">;
614defm : VPatWidenMulAddSDNode_VX<zext_oneuse, zext_oneuse, "PseudoVWMACCU">;
615defm : VPatWidenMulAddSDNode_VV<sext_oneuse, zext_oneuse, "PseudoVWMACCSU">;
616defm : VPatWidenMulAddSDNode_VX<sext_oneuse, zext_oneuse, "PseudoVWMACCSU">;
617defm : VPatWidenMulAddSDNode_VX<zext_oneuse, sext_oneuse, "PseudoVWMACCUS">;
618
619// 12.15. Vector Integer Merge Instructions
620foreach vti = AllIntegerVectors in {
621  def : Pat<(vti.Vector (vselect (vti.Mask V0), vti.RegClass:$rs1,
622                                                      vti.RegClass:$rs2)),
623            (!cast<Instruction>("PseudoVMERGE_VVM_"#vti.LMul.MX)
624                 vti.RegClass:$rs2, vti.RegClass:$rs1, (vti.Mask V0),
625                 vti.AVL, vti.Log2SEW)>;
626
627  def : Pat<(vti.Vector (vselect (vti.Mask V0), (SplatPat XLenVT:$rs1),
628                                                      vti.RegClass:$rs2)),
629            (!cast<Instruction>("PseudoVMERGE_VXM_"#vti.LMul.MX)
630                 vti.RegClass:$rs2, GPR:$rs1, (vti.Mask V0), vti.AVL, vti.Log2SEW)>;
631
632  def : Pat<(vti.Vector (vselect (vti.Mask V0), (SplatPat_simm5 simm5:$rs1),
633                                                      vti.RegClass:$rs2)),
634            (!cast<Instruction>("PseudoVMERGE_VIM_"#vti.LMul.MX)
635                 vti.RegClass:$rs2, simm5:$rs1, (vti.Mask V0), vti.AVL, vti.Log2SEW)>;
636}
637
638// 12.1. Vector Single-Width Saturating Add and Subtract
639defm : VPatBinarySDNode_VV_VX_VI<saddsat, "PseudoVSADD">;
640defm : VPatBinarySDNode_VV_VX_VI<uaddsat, "PseudoVSADDU">;
641defm : VPatBinarySDNode_VV_VX<ssubsat, "PseudoVSSUB">;
642defm : VPatBinarySDNode_VV_VX<usubsat, "PseudoVSSUBU">;
643
644// 16.1. Vector Mask-Register Logical Instructions
645foreach mti = AllMasks in {
646  def : Pat<(mti.Mask (and VR:$rs1, VR:$rs2)),
647            (!cast<Instruction>("PseudoVMAND_MM_"#mti.LMul.MX)
648                 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>;
649  def : Pat<(mti.Mask (or VR:$rs1, VR:$rs2)),
650            (!cast<Instruction>("PseudoVMOR_MM_"#mti.LMul.MX)
651                 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>;
652  def : Pat<(mti.Mask (xor VR:$rs1, VR:$rs2)),
653            (!cast<Instruction>("PseudoVMXOR_MM_"#mti.LMul.MX)
654                 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>;
655
656  def : Pat<(mti.Mask (rvv_vnot (and VR:$rs1, VR:$rs2))),
657            (!cast<Instruction>("PseudoVMNAND_MM_"#mti.LMul.MX)
658                 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>;
659  def : Pat<(mti.Mask (rvv_vnot (or VR:$rs1, VR:$rs2))),
660            (!cast<Instruction>("PseudoVMNOR_MM_"#mti.LMul.MX)
661                 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>;
662  def : Pat<(mti.Mask (rvv_vnot (xor VR:$rs1, VR:$rs2))),
663            (!cast<Instruction>("PseudoVMXNOR_MM_"#mti.LMul.MX)
664                 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>;
665
666  def : Pat<(mti.Mask (and VR:$rs1, (rvv_vnot VR:$rs2))),
667            (!cast<Instruction>("PseudoVMANDN_MM_"#mti.LMul.MX)
668                 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>;
669  def : Pat<(mti.Mask (or VR:$rs1, (rvv_vnot VR:$rs2))),
670            (!cast<Instruction>("PseudoVMORN_MM_"#mti.LMul.MX)
671                 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>;
672
673  // Handle rvv_vnot the same as the vmnot.m pseudoinstruction.
674  def : Pat<(mti.Mask (rvv_vnot VR:$rs)),
675            (!cast<Instruction>("PseudoVMNAND_MM_"#mti.LMul.MX)
676                 VR:$rs, VR:$rs, mti.AVL, mti.Log2SEW)>;
677}
678
679} // Predicates = [HasVInstructions]
680
681let Predicates = [HasVInstructionsAnyF] in {
682
683// 14.2. Vector Single-Width Floating-Point Add/Subtract Instructions
684defm : VPatBinaryFPSDNode_VV_VF<fadd, "PseudoVFADD">;
685defm : VPatBinaryFPSDNode_VV_VF<fsub, "PseudoVFSUB">;
686defm : VPatBinaryFPSDNode_R_VF<fsub, "PseudoVFRSUB">;
687
688// 14.3. Vector Widening Floating-Point Add/Subtract Instructions
689defm : VPatWidenBinaryFPSDNode_VV_VF_WV_WF<fadd, "PseudoVFWADD">;
690defm : VPatWidenBinaryFPSDNode_VV_VF_WV_WF<fsub, "PseudoVFWSUB">;
691
692// 14.4. Vector Single-Width Floating-Point Multiply/Divide Instructions
693defm : VPatBinaryFPSDNode_VV_VF<fmul, "PseudoVFMUL">;
694defm : VPatBinaryFPSDNode_VV_VF<fdiv, "PseudoVFDIV">;
695defm : VPatBinaryFPSDNode_R_VF<fdiv, "PseudoVFRDIV">;
696
697// 14.5. Vector Widening Floating-Point Multiply Instructions
698defm : VPatWidenBinaryFPSDNode_VV_VF<fmul, "PseudoVFWMUL">;
699
700// 14.6 Vector Single-Width Floating-Point Fused Multiply-Add Instructions.
701foreach fvti = AllFloatVectors in {
702  // NOTE: We choose VFMADD because it has the most commuting freedom. So it
703  // works best with how TwoAddressInstructionPass tries commuting.
704  defvar suffix = fvti.LMul.MX;
705  def : Pat<(fvti.Vector (fma fvti.RegClass:$rs1, fvti.RegClass:$rd,
706                              fvti.RegClass:$rs2)),
707            (!cast<Instruction>("PseudoVFMADD_VV_"# suffix)
708                 fvti.RegClass:$rd, fvti.RegClass:$rs1, fvti.RegClass:$rs2,
709                 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;
710  def : Pat<(fvti.Vector (fma fvti.RegClass:$rs1, fvti.RegClass:$rd,
711                              (fneg fvti.RegClass:$rs2))),
712            (!cast<Instruction>("PseudoVFMSUB_VV_"# suffix)
713                 fvti.RegClass:$rd, fvti.RegClass:$rs1, fvti.RegClass:$rs2,
714                 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;
715  def : Pat<(fvti.Vector (fma (fneg fvti.RegClass:$rs1), fvti.RegClass:$rd,
716                              (fneg fvti.RegClass:$rs2))),
717            (!cast<Instruction>("PseudoVFNMADD_VV_"# suffix)
718                 fvti.RegClass:$rd, fvti.RegClass:$rs1, fvti.RegClass:$rs2,
719                 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;
720  def : Pat<(fvti.Vector (fma (fneg fvti.RegClass:$rs1), fvti.RegClass:$rd,
721                              fvti.RegClass:$rs2)),
722            (!cast<Instruction>("PseudoVFNMSUB_VV_"# suffix)
723                 fvti.RegClass:$rd, fvti.RegClass:$rs1, fvti.RegClass:$rs2,
724                 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;
725
726  // The choice of VFMADD here is arbitrary, vfmadd.vf and vfmacc.vf are equally
727  // commutable.
728  def : Pat<(fvti.Vector (fma (splat_vector fvti.ScalarRegClass:$rs1),
729                              fvti.RegClass:$rd, fvti.RegClass:$rs2)),
730            (!cast<Instruction>("PseudoVFMADD_V" # fvti.ScalarSuffix # "_" # suffix)
731                 fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2,
732                 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;
733  def : Pat<(fvti.Vector (fma (splat_vector fvti.ScalarRegClass:$rs1),
734                              fvti.RegClass:$rd, (fneg fvti.RegClass:$rs2))),
735            (!cast<Instruction>("PseudoVFMSUB_V" # fvti.ScalarSuffix # "_" # suffix)
736                 fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2,
737                 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;
738
739  def : Pat<(fvti.Vector (fma (splat_vector fvti.ScalarRegClass:$rs1),
740                              (fneg fvti.RegClass:$rd), (fneg fvti.RegClass:$rs2))),
741            (!cast<Instruction>("PseudoVFNMADD_V" # fvti.ScalarSuffix # "_" # suffix)
742                 fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2,
743                 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;
744  def : Pat<(fvti.Vector (fma (splat_vector fvti.ScalarRegClass:$rs1),
745                              (fneg fvti.RegClass:$rd), fvti.RegClass:$rs2)),
746            (!cast<Instruction>("PseudoVFNMSUB_V" # fvti.ScalarSuffix # "_" # suffix)
747                 fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2,
748                 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;
749
750  // The splat might be negated.
751  def : Pat<(fvti.Vector (fma (fneg (splat_vector fvti.ScalarRegClass:$rs1)),
752                              fvti.RegClass:$rd, (fneg fvti.RegClass:$rs2))),
753            (!cast<Instruction>("PseudoVFNMADD_V" # fvti.ScalarSuffix # "_" # suffix)
754                 fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2,
755                 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;
756  def : Pat<(fvti.Vector (fma (fneg (splat_vector fvti.ScalarRegClass:$rs1)),
757                              fvti.RegClass:$rd, fvti.RegClass:$rs2)),
758            (!cast<Instruction>("PseudoVFNMSUB_V" # fvti.ScalarSuffix # "_" # suffix)
759                 fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2,
760                 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;
761}
762
763foreach vti = AllFloatVectors in {
764  // 14.8. Vector Floating-Point Square-Root Instruction
765  def : Pat<(fsqrt (vti.Vector vti.RegClass:$rs2)),
766            (!cast<Instruction>("PseudoVFSQRT_V_"# vti.LMul.MX)
767                 vti.RegClass:$rs2, vti.AVL, vti.Log2SEW)>;
768
769  // 14.12. Vector Floating-Point Sign-Injection Instructions
770  def : Pat<(fabs (vti.Vector vti.RegClass:$rs)),
771            (!cast<Instruction>("PseudoVFSGNJX_VV_"# vti.LMul.MX)
772                 vti.RegClass:$rs, vti.RegClass:$rs, vti.AVL, vti.Log2SEW)>;
773  // Handle fneg with VFSGNJN using the same input for both operands.
774  def : Pat<(fneg (vti.Vector vti.RegClass:$rs)),
775            (!cast<Instruction>("PseudoVFSGNJN_VV_"# vti.LMul.MX)
776                 vti.RegClass:$rs, vti.RegClass:$rs, vti.AVL, vti.Log2SEW)>;
777
778  def : Pat<(vti.Vector (fcopysign (vti.Vector vti.RegClass:$rs1),
779                                   (vti.Vector vti.RegClass:$rs2))),
780            (!cast<Instruction>("PseudoVFSGNJ_VV_"# vti.LMul.MX)
781                 vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL, vti.Log2SEW)>;
782  def : Pat<(vti.Vector (fcopysign (vti.Vector vti.RegClass:$rs1),
783                                   (vti.Vector (splat_vector vti.ScalarRegClass:$rs2)))),
784            (!cast<Instruction>("PseudoVFSGNJ_V"#vti.ScalarSuffix#"_"#vti.LMul.MX)
785                 vti.RegClass:$rs1, vti.ScalarRegClass:$rs2, vti.AVL, vti.Log2SEW)>;
786
787  def : Pat<(vti.Vector (fcopysign (vti.Vector vti.RegClass:$rs1),
788                                   (vti.Vector (fneg vti.RegClass:$rs2)))),
789            (!cast<Instruction>("PseudoVFSGNJN_VV_"# vti.LMul.MX)
790                 vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL, vti.Log2SEW)>;
791  def : Pat<(vti.Vector (fcopysign (vti.Vector vti.RegClass:$rs1),
792                                   (vti.Vector (fneg (splat_vector vti.ScalarRegClass:$rs2))))),
793            (!cast<Instruction>("PseudoVFSGNJN_V"#vti.ScalarSuffix#"_"#vti.LMul.MX)
794                 vti.RegClass:$rs1, vti.ScalarRegClass:$rs2, vti.AVL, vti.Log2SEW)>;
795}
796
797// 14.11. Vector Floating-Point MIN/MAX Instructions
798defm : VPatBinaryFPSDNode_VV_VF<fminnum, "PseudoVFMIN">;
799defm : VPatBinaryFPSDNode_VV_VF<fmaxnum, "PseudoVFMAX">;
800
801// 14.13. Vector Floating-Point Compare Instructions
802defm : VPatFPSetCCSDNode_VV_VF_FV<SETEQ,  "PseudoVMFEQ", "PseudoVMFEQ">;
803defm : VPatFPSetCCSDNode_VV_VF_FV<SETOEQ, "PseudoVMFEQ", "PseudoVMFEQ">;
804
805defm : VPatFPSetCCSDNode_VV_VF_FV<SETNE,  "PseudoVMFNE", "PseudoVMFNE">;
806defm : VPatFPSetCCSDNode_VV_VF_FV<SETUNE, "PseudoVMFNE", "PseudoVMFNE">;
807
808defm : VPatFPSetCCSDNode_VV_VF_FV<SETLT,  "PseudoVMFLT", "PseudoVMFGT">;
809defm : VPatFPSetCCSDNode_VV_VF_FV<SETOLT, "PseudoVMFLT", "PseudoVMFGT">;
810
811defm : VPatFPSetCCSDNode_VV_VF_FV<SETLE,  "PseudoVMFLE", "PseudoVMFGE">;
812defm : VPatFPSetCCSDNode_VV_VF_FV<SETOLE, "PseudoVMFLE", "PseudoVMFGE">;
813
814// Floating-point vselects:
815// 12.15. Vector Integer Merge Instructions
816// 14.15. Vector Floating-Point Merge Instruction
817foreach fvti = AllFloatVectors in {
818  def : Pat<(fvti.Vector (vselect (fvti.Mask V0), fvti.RegClass:$rs1,
819                                                        fvti.RegClass:$rs2)),
820            (!cast<Instruction>("PseudoVMERGE_VVM_"#fvti.LMul.MX)
821                 fvti.RegClass:$rs2, fvti.RegClass:$rs1, (fvti.Mask V0),
822                 fvti.AVL, fvti.Log2SEW)>;
823
824  def : Pat<(fvti.Vector (vselect (fvti.Mask V0),
825                                  (splat_vector fvti.ScalarRegClass:$rs1),
826                                  fvti.RegClass:$rs2)),
827            (!cast<Instruction>("PseudoVFMERGE_V"#fvti.ScalarSuffix#"M_"#fvti.LMul.MX)
828                 fvti.RegClass:$rs2,
829                 (fvti.Scalar fvti.ScalarRegClass:$rs1),
830                 (fvti.Mask V0), fvti.AVL, fvti.Log2SEW)>;
831
832  def : Pat<(fvti.Vector (vselect (fvti.Mask V0),
833                                  (splat_vector (fvti.Scalar fpimm0)),
834                                  fvti.RegClass:$rs2)),
835            (!cast<Instruction>("PseudoVMERGE_VIM_"#fvti.LMul.MX)
836                 fvti.RegClass:$rs2, 0, (fvti.Mask V0), fvti.AVL, fvti.Log2SEW)>;
837}
838
839// 14.17. Vector Single-Width Floating-Point/Integer Type-Convert Instructions
840defm : VPatConvertFP2ISDNode_V<fp_to_sint, "PseudoVFCVT_RTZ_X_F_V">;
841defm : VPatConvertFP2ISDNode_V<fp_to_uint, "PseudoVFCVT_RTZ_XU_F_V">;
842defm : VPatConvertI2FPSDNode_V<sint_to_fp, "PseudoVFCVT_F_X_V">;
843defm : VPatConvertI2FPSDNode_V<uint_to_fp, "PseudoVFCVT_F_XU_V">;
844
845// 14.18. Widening Floating-Point/Integer Type-Convert Instructions
846defm : VPatWConvertFP2ISDNode_V<fp_to_sint, "PseudoVFWCVT_RTZ_X_F_V">;
847defm : VPatWConvertFP2ISDNode_V<fp_to_uint, "PseudoVFWCVT_RTZ_XU_F_V">;
848defm : VPatWConvertI2FPSDNode_V<sint_to_fp, "PseudoVFWCVT_F_X_V">;
849defm : VPatWConvertI2FPSDNode_V<uint_to_fp, "PseudoVFWCVT_F_XU_V">;
850foreach fvtiToFWti = AllWidenableFloatVectors in {
851  defvar fvti = fvtiToFWti.Vti;
852  defvar fwti = fvtiToFWti.Wti;
853  def : Pat<(fwti.Vector (fpextend (fvti.Vector fvti.RegClass:$rs1))),
854            (!cast<Instruction>("PseudoVFWCVT_F_F_V_"#fvti.LMul.MX)
855                fvti.RegClass:$rs1, fvti.AVL, fvti.Log2SEW)>;
856}
857
858// 14.19. Narrowing Floating-Point/Integer Type-Convert Instructions
859defm : VPatNConvertFP2ISDNode_V<fp_to_sint, "PseudoVFNCVT_RTZ_X_F_W">;
860defm : VPatNConvertFP2ISDNode_V<fp_to_uint, "PseudoVFNCVT_RTZ_XU_F_W">;
861defm : VPatNConvertI2FPSDNode_V<sint_to_fp, "PseudoVFNCVT_F_X_W">;
862defm : VPatNConvertI2FPSDNode_V<uint_to_fp, "PseudoVFNCVT_F_XU_W">;
863foreach fvtiToFWti = AllWidenableFloatVectors in {
864  defvar fvti = fvtiToFWti.Vti;
865  defvar fwti = fvtiToFWti.Wti;
866  def : Pat<(fvti.Vector (fpround (fwti.Vector fwti.RegClass:$rs1))),
867            (!cast<Instruction>("PseudoVFNCVT_F_F_W_"#fvti.LMul.MX)
868                fwti.RegClass:$rs1, fvti.AVL, fvti.Log2SEW)>;
869}
870} // Predicates = [HasVInstructionsAnyF]
871
872//===----------------------------------------------------------------------===//
873// Vector Splats
874//===----------------------------------------------------------------------===//
875
876let Predicates = [HasVInstructions] in {
877foreach vti = AllIntegerVectors in {
878  def : Pat<(vti.Vector (SplatPat GPR:$rs1)),
879            (!cast<Instruction>("PseudoVMV_V_X_" # vti.LMul.MX)
880              GPR:$rs1, vti.AVL, vti.Log2SEW)>;
881  def : Pat<(vti.Vector (SplatPat_simm5 simm5:$rs1)),
882            (!cast<Instruction>("PseudoVMV_V_I_" # vti.LMul.MX)
883              simm5:$rs1, vti.AVL, vti.Log2SEW)>;
884}
885} // Predicates = [HasVInstructions]
886
887let Predicates = [HasVInstructionsAnyF] in {
888foreach fvti = AllFloatVectors in {
889  def : Pat<(fvti.Vector (splat_vector fvti.ScalarRegClass:$rs1)),
890            (!cast<Instruction>("PseudoVFMV_V_"#fvti.ScalarSuffix#"_"#fvti.LMul.MX)
891              (fvti.Scalar fvti.ScalarRegClass:$rs1),
892              fvti.AVL, fvti.Log2SEW)>;
893
894  def : Pat<(fvti.Vector (splat_vector (fvti.Scalar fpimm0))),
895            (!cast<Instruction>("PseudoVMV_V_I_"#fvti.LMul.MX)
896              0, fvti.AVL, fvti.Log2SEW)>;
897}
898} // Predicates = [HasVInstructionsAnyF]
899
900//===----------------------------------------------------------------------===//
901// Vector Element Extracts
902//===----------------------------------------------------------------------===//
903let Predicates = [HasVInstructionsAnyF] in
904foreach vti = AllFloatVectors in {
905  defvar vmv_f_s_inst = !cast<Instruction>(!strconcat("PseudoVFMV_",
906                                                       vti.ScalarSuffix,
907                                                       "_S_", vti.LMul.MX));
908  // Only pattern-match extract-element operations where the index is 0. Any
909  // other index will have been custom-lowered to slide the vector correctly
910  // into place.
911  def : Pat<(vti.Scalar (extractelt (vti.Vector vti.RegClass:$rs2), 0)),
912            (vmv_f_s_inst vti.RegClass:$rs2, vti.Log2SEW)>;
913}
914