Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / AArch64 / sve-streaming-mode-fixed-length-int-minmax.ll
blobd7600c6e6192d92606d445d5c80a8920bb9215c8
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mattr=+sve -force-streaming-compatible-sve  < %s | FileCheck %s
3 ; RUN: llc -mattr=+sme -force-streaming-compatible-sve  < %s | FileCheck %s
5 target triple = "aarch64-unknown-linux-gnu"
8 ; SMAX
11 define <8 x i8> @smax_v8i8(<8 x i8> %op1, <8 x i8> %op2) {
12 ; CHECK-LABEL: smax_v8i8:
13 ; CHECK:       // %bb.0:
14 ; CHECK-NEXT:    ptrue p0.b, vl8
15 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
16 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
17 ; CHECK-NEXT:    smax z0.b, p0/m, z0.b, z1.b
18 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
19 ; CHECK-NEXT:    ret
20   %res = call <8 x i8> @llvm.smax.v8i8(<8 x i8> %op1, <8 x i8> %op2)
21   ret <8 x i8> %res
24 define <16 x i8> @smax_v16i8(<16 x i8> %op1, <16 x i8> %op2) {
25 ; CHECK-LABEL: smax_v16i8:
26 ; CHECK:       // %bb.0:
27 ; CHECK-NEXT:    ptrue p0.b, vl16
28 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
29 ; CHECK-NEXT:    // kill: def $q1 killed $q1 def $z1
30 ; CHECK-NEXT:    smax z0.b, p0/m, z0.b, z1.b
31 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
32 ; CHECK-NEXT:    ret
33   %res = call <16 x i8> @llvm.smax.v16i8(<16 x i8> %op1, <16 x i8> %op2)
34   ret <16 x i8> %res
37 define void @smax_v32i8(ptr %a, ptr %b) {
38 ; CHECK-LABEL: smax_v32i8:
39 ; CHECK:       // %bb.0:
40 ; CHECK-NEXT:    ptrue p0.b, vl16
41 ; CHECK-NEXT:    ldp q0, q3, [x1]
42 ; CHECK-NEXT:    ldp q1, q2, [x0]
43 ; CHECK-NEXT:    smax z0.b, p0/m, z0.b, z1.b
44 ; CHECK-NEXT:    movprfx z1, z2
45 ; CHECK-NEXT:    smax z1.b, p0/m, z1.b, z3.b
46 ; CHECK-NEXT:    stp q0, q1, [x0]
47 ; CHECK-NEXT:    ret
48   %op1 = load <32 x i8>, ptr %a
49   %op2 = load <32 x i8>, ptr %b
50   %res = call <32 x i8> @llvm.smax.v32i8(<32 x i8> %op1, <32 x i8> %op2)
51   store <32 x i8> %res, ptr %a
52   ret void
55 define <4 x i16> @smax_v4i16(<4 x i16> %op1, <4 x i16> %op2) {
56 ; CHECK-LABEL: smax_v4i16:
57 ; CHECK:       // %bb.0:
58 ; CHECK-NEXT:    ptrue p0.h, vl4
59 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
60 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
61 ; CHECK-NEXT:    smax z0.h, p0/m, z0.h, z1.h
62 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
63 ; CHECK-NEXT:    ret
64   %res = call <4 x i16> @llvm.smax.v4i16(<4 x i16> %op1, <4 x i16> %op2)
65   ret <4 x i16> %res
68 define <8 x i16> @smax_v8i16(<8 x i16> %op1, <8 x i16> %op2) {
69 ; CHECK-LABEL: smax_v8i16:
70 ; CHECK:       // %bb.0:
71 ; CHECK-NEXT:    ptrue p0.h, vl8
72 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
73 ; CHECK-NEXT:    // kill: def $q1 killed $q1 def $z1
74 ; CHECK-NEXT:    smax z0.h, p0/m, z0.h, z1.h
75 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
76 ; CHECK-NEXT:    ret
77   %res = call <8 x i16> @llvm.smax.v8i16(<8 x i16> %op1, <8 x i16> %op2)
78   ret <8 x i16> %res
81 define void @smax_v16i16(ptr %a, ptr %b) {
82 ; CHECK-LABEL: smax_v16i16:
83 ; CHECK:       // %bb.0:
84 ; CHECK-NEXT:    ptrue p0.h, vl8
85 ; CHECK-NEXT:    ldp q0, q3, [x1]
86 ; CHECK-NEXT:    ldp q1, q2, [x0]
87 ; CHECK-NEXT:    smax z0.h, p0/m, z0.h, z1.h
88 ; CHECK-NEXT:    movprfx z1, z2
89 ; CHECK-NEXT:    smax z1.h, p0/m, z1.h, z3.h
90 ; CHECK-NEXT:    stp q0, q1, [x0]
91 ; CHECK-NEXT:    ret
92   %op1 = load <16 x i16>, ptr %a
93   %op2 = load <16 x i16>, ptr %b
94   %res = call <16 x i16> @llvm.smax.v16i16(<16 x i16> %op1, <16 x i16> %op2)
95   store <16 x i16> %res, ptr %a
96   ret void
99 define <2 x i32> @smax_v2i32(<2 x i32> %op1, <2 x i32> %op2) {
100 ; CHECK-LABEL: smax_v2i32:
101 ; CHECK:       // %bb.0:
102 ; CHECK-NEXT:    ptrue p0.s, vl2
103 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
104 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
105 ; CHECK-NEXT:    smax z0.s, p0/m, z0.s, z1.s
106 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
107 ; CHECK-NEXT:    ret
108   %res = call <2 x i32> @llvm.smax.v2i32(<2 x i32> %op1, <2 x i32> %op2)
109   ret <2 x i32> %res
112 define <4 x i32> @smax_v4i32(<4 x i32> %op1, <4 x i32> %op2) {
113 ; CHECK-LABEL: smax_v4i32:
114 ; CHECK:       // %bb.0:
115 ; CHECK-NEXT:    ptrue p0.s, vl4
116 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
117 ; CHECK-NEXT:    // kill: def $q1 killed $q1 def $z1
118 ; CHECK-NEXT:    smax z0.s, p0/m, z0.s, z1.s
119 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
120 ; CHECK-NEXT:    ret
121   %res = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %op1, <4 x i32> %op2)
122   ret <4 x i32> %res
125 define void @smax_v8i32(ptr %a, ptr %b) {
126 ; CHECK-LABEL: smax_v8i32:
127 ; CHECK:       // %bb.0:
128 ; CHECK-NEXT:    ptrue p0.s, vl4
129 ; CHECK-NEXT:    ldp q0, q3, [x1]
130 ; CHECK-NEXT:    ldp q1, q2, [x0]
131 ; CHECK-NEXT:    smax z0.s, p0/m, z0.s, z1.s
132 ; CHECK-NEXT:    movprfx z1, z2
133 ; CHECK-NEXT:    smax z1.s, p0/m, z1.s, z3.s
134 ; CHECK-NEXT:    stp q0, q1, [x0]
135 ; CHECK-NEXT:    ret
136   %op1 = load <8 x i32>, ptr %a
137   %op2 = load <8 x i32>, ptr %b
138   %res = call <8 x i32> @llvm.smax.v8i32(<8 x i32> %op1, <8 x i32> %op2)
139   store <8 x i32> %res, ptr %a
140   ret void
143 ; Vector i64 max are not legal for NEON so use SVE when available.
144 define <1 x i64> @smax_v1i64(<1 x i64> %op1, <1 x i64> %op2) {
145 ; CHECK-LABEL: smax_v1i64:
146 ; CHECK:       // %bb.0:
147 ; CHECK-NEXT:    ptrue p0.d, vl1
148 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
149 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
150 ; CHECK-NEXT:    smax z0.d, p0/m, z0.d, z1.d
151 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
152 ; CHECK-NEXT:    ret
153   %res = call <1 x i64> @llvm.smax.v1i64(<1 x i64> %op1, <1 x i64> %op2)
154   ret <1 x i64> %res
157 ; Vector i64 max are not legal for NEON so use SVE when available.
158 define <2 x i64> @smax_v2i64(<2 x i64> %op1, <2 x i64> %op2) {
159 ; CHECK-LABEL: smax_v2i64:
160 ; CHECK:       // %bb.0:
161 ; CHECK-NEXT:    ptrue p0.d, vl2
162 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
163 ; CHECK-NEXT:    // kill: def $q1 killed $q1 def $z1
164 ; CHECK-NEXT:    smax z0.d, p0/m, z0.d, z1.d
165 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
166 ; CHECK-NEXT:    ret
167   %res = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %op1, <2 x i64> %op2)
168   ret <2 x i64> %res
171 define void @smax_v4i64(ptr %a, ptr %b) {
172 ; CHECK-LABEL: smax_v4i64:
173 ; CHECK:       // %bb.0:
174 ; CHECK-NEXT:    ptrue p0.d, vl2
175 ; CHECK-NEXT:    ldp q0, q3, [x1]
176 ; CHECK-NEXT:    ldp q1, q2, [x0]
177 ; CHECK-NEXT:    smax z0.d, p0/m, z0.d, z1.d
178 ; CHECK-NEXT:    movprfx z1, z2
179 ; CHECK-NEXT:    smax z1.d, p0/m, z1.d, z3.d
180 ; CHECK-NEXT:    stp q0, q1, [x0]
181 ; CHECK-NEXT:    ret
182   %op1 = load <4 x i64>, ptr %a
183   %op2 = load <4 x i64>, ptr %b
184   %res = call <4 x i64> @llvm.smax.v4i64(<4 x i64> %op1, <4 x i64> %op2)
185   store <4 x i64> %res, ptr %a
186   ret void
190 ; SMIN
193 define <8 x i8> @smin_v8i8(<8 x i8> %op1, <8 x i8> %op2) {
194 ; CHECK-LABEL: smin_v8i8:
195 ; CHECK:       // %bb.0:
196 ; CHECK-NEXT:    ptrue p0.b, vl8
197 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
198 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
199 ; CHECK-NEXT:    smin z0.b, p0/m, z0.b, z1.b
200 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
201 ; CHECK-NEXT:    ret
202   %res = call <8 x i8> @llvm.smin.v8i8(<8 x i8> %op1, <8 x i8> %op2)
203   ret <8 x i8> %res
206 define <16 x i8> @smin_v16i8(<16 x i8> %op1, <16 x i8> %op2) {
207 ; CHECK-LABEL: smin_v16i8:
208 ; CHECK:       // %bb.0:
209 ; CHECK-NEXT:    ptrue p0.b, vl16
210 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
211 ; CHECK-NEXT:    // kill: def $q1 killed $q1 def $z1
212 ; CHECK-NEXT:    smin z0.b, p0/m, z0.b, z1.b
213 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
214 ; CHECK-NEXT:    ret
215   %res = call <16 x i8> @llvm.smin.v16i8(<16 x i8> %op1, <16 x i8> %op2)
216   ret <16 x i8> %res
219 define void @smin_v32i8(ptr %a, ptr %b) {
220 ; CHECK-LABEL: smin_v32i8:
221 ; CHECK:       // %bb.0:
222 ; CHECK-NEXT:    ptrue p0.b, vl16
223 ; CHECK-NEXT:    ldp q0, q3, [x1]
224 ; CHECK-NEXT:    ldp q1, q2, [x0]
225 ; CHECK-NEXT:    smin z0.b, p0/m, z0.b, z1.b
226 ; CHECK-NEXT:    movprfx z1, z2
227 ; CHECK-NEXT:    smin z1.b, p0/m, z1.b, z3.b
228 ; CHECK-NEXT:    stp q0, q1, [x0]
229 ; CHECK-NEXT:    ret
230   %op1 = load <32 x i8>, ptr %a
231   %op2 = load <32 x i8>, ptr %b
232   %res = call <32 x i8> @llvm.smin.v32i8(<32 x i8> %op1, <32 x i8> %op2)
233   store <32 x i8> %res, ptr %a
234   ret void
237 define <4 x i16> @smin_v4i16(<4 x i16> %op1, <4 x i16> %op2) {
238 ; CHECK-LABEL: smin_v4i16:
239 ; CHECK:       // %bb.0:
240 ; CHECK-NEXT:    ptrue p0.h, vl4
241 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
242 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
243 ; CHECK-NEXT:    smin z0.h, p0/m, z0.h, z1.h
244 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
245 ; CHECK-NEXT:    ret
246   %res = call <4 x i16> @llvm.smin.v4i16(<4 x i16> %op1, <4 x i16> %op2)
247   ret <4 x i16> %res
250 define <8 x i16> @smin_v8i16(<8 x i16> %op1, <8 x i16> %op2) {
251 ; CHECK-LABEL: smin_v8i16:
252 ; CHECK:       // %bb.0:
253 ; CHECK-NEXT:    ptrue p0.h, vl8
254 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
255 ; CHECK-NEXT:    // kill: def $q1 killed $q1 def $z1
256 ; CHECK-NEXT:    smin z0.h, p0/m, z0.h, z1.h
257 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
258 ; CHECK-NEXT:    ret
259   %res = call <8 x i16> @llvm.smin.v8i16(<8 x i16> %op1, <8 x i16> %op2)
260   ret <8 x i16> %res
263 define void @smin_v16i16(ptr %a, ptr %b) {
264 ; CHECK-LABEL: smin_v16i16:
265 ; CHECK:       // %bb.0:
266 ; CHECK-NEXT:    ptrue p0.h, vl8
267 ; CHECK-NEXT:    ldp q0, q3, [x1]
268 ; CHECK-NEXT:    ldp q1, q2, [x0]
269 ; CHECK-NEXT:    smin z0.h, p0/m, z0.h, z1.h
270 ; CHECK-NEXT:    movprfx z1, z2
271 ; CHECK-NEXT:    smin z1.h, p0/m, z1.h, z3.h
272 ; CHECK-NEXT:    stp q0, q1, [x0]
273 ; CHECK-NEXT:    ret
274   %op1 = load <16 x i16>, ptr %a
275   %op2 = load <16 x i16>, ptr %b
276   %res = call <16 x i16> @llvm.smin.v16i16(<16 x i16> %op1, <16 x i16> %op2)
277   store <16 x i16> %res, ptr %a
278   ret void
281 define <2 x i32> @smin_v2i32(<2 x i32> %op1, <2 x i32> %op2) {
282 ; CHECK-LABEL: smin_v2i32:
283 ; CHECK:       // %bb.0:
284 ; CHECK-NEXT:    ptrue p0.s, vl2
285 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
286 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
287 ; CHECK-NEXT:    smin z0.s, p0/m, z0.s, z1.s
288 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
289 ; CHECK-NEXT:    ret
290   %res = call <2 x i32> @llvm.smin.v2i32(<2 x i32> %op1, <2 x i32> %op2)
291   ret <2 x i32> %res
294 define <4 x i32> @smin_v4i32(<4 x i32> %op1, <4 x i32> %op2) {
295 ; CHECK-LABEL: smin_v4i32:
296 ; CHECK:       // %bb.0:
297 ; CHECK-NEXT:    ptrue p0.s, vl4
298 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
299 ; CHECK-NEXT:    // kill: def $q1 killed $q1 def $z1
300 ; CHECK-NEXT:    smin z0.s, p0/m, z0.s, z1.s
301 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
302 ; CHECK-NEXT:    ret
303   %res = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %op1, <4 x i32> %op2)
304   ret <4 x i32> %res
307 define void @smin_v8i32(ptr %a, ptr %b) {
308 ; CHECK-LABEL: smin_v8i32:
309 ; CHECK:       // %bb.0:
310 ; CHECK-NEXT:    ptrue p0.s, vl4
311 ; CHECK-NEXT:    ldp q0, q3, [x1]
312 ; CHECK-NEXT:    ldp q1, q2, [x0]
313 ; CHECK-NEXT:    smin z0.s, p0/m, z0.s, z1.s
314 ; CHECK-NEXT:    movprfx z1, z2
315 ; CHECK-NEXT:    smin z1.s, p0/m, z1.s, z3.s
316 ; CHECK-NEXT:    stp q0, q1, [x0]
317 ; CHECK-NEXT:    ret
318   %op1 = load <8 x i32>, ptr %a
319   %op2 = load <8 x i32>, ptr %b
320   %res = call <8 x i32> @llvm.smin.v8i32(<8 x i32> %op1, <8 x i32> %op2)
321   store <8 x i32> %res, ptr %a
322   ret void
325 ; Vector i64 min are not legal for NEON so use SVE when available.
326 define <1 x i64> @smin_v1i64(<1 x i64> %op1, <1 x i64> %op2) {
327 ; CHECK-LABEL: smin_v1i64:
328 ; CHECK:       // %bb.0:
329 ; CHECK-NEXT:    ptrue p0.d, vl1
330 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
331 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
332 ; CHECK-NEXT:    smin z0.d, p0/m, z0.d, z1.d
333 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
334 ; CHECK-NEXT:    ret
335   %res = call <1 x i64> @llvm.smin.v1i64(<1 x i64> %op1, <1 x i64> %op2)
336   ret <1 x i64> %res
339 ; Vector i64 min are not legal for NEON so use SVE when available.
340 define <2 x i64> @smin_v2i64(<2 x i64> %op1, <2 x i64> %op2) {
341 ; CHECK-LABEL: smin_v2i64:
342 ; CHECK:       // %bb.0:
343 ; CHECK-NEXT:    ptrue p0.d, vl2
344 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
345 ; CHECK-NEXT:    // kill: def $q1 killed $q1 def $z1
346 ; CHECK-NEXT:    smin z0.d, p0/m, z0.d, z1.d
347 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
348 ; CHECK-NEXT:    ret
349   %res = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %op1, <2 x i64> %op2)
350   ret <2 x i64> %res
353 define void @smin_v4i64(ptr %a, ptr %b) {
354 ; CHECK-LABEL: smin_v4i64:
355 ; CHECK:       // %bb.0:
356 ; CHECK-NEXT:    ptrue p0.d, vl2
357 ; CHECK-NEXT:    ldp q0, q3, [x1]
358 ; CHECK-NEXT:    ldp q1, q2, [x0]
359 ; CHECK-NEXT:    smin z0.d, p0/m, z0.d, z1.d
360 ; CHECK-NEXT:    movprfx z1, z2
361 ; CHECK-NEXT:    smin z1.d, p0/m, z1.d, z3.d
362 ; CHECK-NEXT:    stp q0, q1, [x0]
363 ; CHECK-NEXT:    ret
364   %op1 = load <4 x i64>, ptr %a
365   %op2 = load <4 x i64>, ptr %b
366   %res = call <4 x i64> @llvm.smin.v4i64(<4 x i64> %op1, <4 x i64> %op2)
367   store <4 x i64> %res, ptr %a
368   ret void
372 ; UMAX
375 define <8 x i8> @umax_v8i8(<8 x i8> %op1, <8 x i8> %op2) {
376 ; CHECK-LABEL: umax_v8i8:
377 ; CHECK:       // %bb.0:
378 ; CHECK-NEXT:    ptrue p0.b, vl8
379 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
380 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
381 ; CHECK-NEXT:    umax z0.b, p0/m, z0.b, z1.b
382 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
383 ; CHECK-NEXT:    ret
384   %res = call <8 x i8> @llvm.umax.v8i8(<8 x i8> %op1, <8 x i8> %op2)
385   ret <8 x i8> %res
388 define <16 x i8> @umax_v16i8(<16 x i8> %op1, <16 x i8> %op2) {
389 ; CHECK-LABEL: umax_v16i8:
390 ; CHECK:       // %bb.0:
391 ; CHECK-NEXT:    ptrue p0.b, vl16
392 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
393 ; CHECK-NEXT:    // kill: def $q1 killed $q1 def $z1
394 ; CHECK-NEXT:    umax z0.b, p0/m, z0.b, z1.b
395 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
396 ; CHECK-NEXT:    ret
397   %res = call <16 x i8> @llvm.umax.v16i8(<16 x i8> %op1, <16 x i8> %op2)
398   ret <16 x i8> %res
401 define void @umax_v32i8(ptr %a, ptr %b) {
402 ; CHECK-LABEL: umax_v32i8:
403 ; CHECK:       // %bb.0:
404 ; CHECK-NEXT:    ptrue p0.b, vl16
405 ; CHECK-NEXT:    ldp q0, q3, [x1]
406 ; CHECK-NEXT:    ldp q1, q2, [x0]
407 ; CHECK-NEXT:    umax z0.b, p0/m, z0.b, z1.b
408 ; CHECK-NEXT:    movprfx z1, z2
409 ; CHECK-NEXT:    umax z1.b, p0/m, z1.b, z3.b
410 ; CHECK-NEXT:    stp q0, q1, [x0]
411 ; CHECK-NEXT:    ret
412   %op1 = load <32 x i8>, ptr %a
413   %op2 = load <32 x i8>, ptr %b
414   %res = call <32 x i8> @llvm.umax.v32i8(<32 x i8> %op1, <32 x i8> %op2)
415   store <32 x i8> %res, ptr %a
416   ret void
419 define <4 x i16> @umax_v4i16(<4 x i16> %op1, <4 x i16> %op2) {
420 ; CHECK-LABEL: umax_v4i16:
421 ; CHECK:       // %bb.0:
422 ; CHECK-NEXT:    ptrue p0.h, vl4
423 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
424 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
425 ; CHECK-NEXT:    umax z0.h, p0/m, z0.h, z1.h
426 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
427 ; CHECK-NEXT:    ret
428   %res = call <4 x i16> @llvm.umax.v4i16(<4 x i16> %op1, <4 x i16> %op2)
429   ret <4 x i16> %res
432 define <8 x i16> @umax_v8i16(<8 x i16> %op1, <8 x i16> %op2) {
433 ; CHECK-LABEL: umax_v8i16:
434 ; CHECK:       // %bb.0:
435 ; CHECK-NEXT:    ptrue p0.h, vl8
436 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
437 ; CHECK-NEXT:    // kill: def $q1 killed $q1 def $z1
438 ; CHECK-NEXT:    umax z0.h, p0/m, z0.h, z1.h
439 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
440 ; CHECK-NEXT:    ret
441   %res = call <8 x i16> @llvm.umax.v8i16(<8 x i16> %op1, <8 x i16> %op2)
442   ret <8 x i16> %res
445 define void @umax_v16i16(ptr %a, ptr %b) {
446 ; CHECK-LABEL: umax_v16i16:
447 ; CHECK:       // %bb.0:
448 ; CHECK-NEXT:    ptrue p0.h, vl8
449 ; CHECK-NEXT:    ldp q0, q3, [x1]
450 ; CHECK-NEXT:    ldp q1, q2, [x0]
451 ; CHECK-NEXT:    umax z0.h, p0/m, z0.h, z1.h
452 ; CHECK-NEXT:    movprfx z1, z2
453 ; CHECK-NEXT:    umax z1.h, p0/m, z1.h, z3.h
454 ; CHECK-NEXT:    stp q0, q1, [x0]
455 ; CHECK-NEXT:    ret
456   %op1 = load <16 x i16>, ptr %a
457   %op2 = load <16 x i16>, ptr %b
458   %res = call <16 x i16> @llvm.umax.v16i16(<16 x i16> %op1, <16 x i16> %op2)
459   store <16 x i16> %res, ptr %a
460   ret void
463 define <2 x i32> @umax_v2i32(<2 x i32> %op1, <2 x i32> %op2) {
464 ; CHECK-LABEL: umax_v2i32:
465 ; CHECK:       // %bb.0:
466 ; CHECK-NEXT:    ptrue p0.s, vl2
467 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
468 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
469 ; CHECK-NEXT:    umax z0.s, p0/m, z0.s, z1.s
470 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
471 ; CHECK-NEXT:    ret
472   %res = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %op1, <2 x i32> %op2)
473   ret <2 x i32> %res
476 define <4 x i32> @umax_v4i32(<4 x i32> %op1, <4 x i32> %op2) {
477 ; CHECK-LABEL: umax_v4i32:
478 ; CHECK:       // %bb.0:
479 ; CHECK-NEXT:    ptrue p0.s, vl4
480 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
481 ; CHECK-NEXT:    // kill: def $q1 killed $q1 def $z1
482 ; CHECK-NEXT:    umax z0.s, p0/m, z0.s, z1.s
483 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
484 ; CHECK-NEXT:    ret
485   %res = call <4 x i32> @llvm.umax.v4i32(<4 x i32> %op1, <4 x i32> %op2)
486   ret <4 x i32> %res
489 define void @umax_v8i32(ptr %a, ptr %b) {
490 ; CHECK-LABEL: umax_v8i32:
491 ; CHECK:       // %bb.0:
492 ; CHECK-NEXT:    ptrue p0.s, vl4
493 ; CHECK-NEXT:    ldp q0, q3, [x1]
494 ; CHECK-NEXT:    ldp q1, q2, [x0]
495 ; CHECK-NEXT:    umax z0.s, p0/m, z0.s, z1.s
496 ; CHECK-NEXT:    movprfx z1, z2
497 ; CHECK-NEXT:    umax z1.s, p0/m, z1.s, z3.s
498 ; CHECK-NEXT:    stp q0, q1, [x0]
499 ; CHECK-NEXT:    ret
500   %op1 = load <8 x i32>, ptr %a
501   %op2 = load <8 x i32>, ptr %b
502   %res = call <8 x i32> @llvm.umax.v8i32(<8 x i32> %op1, <8 x i32> %op2)
503   store <8 x i32> %res, ptr %a
504   ret void
507 ; Vector i64 max are not legal for NEON so use SVE when available.
508 define <1 x i64> @umax_v1i64(<1 x i64> %op1, <1 x i64> %op2) {
509 ; CHECK-LABEL: umax_v1i64:
510 ; CHECK:       // %bb.0:
511 ; CHECK-NEXT:    ptrue p0.d, vl1
512 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
513 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
514 ; CHECK-NEXT:    umax z0.d, p0/m, z0.d, z1.d
515 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
516 ; CHECK-NEXT:    ret
517   %res = call <1 x i64> @llvm.umax.v1i64(<1 x i64> %op1, <1 x i64> %op2)
518   ret <1 x i64> %res
521 ; Vector i64 max are not legal for NEON so use SVE when available.
522 define <2 x i64> @umax_v2i64(<2 x i64> %op1, <2 x i64> %op2) {
523 ; CHECK-LABEL: umax_v2i64:
524 ; CHECK:       // %bb.0:
525 ; CHECK-NEXT:    ptrue p0.d, vl2
526 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
527 ; CHECK-NEXT:    // kill: def $q1 killed $q1 def $z1
528 ; CHECK-NEXT:    umax z0.d, p0/m, z0.d, z1.d
529 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
530 ; CHECK-NEXT:    ret
531   %res = call <2 x i64> @llvm.umax.v2i64(<2 x i64> %op1, <2 x i64> %op2)
532   ret <2 x i64> %res
535 define void @umax_v4i64(ptr %a, ptr %b) {
536 ; CHECK-LABEL: umax_v4i64:
537 ; CHECK:       // %bb.0:
538 ; CHECK-NEXT:    ptrue p0.d, vl2
539 ; CHECK-NEXT:    ldp q0, q3, [x1]
540 ; CHECK-NEXT:    ldp q1, q2, [x0]
541 ; CHECK-NEXT:    umax z0.d, p0/m, z0.d, z1.d
542 ; CHECK-NEXT:    movprfx z1, z2
543 ; CHECK-NEXT:    umax z1.d, p0/m, z1.d, z3.d
544 ; CHECK-NEXT:    stp q0, q1, [x0]
545 ; CHECK-NEXT:    ret
546   %op1 = load <4 x i64>, ptr %a
547   %op2 = load <4 x i64>, ptr %b
548   %res = call <4 x i64> @llvm.umax.v4i64(<4 x i64> %op1, <4 x i64> %op2)
549   store <4 x i64> %res, ptr %a
550   ret void
554 ; UMIN
557 define <8 x i8> @umin_v8i8(<8 x i8> %op1, <8 x i8> %op2) {
558 ; CHECK-LABEL: umin_v8i8:
559 ; CHECK:       // %bb.0:
560 ; CHECK-NEXT:    ptrue p0.b, vl8
561 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
562 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
563 ; CHECK-NEXT:    umin z0.b, p0/m, z0.b, z1.b
564 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
565 ; CHECK-NEXT:    ret
566   %res = call <8 x i8> @llvm.umin.v8i8(<8 x i8> %op1, <8 x i8> %op2)
567   ret <8 x i8> %res
570 define <16 x i8> @umin_v16i8(<16 x i8> %op1, <16 x i8> %op2) {
571 ; CHECK-LABEL: umin_v16i8:
572 ; CHECK:       // %bb.0:
573 ; CHECK-NEXT:    ptrue p0.b, vl16
574 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
575 ; CHECK-NEXT:    // kill: def $q1 killed $q1 def $z1
576 ; CHECK-NEXT:    umin z0.b, p0/m, z0.b, z1.b
577 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
578 ; CHECK-NEXT:    ret
579   %res = call <16 x i8> @llvm.umin.v16i8(<16 x i8> %op1, <16 x i8> %op2)
580   ret <16 x i8> %res
583 define void @umin_v32i8(ptr %a, ptr %b) {
584 ; CHECK-LABEL: umin_v32i8:
585 ; CHECK:       // %bb.0:
586 ; CHECK-NEXT:    ptrue p0.b, vl16
587 ; CHECK-NEXT:    ldp q0, q3, [x1]
588 ; CHECK-NEXT:    ldp q1, q2, [x0]
589 ; CHECK-NEXT:    umin z0.b, p0/m, z0.b, z1.b
590 ; CHECK-NEXT:    movprfx z1, z2
591 ; CHECK-NEXT:    umin z1.b, p0/m, z1.b, z3.b
592 ; CHECK-NEXT:    stp q0, q1, [x0]
593 ; CHECK-NEXT:    ret
594   %op1 = load <32 x i8>, ptr %a
595   %op2 = load <32 x i8>, ptr %b
596   %res = call <32 x i8> @llvm.umin.v32i8(<32 x i8> %op1, <32 x i8> %op2)
597   store <32 x i8> %res, ptr %a
598   ret void
601 define <4 x i16> @umin_v4i16(<4 x i16> %op1, <4 x i16> %op2) {
602 ; CHECK-LABEL: umin_v4i16:
603 ; CHECK:       // %bb.0:
604 ; CHECK-NEXT:    ptrue p0.h, vl4
605 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
606 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
607 ; CHECK-NEXT:    umin z0.h, p0/m, z0.h, z1.h
608 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
609 ; CHECK-NEXT:    ret
610   %res = call <4 x i16> @llvm.umin.v4i16(<4 x i16> %op1, <4 x i16> %op2)
611   ret <4 x i16> %res
614 define <8 x i16> @umin_v8i16(<8 x i16> %op1, <8 x i16> %op2) {
615 ; CHECK-LABEL: umin_v8i16:
616 ; CHECK:       // %bb.0:
617 ; CHECK-NEXT:    ptrue p0.h, vl8
618 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
619 ; CHECK-NEXT:    // kill: def $q1 killed $q1 def $z1
620 ; CHECK-NEXT:    umin z0.h, p0/m, z0.h, z1.h
621 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
622 ; CHECK-NEXT:    ret
623   %res = call <8 x i16> @llvm.umin.v8i16(<8 x i16> %op1, <8 x i16> %op2)
624   ret <8 x i16> %res
627 define void @umin_v16i16(ptr %a, ptr %b) {
628 ; CHECK-LABEL: umin_v16i16:
629 ; CHECK:       // %bb.0:
630 ; CHECK-NEXT:    ptrue p0.h, vl8
631 ; CHECK-NEXT:    ldp q0, q3, [x1]
632 ; CHECK-NEXT:    ldp q1, q2, [x0]
633 ; CHECK-NEXT:    umin z0.h, p0/m, z0.h, z1.h
634 ; CHECK-NEXT:    movprfx z1, z2
635 ; CHECK-NEXT:    umin z1.h, p0/m, z1.h, z3.h
636 ; CHECK-NEXT:    stp q0, q1, [x0]
637 ; CHECK-NEXT:    ret
638   %op1 = load <16 x i16>, ptr %a
639   %op2 = load <16 x i16>, ptr %b
640   %res = call <16 x i16> @llvm.umin.v16i16(<16 x i16> %op1, <16 x i16> %op2)
641   store <16 x i16> %res, ptr %a
642   ret void
645 define <2 x i32> @umin_v2i32(<2 x i32> %op1, <2 x i32> %op2) {
646 ; CHECK-LABEL: umin_v2i32:
647 ; CHECK:       // %bb.0:
648 ; CHECK-NEXT:    ptrue p0.s, vl2
649 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
650 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
651 ; CHECK-NEXT:    umin z0.s, p0/m, z0.s, z1.s
652 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
653 ; CHECK-NEXT:    ret
654   %res = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %op1, <2 x i32> %op2)
655   ret <2 x i32> %res
658 define <4 x i32> @umin_v4i32(<4 x i32> %op1, <4 x i32> %op2) {
659 ; CHECK-LABEL: umin_v4i32:
660 ; CHECK:       // %bb.0:
661 ; CHECK-NEXT:    ptrue p0.s, vl4
662 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
663 ; CHECK-NEXT:    // kill: def $q1 killed $q1 def $z1
664 ; CHECK-NEXT:    umin z0.s, p0/m, z0.s, z1.s
665 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
666 ; CHECK-NEXT:    ret
667   %res = call <4 x i32> @llvm.umin.v4i32(<4 x i32> %op1, <4 x i32> %op2)
668   ret <4 x i32> %res
671 define void @umin_v8i32(ptr %a, ptr %b) {
672 ; CHECK-LABEL: umin_v8i32:
673 ; CHECK:       // %bb.0:
674 ; CHECK-NEXT:    ptrue p0.s, vl4
675 ; CHECK-NEXT:    ldp q0, q3, [x1]
676 ; CHECK-NEXT:    ldp q1, q2, [x0]
677 ; CHECK-NEXT:    umin z0.s, p0/m, z0.s, z1.s
678 ; CHECK-NEXT:    movprfx z1, z2
679 ; CHECK-NEXT:    umin z1.s, p0/m, z1.s, z3.s
680 ; CHECK-NEXT:    stp q0, q1, [x0]
681 ; CHECK-NEXT:    ret
682   %op1 = load <8 x i32>, ptr %a
683   %op2 = load <8 x i32>, ptr %b
684   %res = call <8 x i32> @llvm.umin.v8i32(<8 x i32> %op1, <8 x i32> %op2)
685   store <8 x i32> %res, ptr %a
686   ret void
689 ; Vector i64 min are not legal for NEON so use SVE when available.
690 define <1 x i64> @umin_v1i64(<1 x i64> %op1, <1 x i64> %op2) {
691 ; CHECK-LABEL: umin_v1i64:
692 ; CHECK:       // %bb.0:
693 ; CHECK-NEXT:    ptrue p0.d, vl1
694 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
695 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
696 ; CHECK-NEXT:    umin z0.d, p0/m, z0.d, z1.d
697 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
698 ; CHECK-NEXT:    ret
699   %res = call <1 x i64> @llvm.umin.v1i64(<1 x i64> %op1, <1 x i64> %op2)
700   ret <1 x i64> %res
703 ; Vector i64 min are not legal for NEON so use SVE when available.
704 define <2 x i64> @umin_v2i64(<2 x i64> %op1, <2 x i64> %op2) {
705 ; CHECK-LABEL: umin_v2i64:
706 ; CHECK:       // %bb.0:
707 ; CHECK-NEXT:    ptrue p0.d, vl2
708 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
709 ; CHECK-NEXT:    // kill: def $q1 killed $q1 def $z1
710 ; CHECK-NEXT:    umin z0.d, p0/m, z0.d, z1.d
711 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
712 ; CHECK-NEXT:    ret
713   %res = call <2 x i64> @llvm.umin.v2i64(<2 x i64> %op1, <2 x i64> %op2)
714   ret <2 x i64> %res
717 define void @umin_v4i64(ptr %a, ptr %b) {
718 ; CHECK-LABEL: umin_v4i64:
719 ; CHECK:       // %bb.0:
720 ; CHECK-NEXT:    ptrue p0.d, vl2
721 ; CHECK-NEXT:    ldp q0, q3, [x1]
722 ; CHECK-NEXT:    ldp q1, q2, [x0]
723 ; CHECK-NEXT:    umin z0.d, p0/m, z0.d, z1.d
724 ; CHECK-NEXT:    movprfx z1, z2
725 ; CHECK-NEXT:    umin z1.d, p0/m, z1.d, z3.d
726 ; CHECK-NEXT:    stp q0, q1, [x0]
727 ; CHECK-NEXT:    ret
728   %op1 = load <4 x i64>, ptr %a
729   %op2 = load <4 x i64>, ptr %b
730   %res = call <4 x i64> @llvm.umin.v4i64(<4 x i64> %op1, <4 x i64> %op2)
731   store <4 x i64> %res, ptr %a
732   ret void
735 declare <8 x i8> @llvm.smin.v8i8(<8 x i8>, <8 x i8>)
736 declare <16 x i8> @llvm.smin.v16i8(<16 x i8>, <16 x i8>)
737 declare <32 x i8> @llvm.smin.v32i8(<32 x i8>, <32 x i8>)
738 declare <4 x i16> @llvm.smin.v4i16(<4 x i16>, <4 x i16>)
739 declare <8 x i16> @llvm.smin.v8i16(<8 x i16>, <8 x i16>)
740 declare <16 x i16> @llvm.smin.v16i16(<16 x i16>, <16 x i16>)
741 declare <2 x i32> @llvm.smin.v2i32(<2 x i32>, <2 x i32>)
742 declare <4 x i32> @llvm.smin.v4i32(<4 x i32>, <4 x i32>)
743 declare <8 x i32> @llvm.smin.v8i32(<8 x i32>, <8 x i32>)
744 declare <1 x i64> @llvm.smin.v1i64(<1 x i64>, <1 x i64>)
745 declare <2 x i64> @llvm.smin.v2i64(<2 x i64>, <2 x i64>)
746 declare <4 x i64> @llvm.smin.v4i64(<4 x i64>, <4 x i64>)
748 declare <8 x i8> @llvm.smax.v8i8(<8 x i8>, <8 x i8>)
749 declare <16 x i8> @llvm.smax.v16i8(<16 x i8>, <16 x i8>)
750 declare <32 x i8> @llvm.smax.v32i8(<32 x i8>, <32 x i8>)
751 declare <4 x i16> @llvm.smax.v4i16(<4 x i16>, <4 x i16>)
752 declare <8 x i16> @llvm.smax.v8i16(<8 x i16>, <8 x i16>)
753 declare <16 x i16> @llvm.smax.v16i16(<16 x i16>, <16 x i16>)
754 declare <2 x i32> @llvm.smax.v2i32(<2 x i32>, <2 x i32>)
755 declare <4 x i32> @llvm.smax.v4i32(<4 x i32>, <4 x i32>)
756 declare <8 x i32> @llvm.smax.v8i32(<8 x i32>, <8 x i32>)
757 declare <1 x i64> @llvm.smax.v1i64(<1 x i64>, <1 x i64>)
758 declare <2 x i64> @llvm.smax.v2i64(<2 x i64>, <2 x i64>)
759 declare <4 x i64> @llvm.smax.v4i64(<4 x i64>, <4 x i64>)
761 declare <8 x i8> @llvm.umin.v8i8(<8 x i8>, <8 x i8>)
762 declare <16 x i8> @llvm.umin.v16i8(<16 x i8>, <16 x i8>)
763 declare <32 x i8> @llvm.umin.v32i8(<32 x i8>, <32 x i8>)
764 declare <4 x i16> @llvm.umin.v4i16(<4 x i16>, <4 x i16>)
765 declare <8 x i16> @llvm.umin.v8i16(<8 x i16>, <8 x i16>)
766 declare <16 x i16> @llvm.umin.v16i16(<16 x i16>, <16 x i16>)
767 declare <2 x i32> @llvm.umin.v2i32(<2 x i32>, <2 x i32>)
768 declare <4 x i32> @llvm.umin.v4i32(<4 x i32>, <4 x i32>)
769 declare <8 x i32> @llvm.umin.v8i32(<8 x i32>, <8 x i32>)
770 declare <1 x i64> @llvm.umin.v1i64(<1 x i64>, <1 x i64>)
771 declare <2 x i64> @llvm.umin.v2i64(<2 x i64>, <2 x i64>)
772 declare <4 x i64> @llvm.umin.v4i64(<4 x i64>, <4 x i64>)
774 declare <8 x i8> @llvm.umax.v8i8(<8 x i8>, <8 x i8>)
775 declare <16 x i8> @llvm.umax.v16i8(<16 x i8>, <16 x i8>)
776 declare <32 x i8> @llvm.umax.v32i8(<32 x i8>, <32 x i8>)
777 declare <4 x i16> @llvm.umax.v4i16(<4 x i16>, <4 x i16>)
778 declare <8 x i16> @llvm.umax.v8i16(<8 x i16>, <8 x i16>)
779 declare <16 x i16> @llvm.umax.v16i16(<16 x i16>, <16 x i16>)
780 declare <2 x i32> @llvm.umax.v2i32(<2 x i32>, <2 x i32>)
781 declare <4 x i32> @llvm.umax.v4i32(<4 x i32>, <4 x i32>)
782 declare <8 x i32> @llvm.umax.v8i32(<8 x i32>, <8 x i32>)
783 declare <1 x i64> @llvm.umax.v1i64(<1 x i64>, <1 x i64>)
784 declare <2 x i64> @llvm.umax.v2i64(<2 x i64>, <2 x i64>)
785 declare <4 x i64> @llvm.umax.v4i64(<4 x i64>, <4 x i64>)