[RISCV] Support postRA vsetvl insertion pass (#70549)
[llvm-project.git] / llvm / test / CodeGen / RISCV / rvv / abd.ll
blobddbfbd0b59fa4b62e9862a10f448cfb84da8825f
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -mattr=+v,+d -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,RV32
3 ; RUN: llc -mtriple=riscv64 -mattr=+v,+d -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,RV64
6 ; SABD
9 define <vscale x 16 x i8> @sabd_b(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b) {
10 ; CHECK-LABEL: sabd_b:
11 ; CHECK:       # %bb.0:
12 ; CHECK-NEXT:    vsetvli a0, zero, e8, m2, ta, ma
13 ; CHECK-NEXT:    vmin.vv v12, v8, v10
14 ; CHECK-NEXT:    vmax.vv v8, v8, v10
15 ; CHECK-NEXT:    vsub.vv v8, v8, v12
16 ; CHECK-NEXT:    ret
17   %a.sext = sext <vscale x 16 x i8> %a to <vscale x 16 x i16>
18   %b.sext = sext <vscale x 16 x i8> %b to <vscale x 16 x i16>
19   %sub = sub <vscale x 16 x i16> %a.sext, %b.sext
20   %abs = call <vscale x 16 x i16> @llvm.abs.nxv16i16(<vscale x 16 x i16> %sub, i1 true)
21   %trunc = trunc <vscale x 16 x i16> %abs to <vscale x 16 x i8>
22   ret <vscale x 16 x i8> %trunc
25 define <vscale x 16 x i8> @sabd_b_promoted_ops(<vscale x 16 x i1> %a, <vscale x 16 x i1> %b) {
26 ; CHECK-LABEL: sabd_b_promoted_ops:
27 ; CHECK:       # %bb.0:
28 ; CHECK-NEXT:    vsetvli a0, zero, e8, m2, ta, ma
29 ; CHECK-NEXT:    vmv.v.i v10, 0
30 ; CHECK-NEXT:    vmerge.vim v12, v10, -1, v0
31 ; CHECK-NEXT:    vmv1r.v v0, v8
32 ; CHECK-NEXT:    vmerge.vim v8, v10, -1, v0
33 ; CHECK-NEXT:    vmin.vv v10, v12, v8
34 ; CHECK-NEXT:    vmax.vv v8, v12, v8
35 ; CHECK-NEXT:    vsub.vv v8, v8, v10
36 ; CHECK-NEXT:    ret
37   %a.sext = sext <vscale x 16 x i1> %a to <vscale x 16 x i8>
38   %b.sext = sext <vscale x 16 x i1> %b to <vscale x 16 x i8>
39   %sub = sub <vscale x 16 x i8> %a.sext, %b.sext
40   %abs = call <vscale x 16 x i8> @llvm.abs.nxv16i8(<vscale x 16 x i8> %sub, i1 true)
41   ret <vscale x 16 x i8> %abs
44 define <vscale x 8 x i16> @sabd_h(<vscale x 8 x i16> %a, <vscale x 8 x i16> %b) {
45 ; CHECK-LABEL: sabd_h:
46 ; CHECK:       # %bb.0:
47 ; CHECK-NEXT:    vsetvli a0, zero, e16, m2, ta, ma
48 ; CHECK-NEXT:    vmin.vv v12, v8, v10
49 ; CHECK-NEXT:    vmax.vv v8, v8, v10
50 ; CHECK-NEXT:    vsub.vv v8, v8, v12
51 ; CHECK-NEXT:    ret
52   %a.sext = sext <vscale x 8 x i16> %a to <vscale x 8 x i32>
53   %b.sext = sext <vscale x 8 x i16> %b to <vscale x 8 x i32>
54   %sub = sub <vscale x 8 x i32> %a.sext, %b.sext
55   %abs = call <vscale x 8 x i32> @llvm.abs.nxv8i32(<vscale x 8 x i32> %sub, i1 true)
56   %trunc = trunc <vscale x 8 x i32> %abs to <vscale x 8 x i16>
57   ret <vscale x 8 x i16> %trunc
60 define <vscale x 8 x i16> @sabd_h_promoted_ops(<vscale x 8 x i8> %a, <vscale x 8 x i8> %b) {
61 ; CHECK-LABEL: sabd_h_promoted_ops:
62 ; CHECK:       # %bb.0:
63 ; CHECK-NEXT:    vsetvli a0, zero, e8, m1, ta, ma
64 ; CHECK-NEXT:    vmin.vv v10, v8, v9
65 ; CHECK-NEXT:    vmax.vv v8, v8, v9
66 ; CHECK-NEXT:    vsub.vv v10, v8, v10
67 ; CHECK-NEXT:    vsetvli zero, zero, e16, m2, ta, ma
68 ; CHECK-NEXT:    vzext.vf2 v8, v10
69 ; CHECK-NEXT:    ret
70   %a.sext = sext <vscale x 8 x i8> %a to <vscale x 8 x i16>
71   %b.sext = sext <vscale x 8 x i8> %b to <vscale x 8 x i16>
72   %sub = sub <vscale x 8 x i16> %a.sext, %b.sext
73   %abs = call <vscale x 8 x i16> @llvm.abs.nxv8i16(<vscale x 8 x i16> %sub, i1 true)
74   ret <vscale x 8 x i16> %abs
77 define <vscale x 4 x i32> @sabd_s(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) {
78 ; CHECK-LABEL: sabd_s:
79 ; CHECK:       # %bb.0:
80 ; CHECK-NEXT:    vsetvli a0, zero, e32, m2, ta, ma
81 ; CHECK-NEXT:    vmin.vv v12, v8, v10
82 ; CHECK-NEXT:    vmax.vv v8, v8, v10
83 ; CHECK-NEXT:    vsub.vv v8, v8, v12
84 ; CHECK-NEXT:    ret
85   %a.sext = sext <vscale x 4 x i32> %a to <vscale x 4 x i64>
86   %b.sext = sext <vscale x 4 x i32> %b to <vscale x 4 x i64>
87   %sub = sub <vscale x 4 x i64> %a.sext, %b.sext
88   %abs = call <vscale x 4 x i64> @llvm.abs.nxv4i64(<vscale x 4 x i64> %sub, i1 true)
89   %trunc = trunc <vscale x 4 x i64> %abs to <vscale x 4 x i32>
90   ret <vscale x 4 x i32> %trunc
93 define <vscale x 4 x i32> @sabd_s_promoted_ops(<vscale x 4 x i16> %a, <vscale x 4 x i16> %b) {
94 ; CHECK-LABEL: sabd_s_promoted_ops:
95 ; CHECK:       # %bb.0:
96 ; CHECK-NEXT:    vsetvli a0, zero, e16, m1, ta, ma
97 ; CHECK-NEXT:    vmin.vv v10, v8, v9
98 ; CHECK-NEXT:    vmax.vv v8, v8, v9
99 ; CHECK-NEXT:    vsub.vv v10, v8, v10
100 ; CHECK-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
101 ; CHECK-NEXT:    vzext.vf2 v8, v10
102 ; CHECK-NEXT:    ret
103   %a.sext = sext <vscale x 4 x i16> %a to <vscale x 4 x i32>
104   %b.sext = sext <vscale x 4 x i16> %b to <vscale x 4 x i32>
105   %sub = sub <vscale x 4 x i32> %a.sext, %b.sext
106   %abs = call <vscale x 4 x i32> @llvm.abs.nxv4i32(<vscale x 4 x i32> %sub, i1 true)
107   ret <vscale x 4 x i32> %abs
110 ; FIXME: Crashes legalization if enabled
111 ;; define <vscale x 2 x i64> @sabd_d(<vscale x 2 x i64> %a, <vscale x 2 x i64> %b) {
112 ;;   %a.sext = sext <vscale x 2 x i64> %a to <vscale x 2 x i128>
113 ;;   %b.sext = sext <vscale x 2 x i64> %b to <vscale x 2 x i128>
114 ;;   %sub = sub <vscale x 2 x i128> %a.sext, %b.sext
115 ;;   %abs = call <vscale x 2 x i128> @llvm.abs.nxv2i128(<vscale x 2 x i128> %sub, i1 true)
116 ;;   %trunc = trunc <vscale x 2 x i128> %abs to <vscale x 2 x i64>
117 ;;   ret <vscale x 2 x i64> %trunc
118 ;; }
120 define <vscale x 2 x i64> @sabd_d_promoted_ops(<vscale x 2 x i32> %a, <vscale x 2 x i32> %b) {
121 ; CHECK-LABEL: sabd_d_promoted_ops:
122 ; CHECK:       # %bb.0:
123 ; CHECK-NEXT:    vsetvli a0, zero, e32, m1, ta, ma
124 ; CHECK-NEXT:    vmin.vv v10, v8, v9
125 ; CHECK-NEXT:    vmax.vv v8, v8, v9
126 ; CHECK-NEXT:    vsub.vv v10, v8, v10
127 ; CHECK-NEXT:    vsetvli zero, zero, e64, m2, ta, ma
128 ; CHECK-NEXT:    vzext.vf2 v8, v10
129 ; CHECK-NEXT:    ret
130   %a.sext = sext <vscale x 2 x i32> %a to <vscale x 2 x i64>
131   %b.sext = sext <vscale x 2 x i32> %b to <vscale x 2 x i64>
132   %sub = sub <vscale x 2 x i64> %a.sext, %b.sext
133   %abs = call <vscale x 2 x i64> @llvm.abs.nxv2i64(<vscale x 2 x i64> %sub, i1 true)
134   ret <vscale x 2 x i64> %abs
138 ; UABD
141 define <vscale x 16 x i8> @uabd_b(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b) {
142 ; CHECK-LABEL: uabd_b:
143 ; CHECK:       # %bb.0:
144 ; CHECK-NEXT:    vsetvli a0, zero, e8, m2, ta, ma
145 ; CHECK-NEXT:    vminu.vv v12, v8, v10
146 ; CHECK-NEXT:    vmaxu.vv v8, v8, v10
147 ; CHECK-NEXT:    vsub.vv v8, v8, v12
148 ; CHECK-NEXT:    ret
149   %a.zext = zext <vscale x 16 x i8> %a to <vscale x 16 x i16>
150   %b.zext = zext <vscale x 16 x i8> %b to <vscale x 16 x i16>
151   %sub = sub <vscale x 16 x i16> %a.zext, %b.zext
152   %abs = call <vscale x 16 x i16> @llvm.abs.nxv16i16(<vscale x 16 x i16> %sub, i1 true)
153   %trunc = trunc <vscale x 16 x i16> %abs to <vscale x 16 x i8>
154   ret <vscale x 16 x i8> %trunc
157 define <vscale x 16 x i8> @uabd_b_promoted_ops(<vscale x 16 x i1> %a, <vscale x 16 x i1> %b) {
158 ; CHECK-LABEL: uabd_b_promoted_ops:
159 ; CHECK:       # %bb.0:
160 ; CHECK-NEXT:    vsetvli a0, zero, e8, m2, ta, ma
161 ; CHECK-NEXT:    vmv.v.i v10, 0
162 ; CHECK-NEXT:    vmerge.vim v12, v10, 1, v0
163 ; CHECK-NEXT:    vmv1r.v v0, v8
164 ; CHECK-NEXT:    vmerge.vim v8, v10, 1, v0
165 ; CHECK-NEXT:    vminu.vv v10, v12, v8
166 ; CHECK-NEXT:    vmaxu.vv v8, v12, v8
167 ; CHECK-NEXT:    vsub.vv v8, v8, v10
168 ; CHECK-NEXT:    ret
169   %a.zext = zext <vscale x 16 x i1> %a to <vscale x 16 x i8>
170   %b.zext = zext <vscale x 16 x i1> %b to <vscale x 16 x i8>
171   %sub = sub <vscale x 16 x i8> %a.zext, %b.zext
172   %abs = call <vscale x 16 x i8> @llvm.abs.nxv16i8(<vscale x 16 x i8> %sub, i1 true)
173   ret <vscale x 16 x i8> %abs
176 define <vscale x 8 x i16> @uabd_h(<vscale x 8 x i16> %a, <vscale x 8 x i16> %b) {
177 ; CHECK-LABEL: uabd_h:
178 ; CHECK:       # %bb.0:
179 ; CHECK-NEXT:    vsetvli a0, zero, e16, m2, ta, ma
180 ; CHECK-NEXT:    vminu.vv v12, v8, v10
181 ; CHECK-NEXT:    vmaxu.vv v8, v8, v10
182 ; CHECK-NEXT:    vsub.vv v8, v8, v12
183 ; CHECK-NEXT:    ret
184   %a.zext = zext <vscale x 8 x i16> %a to <vscale x 8 x i32>
185   %b.zext = zext <vscale x 8 x i16> %b to <vscale x 8 x i32>
186   %sub = sub <vscale x 8 x i32> %a.zext, %b.zext
187   %abs = call <vscale x 8 x i32> @llvm.abs.nxv8i32(<vscale x 8 x i32> %sub, i1 true)
188   %trunc = trunc <vscale x 8 x i32> %abs to <vscale x 8 x i16>
189   ret <vscale x 8 x i16> %trunc
192 define <vscale x 8 x i16> @uabd_h_promoted_ops(<vscale x 8 x i8> %a, <vscale x 8 x i8> %b) {
193 ; CHECK-LABEL: uabd_h_promoted_ops:
194 ; CHECK:       # %bb.0:
195 ; CHECK-NEXT:    vsetvli a0, zero, e8, m1, ta, ma
196 ; CHECK-NEXT:    vminu.vv v10, v8, v9
197 ; CHECK-NEXT:    vmaxu.vv v8, v8, v9
198 ; CHECK-NEXT:    vsub.vv v10, v8, v10
199 ; CHECK-NEXT:    vsetvli zero, zero, e16, m2, ta, ma
200 ; CHECK-NEXT:    vzext.vf2 v8, v10
201 ; CHECK-NEXT:    ret
202   %a.zext = zext <vscale x 8 x i8> %a to <vscale x 8 x i16>
203   %b.zext = zext <vscale x 8 x i8> %b to <vscale x 8 x i16>
204   %sub = sub <vscale x 8 x i16> %a.zext, %b.zext
205   %abs = call <vscale x 8 x i16> @llvm.abs.nxv8i16(<vscale x 8 x i16> %sub, i1 true)
206   ret <vscale x 8 x i16> %abs
209 define <vscale x 4 x i32> @uabd_s(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) {
210 ; CHECK-LABEL: uabd_s:
211 ; CHECK:       # %bb.0:
212 ; CHECK-NEXT:    vsetvli a0, zero, e32, m2, ta, ma
213 ; CHECK-NEXT:    vminu.vv v12, v8, v10
214 ; CHECK-NEXT:    vmaxu.vv v8, v8, v10
215 ; CHECK-NEXT:    vsub.vv v8, v8, v12
216 ; CHECK-NEXT:    ret
217   %a.zext = zext <vscale x 4 x i32> %a to <vscale x 4 x i64>
218   %b.zext = zext <vscale x 4 x i32> %b to <vscale x 4 x i64>
219   %sub = sub <vscale x 4 x i64> %a.zext, %b.zext
220   %abs = call <vscale x 4 x i64> @llvm.abs.nxv4i64(<vscale x 4 x i64> %sub, i1 true)
221   %trunc = trunc <vscale x 4 x i64> %abs to <vscale x 4 x i32>
222   ret <vscale x 4 x i32> %trunc
225 define <vscale x 4 x i32> @uabd_s_promoted_ops(<vscale x 4 x i16> %a, <vscale x 4 x i16> %b) {
226 ; CHECK-LABEL: uabd_s_promoted_ops:
227 ; CHECK:       # %bb.0:
228 ; CHECK-NEXT:    vsetvli a0, zero, e16, m1, ta, ma
229 ; CHECK-NEXT:    vminu.vv v10, v8, v9
230 ; CHECK-NEXT:    vmaxu.vv v8, v8, v9
231 ; CHECK-NEXT:    vsub.vv v10, v8, v10
232 ; CHECK-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
233 ; CHECK-NEXT:    vzext.vf2 v8, v10
234 ; CHECK-NEXT:    ret
235   %a.zext = zext <vscale x 4 x i16> %a to <vscale x 4 x i32>
236   %b.zext = zext <vscale x 4 x i16> %b to <vscale x 4 x i32>
237   %sub = sub <vscale x 4 x i32> %a.zext, %b.zext
238   %abs = call <vscale x 4 x i32> @llvm.abs.nxv4i32(<vscale x 4 x i32> %sub, i1 true)
239   ret <vscale x 4 x i32> %abs
242 ; FIXME: Crashes legalization if enabled
243 ;; define <vscale x 2 x i64> @uabd_d(<vscale x 2 x i64> %a, <vscale x 2 x i64> %b) {
244 ;;   %a.zext = zext <vscale x 2 x i64> %a to <vscale x 2 x i128>
245 ;;   %b.zext = zext <vscale x 2 x i64> %b to <vscale x 2 x i128>
246 ;;   %sub = sub <vscale x 2 x i128> %a.zext, %b.zext
247 ;;   %abs = call <vscale x 2 x i128> @llvm.abs.nxv2i128(<vscale x 2 x i128> %sub, i1 true)
248 ;;   %trunc = trunc <vscale x 2 x i128> %abs to <vscale x 2 x i64>
249 ;;   ret <vscale x 2 x i64> %trunc
250 ;; }
252 define <vscale x 2 x i64> @uabd_d_promoted_ops(<vscale x 2 x i32> %a, <vscale x 2 x i32> %b) {
253 ; CHECK-LABEL: uabd_d_promoted_ops:
254 ; CHECK:       # %bb.0:
255 ; CHECK-NEXT:    vsetvli a0, zero, e32, m1, ta, ma
256 ; CHECK-NEXT:    vminu.vv v10, v8, v9
257 ; CHECK-NEXT:    vmaxu.vv v8, v8, v9
258 ; CHECK-NEXT:    vsub.vv v10, v8, v10
259 ; CHECK-NEXT:    vsetvli zero, zero, e64, m2, ta, ma
260 ; CHECK-NEXT:    vzext.vf2 v8, v10
261 ; CHECK-NEXT:    ret
262   %a.zext = zext <vscale x 2 x i32> %a to <vscale x 2 x i64>
263   %b.zext = zext <vscale x 2 x i32> %b to <vscale x 2 x i64>
264   %sub = sub <vscale x 2 x i64> %a.zext, %b.zext
265   %abs = call <vscale x 2 x i64> @llvm.abs.nxv2i64(<vscale x 2 x i64> %sub, i1 true)
266   ret <vscale x 2 x i64> %abs
269 ; Test the situation where isLegal(ISD::ABD, typeof(%a)) returns true but %a and
270 ; %b have differing types.
271 define <vscale x 4 x i32> @uabd_non_matching_extension(<vscale x 4 x i32> %a, <vscale x 4 x i8> %b) {
272 ; CHECK-LABEL: uabd_non_matching_extension:
273 ; CHECK:       # %bb.0:
274 ; CHECK-NEXT:    vsetvli a0, zero, e32, m2, ta, ma
275 ; CHECK-NEXT:    vzext.vf4 v12, v10
276 ; CHECK-NEXT:    vminu.vv v10, v8, v12
277 ; CHECK-NEXT:    vmaxu.vv v8, v8, v12
278 ; CHECK-NEXT:    vsub.vv v8, v8, v10
279 ; CHECK-NEXT:    ret
280   %a.zext = zext <vscale x 4 x i32> %a to <vscale x 4 x i64>
281   %b.zext = zext <vscale x 4 x i8> %b to <vscale x 4 x i64>
282   %sub = sub <vscale x 4 x i64> %a.zext, %b.zext
283   %abs = call <vscale x 4 x i64> @llvm.abs.nxv4i64(<vscale x 4 x i64> %sub, i1 true)
284   %trunc = trunc <vscale x 4 x i64> %abs to <vscale x 4 x i32>
285   ret <vscale x 4 x i32> %trunc
288 ; Test the situation where isLegal(ISD::ABD, typeof(%a.zext)) returns true but
289 ; %a and %b have differing types.
290 define <vscale x 4 x i32> @uabd_non_matching_promoted_ops(<vscale x 4 x i8> %a, <vscale x 4 x i16> %b) {
291 ; CHECK-LABEL: uabd_non_matching_promoted_ops:
292 ; CHECK:       # %bb.0:
293 ; CHECK-NEXT:    vsetvli a0, zero, e16, m1, ta, ma
294 ; CHECK-NEXT:    vzext.vf2 v10, v8
295 ; CHECK-NEXT:    vminu.vv v8, v10, v9
296 ; CHECK-NEXT:    vmaxu.vv v9, v10, v9
297 ; CHECK-NEXT:    vsub.vv v10, v9, v8
298 ; CHECK-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
299 ; CHECK-NEXT:    vzext.vf2 v8, v10
300 ; CHECK-NEXT:    ret
301   %a.zext = zext <vscale x 4 x i8> %a to <vscale x 4 x i32>
302   %b.zext = zext <vscale x 4 x i16> %b to <vscale x 4 x i32>
303   %sub = sub <vscale x 4 x i32> %a.zext, %b.zext
304   %abs = call <vscale x 4 x i32> @llvm.abs.nxv4i32(<vscale x 4 x i32> %sub, i1 true)
305   ret <vscale x 4 x i32> %abs
308 ; Test the situation where isLegal(ISD::ABD, typeof(%a)) returns true but %a and
309 ; %b are promoted differently.
310 define <vscale x 4 x i32> @uabd_non_matching_promotion(<vscale x 4 x i8> %a, <vscale x 4 x i8> %b) {
311 ; CHECK-LABEL: uabd_non_matching_promotion:
312 ; CHECK:       # %bb.0:
313 ; CHECK-NEXT:    vsetvli a0, zero, e32, m2, ta, ma
314 ; CHECK-NEXT:    vzext.vf4 v10, v8
315 ; CHECK-NEXT:    vsetvli zero, zero, e16, m1, ta, ma
316 ; CHECK-NEXT:    vsext.vf2 v8, v9
317 ; CHECK-NEXT:    vwsub.wv v10, v10, v8
318 ; CHECK-NEXT:    vsetvli zero, zero, e32, m2, ta, ma
319 ; CHECK-NEXT:    vrsub.vi v8, v10, 0
320 ; CHECK-NEXT:    vmax.vv v8, v10, v8
321 ; CHECK-NEXT:    ret
322   %a.zext = zext <vscale x 4 x i8> %a to <vscale x 4 x i32>
323   %b.zext = sext <vscale x 4 x i8> %b to <vscale x 4 x i32>
324   %sub = sub <vscale x 4 x i32> %a.zext, %b.zext
325   %abs = call <vscale x 4 x i32> @llvm.abs.nxv4i32(<vscale x 4 x i32> %sub, i1 true)
326   ret <vscale x 4 x i32> %abs
329 declare <vscale x 16 x i8> @llvm.abs.nxv16i8(<vscale x 16 x i8>, i1)
331 declare <vscale x 8 x i16> @llvm.abs.nxv8i16(<vscale x 8 x i16>, i1)
332 declare <vscale x 16 x i16> @llvm.abs.nxv16i16(<vscale x 16 x i16>, i1)
334 declare <vscale x 4 x i32> @llvm.abs.nxv4i32(<vscale x 4 x i32>, i1)
335 declare <vscale x 8 x i32> @llvm.abs.nxv8i32(<vscale x 8 x i32>, i1)
337 declare <vscale x 2 x i64> @llvm.abs.nxv2i64(<vscale x 2 x i64>, i1)
338 declare <vscale x 4 x i64> @llvm.abs.nxv4i64(<vscale x 4 x i64>, i1)
340 declare <vscale x 2 x i128> @llvm.abs.nxv2i128(<vscale x 2 x i128>, i1)
341 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
342 ; RV32: {{.*}}
343 ; RV64: {{.*}}