RISC-V: Split off shift patterns for autovectorization.
[official-gcc.git] / gcc / config / riscv / autovec.md
blobac0c939d277e99e4b6909fbb043202f8528955b3
1 ;; Machine description for auto-vectorization using RVV for GNU compiler.
2 ;; Copyright (C) 2023 Free Software Foundation, Inc.
3 ;; Contributed by Juzhe Zhong (juzhe.zhong@rivai.ai), RiVAI Technologies Ltd.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;; =========================================================================
22 ;; == Loads/Stores
23 ;; =========================================================================
25 ;; len_load/len_store is a sub-optimal pattern for RVV auto-vectorization support.
26 ;; We will replace them when len_maskload/len_maskstore is supported in loop vectorizer.
27 (define_expand "len_load_<mode>"
28   [(match_operand:V 0 "register_operand")
29    (match_operand:V 1 "memory_operand")
30    (match_operand 2 "vector_length_operand")
31    (match_operand 3 "const_0_operand")]
32   "TARGET_VECTOR"
34   riscv_vector::emit_len_op (code_for_pred_mov (<MODE>mode), operands[0],
35                              operands[1], operands[2], <VM>mode);
36   DONE;
39 (define_expand "len_store_<mode>"
40   [(match_operand:V 0 "memory_operand")
41    (match_operand:V 1 "register_operand")
42    (match_operand 2 "vector_length_operand")
43    (match_operand 3 "const_0_operand")]
44   "TARGET_VECTOR"
46   riscv_vector::emit_len_op (code_for_pred_mov (<MODE>mode), operands[0],
47                              operands[1], operands[2], <VM>mode);
48   DONE;
51 (define_expand "movmisalign<mode>"
52   [(set (match_operand:V 0 "nonimmediate_operand")
53         (match_operand:V 1 "general_operand"))]
54   "TARGET_VECTOR"
55   {
56     /* Equivalent to a normal move for our purpooses.  */
57     emit_move_insn (operands[0], operands[1]);
58     DONE;
59   }
62 ;; =========================================================================
63 ;; == Vector creation
64 ;; =========================================================================
66 ;; -------------------------------------------------------------------------
67 ;; ---- [INT] Linear series
68 ;; -------------------------------------------------------------------------
69 ;; Includes:
70 ;; - vid.v
71 ;; - vmul.vx
72 ;; - vadd.vx/vadd.vi
73 ;; -------------------------------------------------------------------------
75 (define_expand "@vec_series<mode>"
76   [(match_operand:VI 0 "register_operand")
77    (match_operand:<VEL> 1 "reg_or_int_operand")
78    (match_operand:<VEL> 2 "reg_or_int_operand")]
79   "TARGET_VECTOR"
80   {
81     riscv_vector::expand_vec_series (operands[0], operands[1], operands[2]);
82     DONE;
83   }
86 ;; ========================================================================
87 ;; == Vector operations
88 ;; =========================================================================
90 ;; -------------------------------------------------------------------------
91 ;; ---- [INT] Binary operations
92 ;; -------------------------------------------------------------------------
93 ;; Includes:
94 ;; - vadd.vv/vsub.vv/...
95 ;; - vadd.vi/vsub.vi/...
96 ;; -------------------------------------------------------------------------
98 (define_expand "<optab><mode>3"
99   [(set (match_operand:VI 0 "register_operand")
100     (any_int_binop_no_shift:VI
101      (match_operand:VI 1 "<binop_rhs1_predicate>")
102      (match_operand:VI 2 "<binop_rhs2_predicate>")))]
103   "TARGET_VECTOR"
105   if (!register_operand (operands[2], <MODE>mode))
106     {
107       rtx cst;
108       gcc_assert (const_vec_duplicate_p(operands[2], &cst));
109       riscv_vector::emit_len_binop (code_for_pred_scalar
110                                     (<CODE>, <MODE>mode),
111                                     operands[0], operands[1], cst,
112                                     NULL, <VM>mode,
113                                     <VEL>mode);
114     }
115   else
116     riscv_vector::emit_len_binop (code_for_pred
117                                   (<CODE>, <MODE>mode),
118                                   operands[0], operands[1], operands[2],
119                                   NULL, <VM>mode);
120   DONE;
123 ;; -------------------------------------------------------------------------
124 ;; ---- [INT] Binary shifts by scalar.
125 ;; -------------------------------------------------------------------------
126 ;; Includes:
127 ;; - vsll.vx/vsra.vx/vsrl.vx
128 ;; - vsll.vi/vsra.vi/vsrl.vi
129 ;; -------------------------------------------------------------------------
131 (define_expand "<optab><mode>3"
132   [(set (match_operand:VI 0 "register_operand")
133     (any_shift:VI
134      (match_operand:VI 1 "register_operand")
135      (match_operand:<VEL> 2 "csr_operand")))]
136   "TARGET_VECTOR"
138   if (!CONST_SCALAR_INT_P (operands[2]))
139       operands[2] = gen_lowpart (Pmode, operands[2]);
140   riscv_vector::emit_len_binop (code_for_pred_scalar
141                                 (<CODE>, <MODE>mode),
142                                 operands[0], operands[1], operands[2],
143                                 NULL_RTX, <VM>mode, Pmode);
144   DONE;
147 ;; -------------------------------------------------------------------------
148 ;; ---- [INT] Binary shifts by scalar.
149 ;; -------------------------------------------------------------------------
150 ;; Includes:
151 ;; - vsll.vv/vsra.vv/vsrl.vv
152 ;; -------------------------------------------------------------------------
154 (define_expand "v<optab><mode>3"
155   [(set (match_operand:VI 0 "register_operand")
156     (any_shift:VI
157      (match_operand:VI 1 "register_operand")
158      (match_operand:VI 2 "vector_shift_operand")))]
159   "TARGET_VECTOR"
161   riscv_vector::emit_len_binop (code_for_pred
162                                 (<CODE>, <MODE>mode),
163                                 operands[0], operands[1], operands[2],
164                                 NULL_RTX, <VM>mode);
165   DONE;