[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / neon-abd.ll
blob901cb8adc23f097f05f18f1589b7e1a7bf388a8c
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s | FileCheck %s
4 target triple = "aarch64-unknown-linux-gnu"
7 ; SABD
10 define <8 x i8> @sabd_8b(<8 x i8> %a, <8 x i8> %b) #0 {
11 ; CHECK-LABEL: sabd_8b:
12 ; CHECK:       // %bb.0:
13 ; CHECK-NEXT:    sabd v0.8b, v0.8b, v1.8b
14 ; CHECK-NEXT:    ret
15   %a.sext = sext <8 x i8> %a to <8 x i16>
16   %b.sext = sext <8 x i8> %b to <8 x i16>
17   %sub = sub <8 x i16> %a.sext, %b.sext
18   %abs = call <8 x i16> @llvm.abs.v8i16(<8 x i16> %sub, i1 true)
19   %trunc = trunc <8 x i16> %abs to <8 x i8>
20   ret <8 x i8> %trunc
23 define <16 x i8> @sabd_16b(<16 x i8> %a, <16 x i8> %b) #0 {
24 ; CHECK-LABEL: sabd_16b:
25 ; CHECK:       // %bb.0:
26 ; CHECK-NEXT:    sabd v0.16b, v0.16b, v1.16b
27 ; CHECK-NEXT:    ret
28   %a.sext = sext <16 x i8> %a to <16 x i16>
29   %b.sext = sext <16 x i8> %b to <16 x i16>
30   %sub = sub <16 x i16> %a.sext, %b.sext
31   %abs = call <16 x i16> @llvm.abs.v16i16(<16 x i16> %sub, i1 true)
32   %trunc = trunc <16 x i16> %abs to <16 x i8>
33   ret <16 x i8> %trunc
36 define <4 x i16> @sabd_4h(<4 x i16> %a, <4 x i16> %b) #0 {
37 ; CHECK-LABEL: sabd_4h:
38 ; CHECK:       // %bb.0:
39 ; CHECK-NEXT:    sabd v0.4h, v0.4h, v1.4h
40 ; CHECK-NEXT:    ret
41   %a.sext = sext <4 x i16> %a to <4 x i32>
42   %b.sext = sext <4 x i16> %b to <4 x i32>
43   %sub = sub <4 x i32> %a.sext, %b.sext
44   %abs = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %sub, i1 true)
45   %trunc = trunc <4 x i32> %abs to <4 x i16>
46   ret <4 x i16> %trunc
49 define <4 x i16> @sabd_4h_promoted_ops(<4 x i8> %a, <4 x i8> %b) #0 {
50 ; CHECK-LABEL: sabd_4h_promoted_ops:
51 ; CHECK:       // %bb.0:
52 ; CHECK-NEXT:    shl v0.4h, v0.4h, #8
53 ; CHECK-NEXT:    shl v1.4h, v1.4h, #8
54 ; CHECK-NEXT:    sshr v0.4h, v0.4h, #8
55 ; CHECK-NEXT:    sshr v1.4h, v1.4h, #8
56 ; CHECK-NEXT:    sabd v0.4h, v0.4h, v1.4h
57 ; CHECK-NEXT:    ret
58   %a.sext = sext <4 x i8> %a to <4 x i16>
59   %b.sext = sext <4 x i8> %b to <4 x i16>
60   %sub = sub <4 x i16> %a.sext, %b.sext
61   %abs = call <4 x i16> @llvm.abs.v4i16(<4 x i16> %sub, i1 true)
62   ret <4 x i16> %abs
65 define <8 x i16> @sabd_8h(<8 x i16> %a, <8 x i16> %b) #0 {
66 ; CHECK-LABEL: sabd_8h:
67 ; CHECK:       // %bb.0:
68 ; CHECK-NEXT:    sabd v0.8h, v0.8h, v1.8h
69 ; CHECK-NEXT:    ret
70   %a.sext = sext <8 x i16> %a to <8 x i32>
71   %b.sext = sext <8 x i16> %b to <8 x i32>
72   %sub = sub <8 x i32> %a.sext, %b.sext
73   %abs = call <8 x i32> @llvm.abs.v8i32(<8 x i32> %sub, i1 true)
74   %trunc = trunc <8 x i32> %abs to <8 x i16>
75   ret <8 x i16> %trunc
78 define <8 x i16> @sabd_8h_promoted_ops(<8 x i8> %a, <8 x i8> %b) #0 {
79 ; CHECK-LABEL: sabd_8h_promoted_ops:
80 ; CHECK:       // %bb.0:
81 ; CHECK-NEXT:    sabdl v0.8h, v0.8b, v1.8b
82 ; CHECK-NEXT:    ret
83   %a.sext = sext <8 x i8> %a to <8 x i16>
84   %b.sext = sext <8 x i8> %b to <8 x i16>
85   %sub = sub <8 x i16> %a.sext, %b.sext
86   %abs = call <8 x i16> @llvm.abs.v8i16(<8 x i16> %sub, i1 true)
87   ret <8 x i16> %abs
90 define <2 x i32> @sabd_2s(<2 x i32> %a, <2 x i32> %b) #0 {
91 ; CHECK-LABEL: sabd_2s:
92 ; CHECK:       // %bb.0:
93 ; CHECK-NEXT:    sabd v0.2s, v0.2s, v1.2s
94 ; CHECK-NEXT:    ret
95   %a.sext = sext <2 x i32> %a to <2 x i64>
96   %b.sext = sext <2 x i32> %b to <2 x i64>
97   %sub = sub <2 x i64> %a.sext, %b.sext
98   %abs = call <2 x i64> @llvm.abs.v2i64(<2 x i64> %sub, i1 true)
99   %trunc = trunc <2 x i64> %abs to <2 x i32>
100   ret <2 x i32> %trunc
103 define <2 x i32> @sabd_2s_promoted_ops(<2 x i16> %a, <2 x i16> %b) #0 {
104 ; CHECK-LABEL: sabd_2s_promoted_ops:
105 ; CHECK:       // %bb.0:
106 ; CHECK-NEXT:    shl v0.2s, v0.2s, #16
107 ; CHECK-NEXT:    shl v1.2s, v1.2s, #16
108 ; CHECK-NEXT:    sshr v0.2s, v0.2s, #16
109 ; CHECK-NEXT:    sshr v1.2s, v1.2s, #16
110 ; CHECK-NEXT:    sabd v0.2s, v0.2s, v1.2s
111 ; CHECK-NEXT:    ret
112   %a.sext = sext <2 x i16> %a to <2 x i32>
113   %b.sext = sext <2 x i16> %b to <2 x i32>
114   %sub = sub <2 x i32> %a.sext, %b.sext
115   %abs = call <2 x i32> @llvm.abs.v2i32(<2 x i32> %sub, i1 true)
116   ret <2 x i32> %abs
119 define <4 x i32> @sabd_4s(<4 x i32> %a, <4 x i32> %b) #0 {
120 ; CHECK-LABEL: sabd_4s:
121 ; CHECK:       // %bb.0:
122 ; CHECK-NEXT:    sabd v0.4s, v0.4s, v1.4s
123 ; CHECK-NEXT:    ret
124   %a.sext = sext <4 x i32> %a to <4 x i64>
125   %b.sext = sext <4 x i32> %b to <4 x i64>
126   %sub = sub <4 x i64> %a.sext, %b.sext
127   %abs = call <4 x i64> @llvm.abs.v4i64(<4 x i64> %sub, i1 true)
128   %trunc = trunc <4 x i64> %abs to <4 x i32>
129   ret <4 x i32> %trunc
132 define <4 x i32> @sabd_4s_promoted_ops(<4 x i16> %a, <4 x i16> %b) #0 {
133 ; CHECK-LABEL: sabd_4s_promoted_ops:
134 ; CHECK:       // %bb.0:
135 ; CHECK-NEXT:    sabdl v0.4s, v0.4h, v1.4h
136 ; CHECK-NEXT:    ret
137   %a.sext = sext <4 x i16> %a to <4 x i32>
138   %b.sext = sext <4 x i16> %b to <4 x i32>
139   %sub = sub <4 x i32> %a.sext, %b.sext
140   %abs = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %sub, i1 true)
141   ret <4 x i32> %abs
144 define <2 x i64> @sabd_2d(<2 x i64> %a, <2 x i64> %b) #0 {
145 ; CHECK-LABEL: sabd_2d:
146 ; CHECK:       // %bb.0:
147 ; CHECK-NEXT:    mov x8, v0.d[1]
148 ; CHECK-NEXT:    mov x9, v1.d[1]
149 ; CHECK-NEXT:    fmov x10, d0
150 ; CHECK-NEXT:    fmov x12, d1
151 ; CHECK-NEXT:    asr x14, x10, #63
152 ; CHECK-NEXT:    asr x11, x8, #63
153 ; CHECK-NEXT:    asr x13, x9, #63
154 ; CHECK-NEXT:    asr x15, x12, #63
155 ; CHECK-NEXT:    subs x8, x8, x9
156 ; CHECK-NEXT:    sbc x9, x11, x13
157 ; CHECK-NEXT:    subs x10, x10, x12
158 ; CHECK-NEXT:    sbc x11, x14, x15
159 ; CHECK-NEXT:    asr x9, x9, #63
160 ; CHECK-NEXT:    asr x11, x11, #63
161 ; CHECK-NEXT:    eor x8, x8, x9
162 ; CHECK-NEXT:    eor x10, x10, x11
163 ; CHECK-NEXT:    sub x8, x8, x9
164 ; CHECK-NEXT:    sub x10, x10, x11
165 ; CHECK-NEXT:    fmov d1, x8
166 ; CHECK-NEXT:    fmov d0, x10
167 ; CHECK-NEXT:    mov v0.d[1], v1.d[0]
168 ; CHECK-NEXT:    ret
169   %a.sext = sext <2 x i64> %a to <2 x i128>
170   %b.sext = sext <2 x i64> %b to <2 x i128>
171   %sub = sub <2 x i128> %a.sext, %b.sext
172   %abs = call <2 x i128> @llvm.abs.v2i128(<2 x i128> %sub, i1 true)
173   %trunc = trunc <2 x i128> %abs to <2 x i64>
174   ret <2 x i64> %trunc
177 define <2 x i64> @sabd_2d_promoted_ops(<2 x i32> %a, <2 x i32> %b) #0 {
178 ; CHECK-LABEL: sabd_2d_promoted_ops:
179 ; CHECK:       // %bb.0:
180 ; CHECK-NEXT:    sabdl v0.2d, v0.2s, v1.2s
181 ; CHECK-NEXT:    ret
182   %a.sext = sext <2 x i32> %a to <2 x i64>
183   %b.sext = sext <2 x i32> %b to <2 x i64>
184   %sub = sub <2 x i64> %a.sext, %b.sext
185   %abs = call <2 x i64> @llvm.abs.v2i64(<2 x i64> %sub, i1 true)
186   ret <2 x i64> %abs
190 ; UABD
193 define <8 x i8> @uabd_8b(<8 x i8> %a, <8 x i8> %b) #0 {
194 ; CHECK-LABEL: uabd_8b:
195 ; CHECK:       // %bb.0:
196 ; CHECK-NEXT:    uabd v0.8b, v0.8b, v1.8b
197 ; CHECK-NEXT:    ret
198   %a.zext = zext <8 x i8> %a to <8 x i16>
199   %b.zext = zext <8 x i8> %b to <8 x i16>
200   %sub = sub <8 x i16> %a.zext, %b.zext
201   %abs = call <8 x i16> @llvm.abs.v8i16(<8 x i16> %sub, i1 true)
202   %trunc = trunc <8 x i16> %abs to <8 x i8>
203   ret <8 x i8> %trunc
206 define <16 x i8> @uabd_16b(<16 x i8> %a, <16 x i8> %b) #0 {
207 ; CHECK-LABEL: uabd_16b:
208 ; CHECK:       // %bb.0:
209 ; CHECK-NEXT:    uabd v0.16b, v0.16b, v1.16b
210 ; CHECK-NEXT:    ret
211   %a.zext = zext <16 x i8> %a to <16 x i16>
212   %b.zext = zext <16 x i8> %b to <16 x i16>
213   %sub = sub <16 x i16> %a.zext, %b.zext
214   %abs = call <16 x i16> @llvm.abs.v16i16(<16 x i16> %sub, i1 true)
215   %trunc = trunc <16 x i16> %abs to <16 x i8>
216   ret <16 x i8> %trunc
219 define <4 x i16> @uabd_4h(<4 x i16> %a, <4 x i16> %b) #0 {
220 ; CHECK-LABEL: uabd_4h:
221 ; CHECK:       // %bb.0:
222 ; CHECK-NEXT:    uabd v0.4h, v0.4h, v1.4h
223 ; CHECK-NEXT:    ret
224   %a.zext = zext <4 x i16> %a to <4 x i32>
225   %b.zext = zext <4 x i16> %b to <4 x i32>
226   %sub = sub <4 x i32> %a.zext, %b.zext
227   %abs = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %sub, i1 true)
228   %trunc = trunc <4 x i32> %abs to <4 x i16>
229   ret <4 x i16> %trunc
232 define <4 x i16> @uabd_4h_promoted_ops(<4 x i8> %a, <4 x i8> %b) #0 {
233 ; CHECK-LABEL: uabd_4h_promoted_ops:
234 ; CHECK:       // %bb.0:
235 ; CHECK-NEXT:    bic v0.4h, #255, lsl #8
236 ; CHECK-NEXT:    bic v1.4h, #255, lsl #8
237 ; CHECK-NEXT:    uabd v0.4h, v0.4h, v1.4h
238 ; CHECK-NEXT:    ret
239   %a.zext = zext <4 x i8> %a to <4 x i16>
240   %b.zext = zext <4 x i8> %b to <4 x i16>
241   %sub = sub <4 x i16> %a.zext, %b.zext
242   %abs = call <4 x i16> @llvm.abs.v4i16(<4 x i16> %sub, i1 true)
243   ret <4 x i16> %abs
246 define <8 x i16> @uabd_8h(<8 x i16> %a, <8 x i16> %b) #0 {
247 ; CHECK-LABEL: uabd_8h:
248 ; CHECK:       // %bb.0:
249 ; CHECK-NEXT:    uabd v0.8h, v0.8h, v1.8h
250 ; CHECK-NEXT:    ret
251   %a.zext = zext <8 x i16> %a to <8 x i32>
252   %b.zext = zext <8 x i16> %b to <8 x i32>
253   %sub = sub <8 x i32> %a.zext, %b.zext
254   %abs = call <8 x i32> @llvm.abs.v8i32(<8 x i32> %sub, i1 true)
255   %trunc = trunc <8 x i32> %abs to <8 x i16>
256   ret <8 x i16> %trunc
259 define <8 x i16> @uabd_8h_promoted_ops(<8 x i8> %a, <8 x i8> %b) #0 {
260 ; CHECK-LABEL: uabd_8h_promoted_ops:
261 ; CHECK:       // %bb.0:
262 ; CHECK-NEXT:    uabdl v0.8h, v0.8b, v1.8b
263 ; CHECK-NEXT:    ret
264   %a.zext = zext <8 x i8> %a to <8 x i16>
265   %b.zext = zext <8 x i8> %b to <8 x i16>
266   %sub = sub <8 x i16> %a.zext, %b.zext
267   %abs = call <8 x i16> @llvm.abs.v8i16(<8 x i16> %sub, i1 true)
268   ret <8 x i16> %abs
271 define <2 x i32> @uabd_2s(<2 x i32> %a, <2 x i32> %b) #0 {
272 ; CHECK-LABEL: uabd_2s:
273 ; CHECK:       // %bb.0:
274 ; CHECK-NEXT:    uabd v0.2s, v0.2s, v1.2s
275 ; CHECK-NEXT:    ret
276   %a.zext = zext <2 x i32> %a to <2 x i64>
277   %b.zext = zext <2 x i32> %b to <2 x i64>
278   %sub = sub <2 x i64> %a.zext, %b.zext
279   %abs = call <2 x i64> @llvm.abs.v2i64(<2 x i64> %sub, i1 true)
280   %trunc = trunc <2 x i64> %abs to <2 x i32>
281   ret <2 x i32> %trunc
284 define <2 x i32> @uabd_2s_promoted_ops(<2 x i16> %a, <2 x i16> %b) #0 {
285 ; CHECK-LABEL: uabd_2s_promoted_ops:
286 ; CHECK:       // %bb.0:
287 ; CHECK-NEXT:    movi d2, #0x00ffff0000ffff
288 ; CHECK-NEXT:    and v0.8b, v0.8b, v2.8b
289 ; CHECK-NEXT:    and v1.8b, v1.8b, v2.8b
290 ; CHECK-NEXT:    uabd v0.2s, v0.2s, v1.2s
291 ; CHECK-NEXT:    ret
292   %a.zext = zext <2 x i16> %a to <2 x i32>
293   %b.zext = zext <2 x i16> %b to <2 x i32>
294   %sub = sub <2 x i32> %a.zext, %b.zext
295   %abs = call <2 x i32> @llvm.abs.v2i32(<2 x i32> %sub, i1 true)
296   ret <2 x i32> %abs
299 define <4 x i32> @uabd_4s(<4 x i32> %a, <4 x i32> %b) #0 {
300 ; CHECK-LABEL: uabd_4s:
301 ; CHECK:       // %bb.0:
302 ; CHECK-NEXT:    uabd v0.4s, v0.4s, v1.4s
303 ; CHECK-NEXT:    ret
304   %a.zext = zext <4 x i32> %a to <4 x i64>
305   %b.zext = zext <4 x i32> %b to <4 x i64>
306   %sub = sub <4 x i64> %a.zext, %b.zext
307   %abs = call <4 x i64> @llvm.abs.v4i64(<4 x i64> %sub, i1 true)
308   %trunc = trunc <4 x i64> %abs to <4 x i32>
309   ret <4 x i32> %trunc
312 define <4 x i32> @uabd_4s_promoted_ops(<4 x i16> %a, <4 x i16> %b) #0 {
313 ; CHECK-LABEL: uabd_4s_promoted_ops:
314 ; CHECK:       // %bb.0:
315 ; CHECK-NEXT:    uabdl v0.4s, v0.4h, v1.4h
316 ; CHECK-NEXT:    ret
317   %a.zext = zext <4 x i16> %a to <4 x i32>
318   %b.zext = zext <4 x i16> %b to <4 x i32>
319   %sub = sub <4 x i32> %a.zext, %b.zext
320   %abs = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %sub, i1 true)
321   ret <4 x i32> %abs
324 define <2 x i64> @uabd_2d(<2 x i64> %a, <2 x i64> %b) #0 {
325 ; CHECK-LABEL: uabd_2d:
326 ; CHECK:       // %bb.0:
327 ; CHECK-NEXT:    mov x8, v0.d[1]
328 ; CHECK-NEXT:    mov x9, v1.d[1]
329 ; CHECK-NEXT:    fmov x10, d0
330 ; CHECK-NEXT:    fmov x11, d1
331 ; CHECK-NEXT:    subs x8, x8, x9
332 ; CHECK-NEXT:    ngc x9, xzr
333 ; CHECK-NEXT:    subs x10, x10, x11
334 ; CHECK-NEXT:    ngc x11, xzr
335 ; CHECK-NEXT:    asr x9, x9, #63
336 ; CHECK-NEXT:    asr x11, x11, #63
337 ; CHECK-NEXT:    eor x8, x8, x9
338 ; CHECK-NEXT:    eor x10, x10, x11
339 ; CHECK-NEXT:    sub x8, x8, x9
340 ; CHECK-NEXT:    sub x10, x10, x11
341 ; CHECK-NEXT:    fmov d1, x8
342 ; CHECK-NEXT:    fmov d0, x10
343 ; CHECK-NEXT:    mov v0.d[1], v1.d[0]
344 ; CHECK-NEXT:    ret
345   %a.zext = zext <2 x i64> %a to <2 x i128>
346   %b.zext = zext <2 x i64> %b to <2 x i128>
347   %sub = sub <2 x i128> %a.zext, %b.zext
348   %abs = call <2 x i128> @llvm.abs.v2i128(<2 x i128> %sub, i1 true)
349   %trunc = trunc <2 x i128> %abs to <2 x i64>
350   ret <2 x i64> %trunc
353 define <2 x i64> @uabd_2d_promoted_ops(<2 x i32> %a, <2 x i32> %b) #0 {
354 ; CHECK-LABEL: uabd_2d_promoted_ops:
355 ; CHECK:       // %bb.0:
356 ; CHECK-NEXT:    uabdl v0.2d, v0.2s, v1.2s
357 ; CHECK-NEXT:    ret
358   %a.zext = zext <2 x i32> %a to <2 x i64>
359   %b.zext = zext <2 x i32> %b to <2 x i64>
360   %sub = sub <2 x i64> %a.zext, %b.zext
361   %abs = call <2 x i64> @llvm.abs.v2i64(<2 x i64> %sub, i1 true)
362   ret <2 x i64> %abs
365 define <16 x i8> @uabd_v16i8_nuw(<16 x i8> %a, <16 x i8> %b) #0 {
366 ; CHECK-LABEL: uabd_v16i8_nuw:
367 ; CHECK:       // %bb.0:
368 ; CHECK-NEXT:    sub v0.16b, v0.16b, v1.16b
369 ; CHECK-NEXT:    abs v0.16b, v0.16b
370 ; CHECK-NEXT:    ret
371   %sub = sub nuw <16 x i8> %a, %b
372   %abs = call <16 x i8> @llvm.abs.v16i8(<16 x i8> %sub, i1 true)
373   ret <16 x i8> %abs
376 define <8 x i16> @uabd_v8i16_nuw(<8 x i16> %a, <8 x i16> %b) #0 {
377 ; CHECK-LABEL: uabd_v8i16_nuw:
378 ; CHECK:       // %bb.0:
379 ; CHECK-NEXT:    sub v0.8h, v0.8h, v1.8h
380 ; CHECK-NEXT:    abs v0.8h, v0.8h
381 ; CHECK-NEXT:    ret
382   %sub = sub nuw <8 x i16> %a, %b
383   %abs = call <8 x i16> @llvm.abs.v8i16(<8 x i16> %sub, i1 true)
384   ret <8 x i16> %abs
387 define <4 x i32> @uabd_v4i32_nuw(<4 x i32> %a, <4 x i32> %b) #0 {
388 ; CHECK-LABEL: uabd_v4i32_nuw:
389 ; CHECK:       // %bb.0:
390 ; CHECK-NEXT:    sub v0.4s, v0.4s, v1.4s
391 ; CHECK-NEXT:    abs v0.4s, v0.4s
392 ; CHECK-NEXT:    ret
393   %sub = sub nuw <4 x i32> %a, %b
394   %abs = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %sub, i1 true)
395   ret <4 x i32> %abs
398 define <2 x i64> @uabd_v2i64_nuw(<2 x i64> %a, <2 x i64> %b) #0 {
399 ; CHECK-LABEL: uabd_v2i64_nuw:
400 ; CHECK:       // %bb.0:
401 ; CHECK-NEXT:    sub v0.2d, v0.2d, v1.2d
402 ; CHECK-NEXT:    abs v0.2d, v0.2d
403 ; CHECK-NEXT:    ret
404   %sub = sub nuw <2 x i64> %a, %b
405   %abs = call <2 x i64> @llvm.abs.v2i64(<2 x i64> %sub, i1 true)
406   ret <2 x i64> %abs
409 define <16 x i8> @sabd_v16i8_nsw(<16 x i8> %a, <16 x i8> %b) #0 {
410 ; CHECK-LABEL: sabd_v16i8_nsw:
411 ; CHECK:       // %bb.0:
412 ; CHECK-NEXT:    sabd v0.16b, v0.16b, v1.16b
413 ; CHECK-NEXT:    ret
414   %sub = sub nsw <16 x i8> %a, %b
415   %abs = call <16 x i8> @llvm.abs.v16i8(<16 x i8> %sub, i1 true)
416   ret <16 x i8> %abs
419 define <8 x i16> @sabd_v8i16_nsw(<8 x i16> %a, <8 x i16> %b) #0 {
420 ; CHECK-LABEL: sabd_v8i16_nsw:
421 ; CHECK:       // %bb.0:
422 ; CHECK-NEXT:    sabd v0.8h, v0.8h, v1.8h
423 ; CHECK-NEXT:    ret
424   %sub = sub nsw <8 x i16> %a, %b
425   %abs = call <8 x i16> @llvm.abs.v8i16(<8 x i16> %sub, i1 true)
426   ret <8 x i16> %abs
429 define <4 x i32> @sabd_v4i32_nsw(<4 x i32> %a, <4 x i32> %b) #0 {
430 ; CHECK-LABEL: sabd_v4i32_nsw:
431 ; CHECK:       // %bb.0:
432 ; CHECK-NEXT:    sabd v0.4s, v0.4s, v1.4s
433 ; CHECK-NEXT:    ret
434   %sub = sub nsw <4 x i32> %a, %b
435   %abs = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %sub, i1 true)
436   ret <4 x i32> %abs
439 define <2 x i64> @sabd_v2i64_nsw(<2 x i64> %a, <2 x i64> %b) #0 {
440 ; CHECK-LABEL: sabd_v2i64_nsw:
441 ; CHECK:       // %bb.0:
442 ; CHECK-NEXT:    sub v0.2d, v0.2d, v1.2d
443 ; CHECK-NEXT:    abs v0.2d, v0.2d
444 ; CHECK-NEXT:    ret
445   %sub = sub nsw <2 x i64> %a, %b
446   %abs = call <2 x i64> @llvm.abs.v2i64(<2 x i64> %sub, i1 true)
447   ret <2 x i64> %abs
450 define <16 x i8> @smaxmin_v16i8(<16 x i8> %0, <16 x i8> %1) {
451 ; CHECK-LABEL: smaxmin_v16i8:
452 ; CHECK:       // %bb.0:
453 ; CHECK-NEXT:    sabd v0.16b, v0.16b, v1.16b
454 ; CHECK-NEXT:    ret
455   %a = tail call <16 x i8> @llvm.smax.v16i8(<16 x i8> %0, <16 x i8> %1)
456   %b = tail call <16 x i8> @llvm.smin.v16i8(<16 x i8> %0, <16 x i8> %1)
457   %sub = sub <16 x i8> %a, %b
458   ret <16 x i8> %sub
461 define <8 x i16> @smaxmin_v8i16(<8 x i16> %0, <8 x i16> %1) {
462 ; CHECK-LABEL: smaxmin_v8i16:
463 ; CHECK:       // %bb.0:
464 ; CHECK-NEXT:    sabd v0.8h, v0.8h, v1.8h
465 ; CHECK-NEXT:    ret
466   %a = tail call <8 x i16> @llvm.smax.v8i16(<8 x i16> %0, <8 x i16> %1)
467   %b = tail call <8 x i16> @llvm.smin.v8i16(<8 x i16> %0, <8 x i16> %1)
468   %sub = sub <8 x i16> %a, %b
469   ret <8 x i16> %sub
472 define <4 x i32> @smaxmin_v4i32(<4 x i32> %0, <4 x i32> %1) {
473 ; CHECK-LABEL: smaxmin_v4i32:
474 ; CHECK:       // %bb.0:
475 ; CHECK-NEXT:    sabd v0.4s, v0.4s, v1.4s
476 ; CHECK-NEXT:    ret
477   %a = tail call <4 x i32> @llvm.smax.v4i32(<4 x i32> %0, <4 x i32> %1)
478   %b = tail call <4 x i32> @llvm.smin.v4i32(<4 x i32> %0, <4 x i32> %1)
479   %sub = sub <4 x i32> %a, %b
480   ret <4 x i32> %sub
483 define <2 x i64> @smaxmin_v2i64(<2 x i64> %0, <2 x i64> %1) {
484 ; CHECK-LABEL: smaxmin_v2i64:
485 ; CHECK:       // %bb.0:
486 ; CHECK-NEXT:    cmgt v2.2d, v0.2d, v1.2d
487 ; CHECK-NEXT:    cmgt v3.2d, v1.2d, v0.2d
488 ; CHECK-NEXT:    bsl v2.16b, v0.16b, v1.16b
489 ; CHECK-NEXT:    bif v0.16b, v1.16b, v3.16b
490 ; CHECK-NEXT:    sub v0.2d, v2.2d, v0.2d
491 ; CHECK-NEXT:    ret
492   %a = tail call <2 x i64> @llvm.smax.v2i64(<2 x i64> %0, <2 x i64> %1)
493   %b = tail call <2 x i64> @llvm.smin.v2i64(<2 x i64> %0, <2 x i64> %1)
494   %sub = sub <2 x i64> %a, %b
495   ret <2 x i64> %sub
498 define <16 x i8> @umaxmin_v16i8(<16 x i8> %0, <16 x i8> %1) {
499 ; CHECK-LABEL: umaxmin_v16i8:
500 ; CHECK:       // %bb.0:
501 ; CHECK-NEXT:    uabd v0.16b, v0.16b, v1.16b
502 ; CHECK-NEXT:    ret
503   %a = tail call <16 x i8> @llvm.umax.v16i8(<16 x i8> %0, <16 x i8> %1)
504   %b = tail call <16 x i8> @llvm.umin.v16i8(<16 x i8> %0, <16 x i8> %1)
505   %sub = sub <16 x i8> %a, %b
506   ret <16 x i8> %sub
509 define <8 x i16> @umaxmin_v8i16(<8 x i16> %0, <8 x i16> %1) {
510 ; CHECK-LABEL: umaxmin_v8i16:
511 ; CHECK:       // %bb.0:
512 ; CHECK-NEXT:    uabd v0.8h, v0.8h, v1.8h
513 ; CHECK-NEXT:    ret
514   %a = tail call <8 x i16> @llvm.umax.v8i16(<8 x i16> %0, <8 x i16> %1)
515   %b = tail call <8 x i16> @llvm.umin.v8i16(<8 x i16> %0, <8 x i16> %1)
516   %sub = sub <8 x i16> %a, %b
517   ret <8 x i16> %sub
520 define <4 x i32> @umaxmin_v4i32(<4 x i32> %0, <4 x i32> %1) {
521 ; CHECK-LABEL: umaxmin_v4i32:
522 ; CHECK:       // %bb.0:
523 ; CHECK-NEXT:    uabd v0.4s, v0.4s, v1.4s
524 ; CHECK-NEXT:    ret
525   %a = tail call <4 x i32> @llvm.umax.v4i32(<4 x i32> %0, <4 x i32> %1)
526   %b = tail call <4 x i32> @llvm.umin.v4i32(<4 x i32> %0, <4 x i32> %1)
527   %sub = sub <4 x i32> %a, %b
528   ret <4 x i32> %sub
531 define <2 x i64> @umaxmin_v2i64(<2 x i64> %0, <2 x i64> %1) {
532 ; CHECK-LABEL: umaxmin_v2i64:
533 ; CHECK:       // %bb.0:
534 ; CHECK-NEXT:    cmhi v2.2d, v0.2d, v1.2d
535 ; CHECK-NEXT:    cmhi v3.2d, v1.2d, v0.2d
536 ; CHECK-NEXT:    bsl v2.16b, v0.16b, v1.16b
537 ; CHECK-NEXT:    bif v0.16b, v1.16b, v3.16b
538 ; CHECK-NEXT:    sub v0.2d, v2.2d, v0.2d
539 ; CHECK-NEXT:    ret
540   %a = tail call <2 x i64> @llvm.umax.v2i64(<2 x i64> %0, <2 x i64> %1)
541   %b = tail call <2 x i64> @llvm.umin.v2i64(<2 x i64> %0, <2 x i64> %1)
542   %sub = sub <2 x i64> %a, %b
543   ret <2 x i64> %sub
546 define <16 x i8> @umaxmin_v16i8_com1(<16 x i8> %0, <16 x i8> %1) {
547 ; CHECK-LABEL: umaxmin_v16i8_com1:
548 ; CHECK:       // %bb.0:
549 ; CHECK-NEXT:    uabd v0.16b, v0.16b, v1.16b
550 ; CHECK-NEXT:    ret
551   %a = tail call <16 x i8> @llvm.umax.v16i8(<16 x i8> %0, <16 x i8> %1)
552   %b = tail call <16 x i8> @llvm.umin.v16i8(<16 x i8> %1, <16 x i8> %0)
553   %sub = sub <16 x i8> %a, %b
554   ret <16 x i8> %sub
557 declare <8 x i8> @llvm.abs.v8i8(<8 x i8>, i1)
558 declare <16 x i8> @llvm.abs.v16i8(<16 x i8>, i1)
560 declare <4 x i16> @llvm.abs.v4i16(<4 x i16>, i1)
561 declare <8 x i16> @llvm.abs.v8i16(<8 x i16>, i1)
562 declare <16 x i16> @llvm.abs.v16i16(<16 x i16>, i1)
564 declare <2 x i32> @llvm.abs.v2i32(<2 x i32>, i1)
565 declare <4 x i32> @llvm.abs.v4i32(<4 x i32>, i1)
566 declare <8 x i32> @llvm.abs.v8i32(<8 x i32>, i1)
568 declare <2 x i64> @llvm.abs.v2i64(<2 x i64>, i1)
569 declare <4 x i64> @llvm.abs.v4i64(<4 x i64>, i1)
571 declare <2 x i128> @llvm.abs.v2i128(<2 x i128>, i1)
573 declare <16 x i8> @llvm.smax.v16i8(<16 x i8>, <16 x i8>)
574 declare <8 x i16> @llvm.smax.v8i16(<8 x i16>, <8 x i16>)
575 declare <4 x i32> @llvm.smax.v4i32(<4 x i32>, <4 x i32>)
576 declare <2 x i64> @llvm.smax.v2i64(<2 x i64>, <2 x i64>)
577 declare <16 x i8> @llvm.smin.v16i8(<16 x i8>, <16 x i8>)
578 declare <8 x i16> @llvm.smin.v8i16(<8 x i16>, <8 x i16>)
579 declare <4 x i32> @llvm.smin.v4i32(<4 x i32>, <4 x i32>)
580 declare <2 x i64> @llvm.smin.v2i64(<2 x i64>, <2 x i64>)
581 declare <16 x i8> @llvm.umax.v16i8(<16 x i8>, <16 x i8>)
582 declare <8 x i16> @llvm.umax.v8i16(<8 x i16>, <8 x i16>)
583 declare <4 x i32> @llvm.umax.v4i32(<4 x i32>, <4 x i32>)
584 declare <2 x i64> @llvm.umax.v2i64(<2 x i64>, <2 x i64>)
585 declare <16 x i8> @llvm.umin.v16i8(<16 x i8>, <16 x i8>)
586 declare <8 x i16> @llvm.umin.v8i16(<8 x i16>, <8 x i16>)
587 declare <4 x i32> @llvm.umin.v4i32(<4 x i32>, <4 x i32>)
588 declare <2 x i64> @llvm.umin.v2i64(<2 x i64>, <2 x i64>)
590 attributes #0 = { "target-features"="+neon" }