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