[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / llvm / test / CodeGen / AArch64 / sve-fixed-length-int-minmax.ll
blob4091c01fe93fbd3daca45f3d1d7024aad4836a5d
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -aarch64-sve-vector-bits-min=256  < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_256
3 ; RUN: llc -aarch64-sve-vector-bits-min=512  < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512
4 ; RUN: llc -aarch64-sve-vector-bits-min=2048 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512
6 target triple = "aarch64-unknown-linux-gnu"
9 ; SMAX
12 ; Don't use SVE for 64-bit vectors.
13 define <8 x i8> @smax_v8i8(<8 x i8> %op1, <8 x i8> %op2) vscale_range(2,0) #0 {
14 ; CHECK-LABEL: smax_v8i8:
15 ; CHECK:       // %bb.0:
16 ; CHECK-NEXT:    smax v0.8b, v0.8b, v1.8b
17 ; CHECK-NEXT:    ret
18   %res = call <8 x i8> @llvm.smax.v8i8(<8 x i8> %op1, <8 x i8> %op2)
19   ret <8 x i8> %res
22 ; Don't use SVE for 128-bit vectors.
23 define <16 x i8> @smax_v16i8(<16 x i8> %op1, <16 x i8> %op2) vscale_range(2,0) #0 {
24 ; CHECK-LABEL: smax_v16i8:
25 ; CHECK:       // %bb.0:
26 ; CHECK-NEXT:    smax v0.16b, v0.16b, v1.16b
27 ; CHECK-NEXT:    ret
28   %res = call <16 x i8> @llvm.smax.v16i8(<16 x i8> %op1, <16 x i8> %op2)
29   ret <16 x i8> %res
32 define void @smax_v32i8(ptr %a, ptr %b) vscale_range(2,0) #0 {
33 ; CHECK-LABEL: smax_v32i8:
34 ; CHECK:       // %bb.0:
35 ; CHECK-NEXT:    ptrue p0.b, vl32
36 ; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]
37 ; CHECK-NEXT:    ld1b { z1.b }, p0/z, [x1]
38 ; CHECK-NEXT:    smax z0.b, p0/m, z0.b, z1.b
39 ; CHECK-NEXT:    st1b { z0.b }, p0, [x0]
40 ; CHECK-NEXT:    ret
41   %op1 = load <32 x i8>, ptr %a
42   %op2 = load <32 x i8>, ptr %b
43   %res = call <32 x i8> @llvm.smax.v32i8(<32 x i8> %op1, <32 x i8> %op2)
44   store <32 x i8> %res, ptr %a
45   ret void
48 define void @smax_v64i8(ptr %a, ptr %b) #0 {
49 ; VBITS_GE_256-LABEL: smax_v64i8:
50 ; VBITS_GE_256:       // %bb.0:
51 ; VBITS_GE_256-NEXT:    ptrue p0.b, vl32
52 ; VBITS_GE_256-NEXT:    mov w8, #32 // =0x20
53 ; VBITS_GE_256-NEXT:    ld1b { z0.b }, p0/z, [x0, x8]
54 ; VBITS_GE_256-NEXT:    ld1b { z1.b }, p0/z, [x0]
55 ; VBITS_GE_256-NEXT:    ld1b { z2.b }, p0/z, [x1, x8]
56 ; VBITS_GE_256-NEXT:    ld1b { z3.b }, p0/z, [x1]
57 ; VBITS_GE_256-NEXT:    smax z0.b, p0/m, z0.b, z2.b
58 ; VBITS_GE_256-NEXT:    smax z1.b, p0/m, z1.b, z3.b
59 ; VBITS_GE_256-NEXT:    st1b { z0.b }, p0, [x0, x8]
60 ; VBITS_GE_256-NEXT:    st1b { z1.b }, p0, [x0]
61 ; VBITS_GE_256-NEXT:    ret
63 ; VBITS_GE_512-LABEL: smax_v64i8:
64 ; VBITS_GE_512:       // %bb.0:
65 ; VBITS_GE_512-NEXT:    ptrue p0.b, vl64
66 ; VBITS_GE_512-NEXT:    ld1b { z0.b }, p0/z, [x0]
67 ; VBITS_GE_512-NEXT:    ld1b { z1.b }, p0/z, [x1]
68 ; VBITS_GE_512-NEXT:    smax z0.b, p0/m, z0.b, z1.b
69 ; VBITS_GE_512-NEXT:    st1b { z0.b }, p0, [x0]
70 ; VBITS_GE_512-NEXT:    ret
71   %op1 = load <64 x i8>, ptr %a
72   %op2 = load <64 x i8>, ptr %b
73   %res = call <64 x i8> @llvm.smax.v64i8(<64 x i8> %op1, <64 x i8> %op2)
74   store <64 x i8> %res, ptr %a
75   ret void
78 define void @smax_v128i8(ptr %a, ptr %b) vscale_range(8,0) #0 {
79 ; CHECK-LABEL: smax_v128i8:
80 ; CHECK:       // %bb.0:
81 ; CHECK-NEXT:    ptrue p0.b, vl128
82 ; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]
83 ; CHECK-NEXT:    ld1b { z1.b }, p0/z, [x1]
84 ; CHECK-NEXT:    smax z0.b, p0/m, z0.b, z1.b
85 ; CHECK-NEXT:    st1b { z0.b }, p0, [x0]
86 ; CHECK-NEXT:    ret
87   %op1 = load <128 x i8>, ptr %a
88   %op2 = load <128 x i8>, ptr %b
89   %res = call <128 x i8> @llvm.smax.v128i8(<128 x i8> %op1, <128 x i8> %op2)
90   store <128 x i8> %res, ptr %a
91   ret void
94 define void @smax_v256i8(ptr %a, ptr %b) vscale_range(16,0) #0 {
95 ; CHECK-LABEL: smax_v256i8:
96 ; CHECK:       // %bb.0:
97 ; CHECK-NEXT:    ptrue p0.b, vl256
98 ; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]
99 ; CHECK-NEXT:    ld1b { z1.b }, p0/z, [x1]
100 ; CHECK-NEXT:    smax z0.b, p0/m, z0.b, z1.b
101 ; CHECK-NEXT:    st1b { z0.b }, p0, [x0]
102 ; CHECK-NEXT:    ret
103   %op1 = load <256 x i8>, ptr %a
104   %op2 = load <256 x i8>, ptr %b
105   %res = call <256 x i8> @llvm.smax.v256i8(<256 x i8> %op1, <256 x i8> %op2)
106   store <256 x i8> %res, ptr %a
107   ret void
110 ; Don't use SVE for 64-bit vectors.
111 define <4 x i16> @smax_v4i16(<4 x i16> %op1, <4 x i16> %op2) vscale_range(2,0) #0 {
112 ; CHECK-LABEL: smax_v4i16:
113 ; CHECK:       // %bb.0:
114 ; CHECK-NEXT:    smax v0.4h, v0.4h, v1.4h
115 ; CHECK-NEXT:    ret
116   %res = call <4 x i16> @llvm.smax.v4i16(<4 x i16> %op1, <4 x i16> %op2)
117   ret <4 x i16> %res
120 ; Don't use SVE for 128-bit vectors.
121 define <8 x i16> @smax_v8i16(<8 x i16> %op1, <8 x i16> %op2) vscale_range(2,0) #0 {
122 ; CHECK-LABEL: smax_v8i16:
123 ; CHECK:       // %bb.0:
124 ; CHECK-NEXT:    smax v0.8h, v0.8h, v1.8h
125 ; CHECK-NEXT:    ret
126   %res = call <8 x i16> @llvm.smax.v8i16(<8 x i16> %op1, <8 x i16> %op2)
127   ret <8 x i16> %res
130 define void @smax_v16i16(ptr %a, ptr %b) vscale_range(2,0) #0 {
131 ; CHECK-LABEL: smax_v16i16:
132 ; CHECK:       // %bb.0:
133 ; CHECK-NEXT:    ptrue p0.h, vl16
134 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]
135 ; CHECK-NEXT:    ld1h { z1.h }, p0/z, [x1]
136 ; CHECK-NEXT:    smax z0.h, p0/m, z0.h, z1.h
137 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
138 ; CHECK-NEXT:    ret
139   %op1 = load <16 x i16>, ptr %a
140   %op2 = load <16 x i16>, ptr %b
141   %res = call <16 x i16> @llvm.smax.v16i16(<16 x i16> %op1, <16 x i16> %op2)
142   store <16 x i16> %res, ptr %a
143   ret void
146 define void @smax_v32i16(ptr %a, ptr %b) #0 {
147 ; VBITS_GE_256-LABEL: smax_v32i16:
148 ; VBITS_GE_256:       // %bb.0:
149 ; VBITS_GE_256-NEXT:    ptrue p0.h, vl16
150 ; VBITS_GE_256-NEXT:    mov x8, #16 // =0x10
151 ; VBITS_GE_256-NEXT:    ld1h { z0.h }, p0/z, [x0, x8, lsl #1]
152 ; VBITS_GE_256-NEXT:    ld1h { z1.h }, p0/z, [x0]
153 ; VBITS_GE_256-NEXT:    ld1h { z2.h }, p0/z, [x1, x8, lsl #1]
154 ; VBITS_GE_256-NEXT:    ld1h { z3.h }, p0/z, [x1]
155 ; VBITS_GE_256-NEXT:    smax z0.h, p0/m, z0.h, z2.h
156 ; VBITS_GE_256-NEXT:    smax z1.h, p0/m, z1.h, z3.h
157 ; VBITS_GE_256-NEXT:    st1h { z0.h }, p0, [x0, x8, lsl #1]
158 ; VBITS_GE_256-NEXT:    st1h { z1.h }, p0, [x0]
159 ; VBITS_GE_256-NEXT:    ret
161 ; VBITS_GE_512-LABEL: smax_v32i16:
162 ; VBITS_GE_512:       // %bb.0:
163 ; VBITS_GE_512-NEXT:    ptrue p0.h, vl32
164 ; VBITS_GE_512-NEXT:    ld1h { z0.h }, p0/z, [x0]
165 ; VBITS_GE_512-NEXT:    ld1h { z1.h }, p0/z, [x1]
166 ; VBITS_GE_512-NEXT:    smax z0.h, p0/m, z0.h, z1.h
167 ; VBITS_GE_512-NEXT:    st1h { z0.h }, p0, [x0]
168 ; VBITS_GE_512-NEXT:    ret
169   %op1 = load <32 x i16>, ptr %a
170   %op2 = load <32 x i16>, ptr %b
171   %res = call <32 x i16> @llvm.smax.v32i16(<32 x i16> %op1, <32 x i16> %op2)
172   store <32 x i16> %res, ptr %a
173   ret void
176 define void @smax_v64i16(ptr %a, ptr %b) vscale_range(8,0) #0 {
177 ; CHECK-LABEL: smax_v64i16:
178 ; CHECK:       // %bb.0:
179 ; CHECK-NEXT:    ptrue p0.h, vl64
180 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]
181 ; CHECK-NEXT:    ld1h { z1.h }, p0/z, [x1]
182 ; CHECK-NEXT:    smax z0.h, p0/m, z0.h, z1.h
183 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
184 ; CHECK-NEXT:    ret
185   %op1 = load <64 x i16>, ptr %a
186   %op2 = load <64 x i16>, ptr %b
187   %res = call <64 x i16> @llvm.smax.v64i16(<64 x i16> %op1, <64 x i16> %op2)
188   store <64 x i16> %res, ptr %a
189   ret void
192 define void @smax_v128i16(ptr %a, ptr %b) vscale_range(16,0) #0 {
193 ; CHECK-LABEL: smax_v128i16:
194 ; CHECK:       // %bb.0:
195 ; CHECK-NEXT:    ptrue p0.h, vl128
196 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]
197 ; CHECK-NEXT:    ld1h { z1.h }, p0/z, [x1]
198 ; CHECK-NEXT:    smax z0.h, p0/m, z0.h, z1.h
199 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
200 ; CHECK-NEXT:    ret
201   %op1 = load <128 x i16>, ptr %a
202   %op2 = load <128 x i16>, ptr %b
203   %res = call <128 x i16> @llvm.smax.v128i16(<128 x i16> %op1, <128 x i16> %op2)
204   store <128 x i16> %res, ptr %a
205   ret void
208 ; Don't use SVE for 64-bit vectors.
209 define <2 x i32> @smax_v2i32(<2 x i32> %op1, <2 x i32> %op2) vscale_range(2,0) #0 {
210 ; CHECK-LABEL: smax_v2i32:
211 ; CHECK:       // %bb.0:
212 ; CHECK-NEXT:    smax v0.2s, v0.2s, v1.2s
213 ; CHECK-NEXT:    ret
214   %res = call <2 x i32> @llvm.smax.v2i32(<2 x i32> %op1, <2 x i32> %op2)
215   ret <2 x i32> %res
218 ; Don't use SVE for 128-bit vectors.
219 define <4 x i32> @smax_v4i32(<4 x i32> %op1, <4 x i32> %op2) vscale_range(2,0) #0 {
220 ; CHECK-LABEL: smax_v4i32:
221 ; CHECK:       // %bb.0:
222 ; CHECK-NEXT:    smax v0.4s, v0.4s, v1.4s
223 ; CHECK-NEXT:    ret
224   %res = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %op1, <4 x i32> %op2)
225   ret <4 x i32> %res
228 define void @smax_v8i32(ptr %a, ptr %b) vscale_range(2,0) #0 {
229 ; CHECK-LABEL: smax_v8i32:
230 ; CHECK:       // %bb.0:
231 ; CHECK-NEXT:    ptrue p0.s, vl8
232 ; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0]
233 ; CHECK-NEXT:    ld1w { z1.s }, p0/z, [x1]
234 ; CHECK-NEXT:    smax z0.s, p0/m, z0.s, z1.s
235 ; CHECK-NEXT:    st1w { z0.s }, p0, [x0]
236 ; CHECK-NEXT:    ret
237   %op1 = load <8 x i32>, ptr %a
238   %op2 = load <8 x i32>, ptr %b
239   %res = call <8 x i32> @llvm.smax.v8i32(<8 x i32> %op1, <8 x i32> %op2)
240   store <8 x i32> %res, ptr %a
241   ret void
244 define void @smax_v16i32(ptr %a, ptr %b) #0 {
245 ; VBITS_GE_256-LABEL: smax_v16i32:
246 ; VBITS_GE_256:       // %bb.0:
247 ; VBITS_GE_256-NEXT:    ptrue p0.s, vl8
248 ; VBITS_GE_256-NEXT:    mov x8, #8 // =0x8
249 ; VBITS_GE_256-NEXT:    ld1w { z0.s }, p0/z, [x0, x8, lsl #2]
250 ; VBITS_GE_256-NEXT:    ld1w { z1.s }, p0/z, [x0]
251 ; VBITS_GE_256-NEXT:    ld1w { z2.s }, p0/z, [x1, x8, lsl #2]
252 ; VBITS_GE_256-NEXT:    ld1w { z3.s }, p0/z, [x1]
253 ; VBITS_GE_256-NEXT:    smax z0.s, p0/m, z0.s, z2.s
254 ; VBITS_GE_256-NEXT:    smax z1.s, p0/m, z1.s, z3.s
255 ; VBITS_GE_256-NEXT:    st1w { z0.s }, p0, [x0, x8, lsl #2]
256 ; VBITS_GE_256-NEXT:    st1w { z1.s }, p0, [x0]
257 ; VBITS_GE_256-NEXT:    ret
259 ; VBITS_GE_512-LABEL: smax_v16i32:
260 ; VBITS_GE_512:       // %bb.0:
261 ; VBITS_GE_512-NEXT:    ptrue p0.s, vl16
262 ; VBITS_GE_512-NEXT:    ld1w { z0.s }, p0/z, [x0]
263 ; VBITS_GE_512-NEXT:    ld1w { z1.s }, p0/z, [x1]
264 ; VBITS_GE_512-NEXT:    smax z0.s, p0/m, z0.s, z1.s
265 ; VBITS_GE_512-NEXT:    st1w { z0.s }, p0, [x0]
266 ; VBITS_GE_512-NEXT:    ret
267   %op1 = load <16 x i32>, ptr %a
268   %op2 = load <16 x i32>, ptr %b
269   %res = call <16 x i32> @llvm.smax.v16i32(<16 x i32> %op1, <16 x i32> %op2)
270   store <16 x i32> %res, ptr %a
271   ret void
274 define void @smax_v32i32(ptr %a, ptr %b) vscale_range(8,0) #0 {
275 ; CHECK-LABEL: smax_v32i32:
276 ; CHECK:       // %bb.0:
277 ; CHECK-NEXT:    ptrue p0.s, vl32
278 ; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0]
279 ; CHECK-NEXT:    ld1w { z1.s }, p0/z, [x1]
280 ; CHECK-NEXT:    smax z0.s, p0/m, z0.s, z1.s
281 ; CHECK-NEXT:    st1w { z0.s }, p0, [x0]
282 ; CHECK-NEXT:    ret
283   %op1 = load <32 x i32>, ptr %a
284   %op2 = load <32 x i32>, ptr %b
285   %res = call <32 x i32> @llvm.smax.v32i32(<32 x i32> %op1, <32 x i32> %op2)
286   store <32 x i32> %res, ptr %a
287   ret void
290 define void @smax_v64i32(ptr %a, ptr %b) vscale_range(16,0) #0 {
291 ; CHECK-LABEL: smax_v64i32:
292 ; CHECK:       // %bb.0:
293 ; CHECK-NEXT:    ptrue p0.s, vl64
294 ; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0]
295 ; CHECK-NEXT:    ld1w { z1.s }, p0/z, [x1]
296 ; CHECK-NEXT:    smax z0.s, p0/m, z0.s, z1.s
297 ; CHECK-NEXT:    st1w { z0.s }, p0, [x0]
298 ; CHECK-NEXT:    ret
299   %op1 = load <64 x i32>, ptr %a
300   %op2 = load <64 x i32>, ptr %b
301   %res = call <64 x i32> @llvm.smax.v64i32(<64 x i32> %op1, <64 x i32> %op2)
302   store <64 x i32> %res, ptr %a
303   ret void
306 ; Vector i64 max are not legal for NEON so use SVE when available.
307 define <1 x i64> @smax_v1i64(<1 x i64> %op1, <1 x i64> %op2) vscale_range(2,0) #0 {
308 ; CHECK-LABEL: smax_v1i64:
309 ; CHECK:       // %bb.0:
310 ; CHECK-NEXT:    ptrue p0.d, vl1
311 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
312 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
313 ; CHECK-NEXT:    smax z0.d, p0/m, z0.d, z1.d
314 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
315 ; CHECK-NEXT:    ret
316   %res = call <1 x i64> @llvm.smax.v1i64(<1 x i64> %op1, <1 x i64> %op2)
317   ret <1 x i64> %res
320 ; Vector i64 max are not legal for NEON so use SVE when available.
321 define <2 x i64> @smax_v2i64(<2 x i64> %op1, <2 x i64> %op2) vscale_range(2,0) #0 {
322 ; CHECK-LABEL: smax_v2i64:
323 ; CHECK:       // %bb.0:
324 ; CHECK-NEXT:    ptrue p0.d, vl2
325 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
326 ; CHECK-NEXT:    // kill: def $q1 killed $q1 def $z1
327 ; CHECK-NEXT:    smax z0.d, p0/m, z0.d, z1.d
328 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
329 ; CHECK-NEXT:    ret
330   %res = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %op1, <2 x i64> %op2)
331   ret <2 x i64> %res
334 define void @smax_v4i64(ptr %a, ptr %b) vscale_range(2,0) #0 {
335 ; CHECK-LABEL: smax_v4i64:
336 ; CHECK:       // %bb.0:
337 ; CHECK-NEXT:    ptrue p0.d, vl4
338 ; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0]
339 ; CHECK-NEXT:    ld1d { z1.d }, p0/z, [x1]
340 ; CHECK-NEXT:    smax z0.d, p0/m, z0.d, z1.d
341 ; CHECK-NEXT:    st1d { z0.d }, p0, [x0]
342 ; CHECK-NEXT:    ret
343   %op1 = load <4 x i64>, ptr %a
344   %op2 = load <4 x i64>, ptr %b
345   %res = call <4 x i64> @llvm.smax.v4i64(<4 x i64> %op1, <4 x i64> %op2)
346   store <4 x i64> %res, ptr %a
347   ret void
350 define void @smax_v8i64(ptr %a, ptr %b) #0 {
351 ; VBITS_GE_256-LABEL: smax_v8i64:
352 ; VBITS_GE_256:       // %bb.0:
353 ; VBITS_GE_256-NEXT:    ptrue p0.d, vl4
354 ; VBITS_GE_256-NEXT:    mov x8, #4 // =0x4
355 ; VBITS_GE_256-NEXT:    ld1d { z0.d }, p0/z, [x0, x8, lsl #3]
356 ; VBITS_GE_256-NEXT:    ld1d { z1.d }, p0/z, [x0]
357 ; VBITS_GE_256-NEXT:    ld1d { z2.d }, p0/z, [x1, x8, lsl #3]
358 ; VBITS_GE_256-NEXT:    ld1d { z3.d }, p0/z, [x1]
359 ; VBITS_GE_256-NEXT:    smax z0.d, p0/m, z0.d, z2.d
360 ; VBITS_GE_256-NEXT:    smax z1.d, p0/m, z1.d, z3.d
361 ; VBITS_GE_256-NEXT:    st1d { z0.d }, p0, [x0, x8, lsl #3]
362 ; VBITS_GE_256-NEXT:    st1d { z1.d }, p0, [x0]
363 ; VBITS_GE_256-NEXT:    ret
365 ; VBITS_GE_512-LABEL: smax_v8i64:
366 ; VBITS_GE_512:       // %bb.0:
367 ; VBITS_GE_512-NEXT:    ptrue p0.d, vl8
368 ; VBITS_GE_512-NEXT:    ld1d { z0.d }, p0/z, [x0]
369 ; VBITS_GE_512-NEXT:    ld1d { z1.d }, p0/z, [x1]
370 ; VBITS_GE_512-NEXT:    smax z0.d, p0/m, z0.d, z1.d
371 ; VBITS_GE_512-NEXT:    st1d { z0.d }, p0, [x0]
372 ; VBITS_GE_512-NEXT:    ret
373   %op1 = load <8 x i64>, ptr %a
374   %op2 = load <8 x i64>, ptr %b
375   %res = call <8 x i64> @llvm.smax.v8i64(<8 x i64> %op1, <8 x i64> %op2)
376   store <8 x i64> %res, ptr %a
377   ret void
380 define void @smax_v16i64(ptr %a, ptr %b) vscale_range(8,0) #0 {
381 ; CHECK-LABEL: smax_v16i64:
382 ; CHECK:       // %bb.0:
383 ; CHECK-NEXT:    ptrue p0.d, vl16
384 ; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0]
385 ; CHECK-NEXT:    ld1d { z1.d }, p0/z, [x1]
386 ; CHECK-NEXT:    smax z0.d, p0/m, z0.d, z1.d
387 ; CHECK-NEXT:    st1d { z0.d }, p0, [x0]
388 ; CHECK-NEXT:    ret
389   %op1 = load <16 x i64>, ptr %a
390   %op2 = load <16 x i64>, ptr %b
391   %res = call <16 x i64> @llvm.smax.v16i64(<16 x i64> %op1, <16 x i64> %op2)
392   store <16 x i64> %res, ptr %a
393   ret void
396 define void @smax_v32i64(ptr %a, ptr %b) vscale_range(16,0) #0 {
397 ; CHECK-LABEL: smax_v32i64:
398 ; CHECK:       // %bb.0:
399 ; CHECK-NEXT:    ptrue p0.d, vl32
400 ; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0]
401 ; CHECK-NEXT:    ld1d { z1.d }, p0/z, [x1]
402 ; CHECK-NEXT:    smax z0.d, p0/m, z0.d, z1.d
403 ; CHECK-NEXT:    st1d { z0.d }, p0, [x0]
404 ; CHECK-NEXT:    ret
405   %op1 = load <32 x i64>, ptr %a
406   %op2 = load <32 x i64>, ptr %b
407   %res = call <32 x i64> @llvm.smax.v32i64(<32 x i64> %op1, <32 x i64> %op2)
408   store <32 x i64> %res, ptr %a
409   ret void
413 ; SMIN
416 ; Don't use SVE for 64-bit vectors.
417 define <8 x i8> @smin_v8i8(<8 x i8> %op1, <8 x i8> %op2) vscale_range(2,0) #0 {
418 ; CHECK-LABEL: smin_v8i8:
419 ; CHECK:       // %bb.0:
420 ; CHECK-NEXT:    smin v0.8b, v0.8b, v1.8b
421 ; CHECK-NEXT:    ret
422   %res = call <8 x i8> @llvm.smin.v8i8(<8 x i8> %op1, <8 x i8> %op2)
423   ret <8 x i8> %res
426 ; Don't use SVE for 128-bit vectors.
427 define <16 x i8> @smin_v16i8(<16 x i8> %op1, <16 x i8> %op2) vscale_range(2,0) #0 {
428 ; CHECK-LABEL: smin_v16i8:
429 ; CHECK:       // %bb.0:
430 ; CHECK-NEXT:    smin v0.16b, v0.16b, v1.16b
431 ; CHECK-NEXT:    ret
432   %res = call <16 x i8> @llvm.smin.v16i8(<16 x i8> %op1, <16 x i8> %op2)
433   ret <16 x i8> %res
436 define void @smin_v32i8(ptr %a, ptr %b) vscale_range(2,0) #0 {
437 ; CHECK-LABEL: smin_v32i8:
438 ; CHECK:       // %bb.0:
439 ; CHECK-NEXT:    ptrue p0.b, vl32
440 ; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]
441 ; CHECK-NEXT:    ld1b { z1.b }, p0/z, [x1]
442 ; CHECK-NEXT:    smin z0.b, p0/m, z0.b, z1.b
443 ; CHECK-NEXT:    st1b { z0.b }, p0, [x0]
444 ; CHECK-NEXT:    ret
445   %op1 = load <32 x i8>, ptr %a
446   %op2 = load <32 x i8>, ptr %b
447   %res = call <32 x i8> @llvm.smin.v32i8(<32 x i8> %op1, <32 x i8> %op2)
448   store <32 x i8> %res, ptr %a
449   ret void
452 define void @smin_v64i8(ptr %a, ptr %b) #0 {
453 ; VBITS_GE_256-LABEL: smin_v64i8:
454 ; VBITS_GE_256:       // %bb.0:
455 ; VBITS_GE_256-NEXT:    ptrue p0.b, vl32
456 ; VBITS_GE_256-NEXT:    mov w8, #32 // =0x20
457 ; VBITS_GE_256-NEXT:    ld1b { z0.b }, p0/z, [x0, x8]
458 ; VBITS_GE_256-NEXT:    ld1b { z1.b }, p0/z, [x0]
459 ; VBITS_GE_256-NEXT:    ld1b { z2.b }, p0/z, [x1, x8]
460 ; VBITS_GE_256-NEXT:    ld1b { z3.b }, p0/z, [x1]
461 ; VBITS_GE_256-NEXT:    smin z0.b, p0/m, z0.b, z2.b
462 ; VBITS_GE_256-NEXT:    smin z1.b, p0/m, z1.b, z3.b
463 ; VBITS_GE_256-NEXT:    st1b { z0.b }, p0, [x0, x8]
464 ; VBITS_GE_256-NEXT:    st1b { z1.b }, p0, [x0]
465 ; VBITS_GE_256-NEXT:    ret
467 ; VBITS_GE_512-LABEL: smin_v64i8:
468 ; VBITS_GE_512:       // %bb.0:
469 ; VBITS_GE_512-NEXT:    ptrue p0.b, vl64
470 ; VBITS_GE_512-NEXT:    ld1b { z0.b }, p0/z, [x0]
471 ; VBITS_GE_512-NEXT:    ld1b { z1.b }, p0/z, [x1]
472 ; VBITS_GE_512-NEXT:    smin z0.b, p0/m, z0.b, z1.b
473 ; VBITS_GE_512-NEXT:    st1b { z0.b }, p0, [x0]
474 ; VBITS_GE_512-NEXT:    ret
475   %op1 = load <64 x i8>, ptr %a
476   %op2 = load <64 x i8>, ptr %b
477   %res = call <64 x i8> @llvm.smin.v64i8(<64 x i8> %op1, <64 x i8> %op2)
478   store <64 x i8> %res, ptr %a
479   ret void
482 define void @smin_v128i8(ptr %a, ptr %b) vscale_range(8,0) #0 {
483 ; CHECK-LABEL: smin_v128i8:
484 ; CHECK:       // %bb.0:
485 ; CHECK-NEXT:    ptrue p0.b, vl128
486 ; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]
487 ; CHECK-NEXT:    ld1b { z1.b }, p0/z, [x1]
488 ; CHECK-NEXT:    smin z0.b, p0/m, z0.b, z1.b
489 ; CHECK-NEXT:    st1b { z0.b }, p0, [x0]
490 ; CHECK-NEXT:    ret
491   %op1 = load <128 x i8>, ptr %a
492   %op2 = load <128 x i8>, ptr %b
493   %res = call <128 x i8> @llvm.smin.v128i8(<128 x i8> %op1, <128 x i8> %op2)
494   store <128 x i8> %res, ptr %a
495   ret void
498 define void @smin_v256i8(ptr %a, ptr %b) vscale_range(16,0) #0 {
499 ; CHECK-LABEL: smin_v256i8:
500 ; CHECK:       // %bb.0:
501 ; CHECK-NEXT:    ptrue p0.b, vl256
502 ; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]
503 ; CHECK-NEXT:    ld1b { z1.b }, p0/z, [x1]
504 ; CHECK-NEXT:    smin z0.b, p0/m, z0.b, z1.b
505 ; CHECK-NEXT:    st1b { z0.b }, p0, [x0]
506 ; CHECK-NEXT:    ret
507   %op1 = load <256 x i8>, ptr %a
508   %op2 = load <256 x i8>, ptr %b
509   %res = call <256 x i8> @llvm.smin.v256i8(<256 x i8> %op1, <256 x i8> %op2)
510   store <256 x i8> %res, ptr %a
511   ret void
514 ; Don't use SVE for 64-bit vectors.
515 define <4 x i16> @smin_v4i16(<4 x i16> %op1, <4 x i16> %op2) vscale_range(2,0) #0 {
516 ; CHECK-LABEL: smin_v4i16:
517 ; CHECK:       // %bb.0:
518 ; CHECK-NEXT:    smin v0.4h, v0.4h, v1.4h
519 ; CHECK-NEXT:    ret
520   %res = call <4 x i16> @llvm.smin.v4i16(<4 x i16> %op1, <4 x i16> %op2)
521   ret <4 x i16> %res
524 ; Don't use SVE for 128-bit vectors.
525 define <8 x i16> @smin_v8i16(<8 x i16> %op1, <8 x i16> %op2) vscale_range(2,0) #0 {
526 ; CHECK-LABEL: smin_v8i16:
527 ; CHECK:       // %bb.0:
528 ; CHECK-NEXT:    smin v0.8h, v0.8h, v1.8h
529 ; CHECK-NEXT:    ret
530   %res = call <8 x i16> @llvm.smin.v8i16(<8 x i16> %op1, <8 x i16> %op2)
531   ret <8 x i16> %res
534 define void @smin_v16i16(ptr %a, ptr %b) vscale_range(2,0) #0 {
535 ; CHECK-LABEL: smin_v16i16:
536 ; CHECK:       // %bb.0:
537 ; CHECK-NEXT:    ptrue p0.h, vl16
538 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]
539 ; CHECK-NEXT:    ld1h { z1.h }, p0/z, [x1]
540 ; CHECK-NEXT:    smin z0.h, p0/m, z0.h, z1.h
541 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
542 ; CHECK-NEXT:    ret
543   %op1 = load <16 x i16>, ptr %a
544   %op2 = load <16 x i16>, ptr %b
545   %res = call <16 x i16> @llvm.smin.v16i16(<16 x i16> %op1, <16 x i16> %op2)
546   store <16 x i16> %res, ptr %a
547   ret void
550 define void @smin_v32i16(ptr %a, ptr %b) #0 {
551 ; VBITS_GE_256-LABEL: smin_v32i16:
552 ; VBITS_GE_256:       // %bb.0:
553 ; VBITS_GE_256-NEXT:    ptrue p0.h, vl16
554 ; VBITS_GE_256-NEXT:    mov x8, #16 // =0x10
555 ; VBITS_GE_256-NEXT:    ld1h { z0.h }, p0/z, [x0, x8, lsl #1]
556 ; VBITS_GE_256-NEXT:    ld1h { z1.h }, p0/z, [x0]
557 ; VBITS_GE_256-NEXT:    ld1h { z2.h }, p0/z, [x1, x8, lsl #1]
558 ; VBITS_GE_256-NEXT:    ld1h { z3.h }, p0/z, [x1]
559 ; VBITS_GE_256-NEXT:    smin z0.h, p0/m, z0.h, z2.h
560 ; VBITS_GE_256-NEXT:    smin z1.h, p0/m, z1.h, z3.h
561 ; VBITS_GE_256-NEXT:    st1h { z0.h }, p0, [x0, x8, lsl #1]
562 ; VBITS_GE_256-NEXT:    st1h { z1.h }, p0, [x0]
563 ; VBITS_GE_256-NEXT:    ret
565 ; VBITS_GE_512-LABEL: smin_v32i16:
566 ; VBITS_GE_512:       // %bb.0:
567 ; VBITS_GE_512-NEXT:    ptrue p0.h, vl32
568 ; VBITS_GE_512-NEXT:    ld1h { z0.h }, p0/z, [x0]
569 ; VBITS_GE_512-NEXT:    ld1h { z1.h }, p0/z, [x1]
570 ; VBITS_GE_512-NEXT:    smin z0.h, p0/m, z0.h, z1.h
571 ; VBITS_GE_512-NEXT:    st1h { z0.h }, p0, [x0]
572 ; VBITS_GE_512-NEXT:    ret
573   %op1 = load <32 x i16>, ptr %a
574   %op2 = load <32 x i16>, ptr %b
575   %res = call <32 x i16> @llvm.smin.v32i16(<32 x i16> %op1, <32 x i16> %op2)
576   store <32 x i16> %res, ptr %a
577   ret void
580 define void @smin_v64i16(ptr %a, ptr %b) vscale_range(8,0) #0 {
581 ; CHECK-LABEL: smin_v64i16:
582 ; CHECK:       // %bb.0:
583 ; CHECK-NEXT:    ptrue p0.h, vl64
584 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]
585 ; CHECK-NEXT:    ld1h { z1.h }, p0/z, [x1]
586 ; CHECK-NEXT:    smin z0.h, p0/m, z0.h, z1.h
587 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
588 ; CHECK-NEXT:    ret
589   %op1 = load <64 x i16>, ptr %a
590   %op2 = load <64 x i16>, ptr %b
591   %res = call <64 x i16> @llvm.smin.v64i16(<64 x i16> %op1, <64 x i16> %op2)
592   store <64 x i16> %res, ptr %a
593   ret void
596 define void @smin_v128i16(ptr %a, ptr %b) vscale_range(16,0) #0 {
597 ; CHECK-LABEL: smin_v128i16:
598 ; CHECK:       // %bb.0:
599 ; CHECK-NEXT:    ptrue p0.h, vl128
600 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]
601 ; CHECK-NEXT:    ld1h { z1.h }, p0/z, [x1]
602 ; CHECK-NEXT:    smin z0.h, p0/m, z0.h, z1.h
603 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
604 ; CHECK-NEXT:    ret
605   %op1 = load <128 x i16>, ptr %a
606   %op2 = load <128 x i16>, ptr %b
607   %res = call <128 x i16> @llvm.smin.v128i16(<128 x i16> %op1, <128 x i16> %op2)
608   store <128 x i16> %res, ptr %a
609   ret void
612 ; Don't use SVE for 64-bit vectors.
613 define <2 x i32> @smin_v2i32(<2 x i32> %op1, <2 x i32> %op2) vscale_range(2,0) #0 {
614 ; CHECK-LABEL: smin_v2i32:
615 ; CHECK:       // %bb.0:
616 ; CHECK-NEXT:    smin v0.2s, v0.2s, v1.2s
617 ; CHECK-NEXT:    ret
618   %res = call <2 x i32> @llvm.smin.v2i32(<2 x i32> %op1, <2 x i32> %op2)
619   ret <2 x i32> %res
622 ; Don't use SVE for 128-bit vectors.
623 define <4 x i32> @smin_v4i32(<4 x i32> %op1, <4 x i32> %op2) vscale_range(2,0) #0 {
624 ; CHECK-LABEL: smin_v4i32:
625 ; CHECK:       // %bb.0:
626 ; CHECK-NEXT:    smin v0.4s, v0.4s, v1.4s
627 ; CHECK-NEXT:    ret
628   %res = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %op1, <4 x i32> %op2)
629   ret <4 x i32> %res
632 define void @smin_v8i32(ptr %a, ptr %b) vscale_range(2,0) #0 {
633 ; CHECK-LABEL: smin_v8i32:
634 ; CHECK:       // %bb.0:
635 ; CHECK-NEXT:    ptrue p0.s, vl8
636 ; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0]
637 ; CHECK-NEXT:    ld1w { z1.s }, p0/z, [x1]
638 ; CHECK-NEXT:    smin z0.s, p0/m, z0.s, z1.s
639 ; CHECK-NEXT:    st1w { z0.s }, p0, [x0]
640 ; CHECK-NEXT:    ret
641   %op1 = load <8 x i32>, ptr %a
642   %op2 = load <8 x i32>, ptr %b
643   %res = call <8 x i32> @llvm.smin.v8i32(<8 x i32> %op1, <8 x i32> %op2)
644   store <8 x i32> %res, ptr %a
645   ret void
648 define void @smin_v16i32(ptr %a, ptr %b) #0 {
649 ; VBITS_GE_256-LABEL: smin_v16i32:
650 ; VBITS_GE_256:       // %bb.0:
651 ; VBITS_GE_256-NEXT:    ptrue p0.s, vl8
652 ; VBITS_GE_256-NEXT:    mov x8, #8 // =0x8
653 ; VBITS_GE_256-NEXT:    ld1w { z0.s }, p0/z, [x0, x8, lsl #2]
654 ; VBITS_GE_256-NEXT:    ld1w { z1.s }, p0/z, [x0]
655 ; VBITS_GE_256-NEXT:    ld1w { z2.s }, p0/z, [x1, x8, lsl #2]
656 ; VBITS_GE_256-NEXT:    ld1w { z3.s }, p0/z, [x1]
657 ; VBITS_GE_256-NEXT:    smin z0.s, p0/m, z0.s, z2.s
658 ; VBITS_GE_256-NEXT:    smin z1.s, p0/m, z1.s, z3.s
659 ; VBITS_GE_256-NEXT:    st1w { z0.s }, p0, [x0, x8, lsl #2]
660 ; VBITS_GE_256-NEXT:    st1w { z1.s }, p0, [x0]
661 ; VBITS_GE_256-NEXT:    ret
663 ; VBITS_GE_512-LABEL: smin_v16i32:
664 ; VBITS_GE_512:       // %bb.0:
665 ; VBITS_GE_512-NEXT:    ptrue p0.s, vl16
666 ; VBITS_GE_512-NEXT:    ld1w { z0.s }, p0/z, [x0]
667 ; VBITS_GE_512-NEXT:    ld1w { z1.s }, p0/z, [x1]
668 ; VBITS_GE_512-NEXT:    smin z0.s, p0/m, z0.s, z1.s
669 ; VBITS_GE_512-NEXT:    st1w { z0.s }, p0, [x0]
670 ; VBITS_GE_512-NEXT:    ret
671   %op1 = load <16 x i32>, ptr %a
672   %op2 = load <16 x i32>, ptr %b
673   %res = call <16 x i32> @llvm.smin.v16i32(<16 x i32> %op1, <16 x i32> %op2)
674   store <16 x i32> %res, ptr %a
675   ret void
678 define void @smin_v32i32(ptr %a, ptr %b) vscale_range(8,0) #0 {
679 ; CHECK-LABEL: smin_v32i32:
680 ; CHECK:       // %bb.0:
681 ; CHECK-NEXT:    ptrue p0.s, vl32
682 ; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0]
683 ; CHECK-NEXT:    ld1w { z1.s }, p0/z, [x1]
684 ; CHECK-NEXT:    smin z0.s, p0/m, z0.s, z1.s
685 ; CHECK-NEXT:    st1w { z0.s }, p0, [x0]
686 ; CHECK-NEXT:    ret
687   %op1 = load <32 x i32>, ptr %a
688   %op2 = load <32 x i32>, ptr %b
689   %res = call <32 x i32> @llvm.smin.v32i32(<32 x i32> %op1, <32 x i32> %op2)
690   store <32 x i32> %res, ptr %a
691   ret void
694 define void @smin_v64i32(ptr %a, ptr %b) vscale_range(16,0) #0 {
695 ; CHECK-LABEL: smin_v64i32:
696 ; CHECK:       // %bb.0:
697 ; CHECK-NEXT:    ptrue p0.s, vl64
698 ; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0]
699 ; CHECK-NEXT:    ld1w { z1.s }, p0/z, [x1]
700 ; CHECK-NEXT:    smin z0.s, p0/m, z0.s, z1.s
701 ; CHECK-NEXT:    st1w { z0.s }, p0, [x0]
702 ; CHECK-NEXT:    ret
703   %op1 = load <64 x i32>, ptr %a
704   %op2 = load <64 x i32>, ptr %b
705   %res = call <64 x i32> @llvm.smin.v64i32(<64 x i32> %op1, <64 x i32> %op2)
706   store <64 x i32> %res, ptr %a
707   ret void
710 ; Vector i64 min are not legal for NEON so use SVE when available.
711 define <1 x i64> @smin_v1i64(<1 x i64> %op1, <1 x i64> %op2) vscale_range(2,0) #0 {
712 ; CHECK-LABEL: smin_v1i64:
713 ; CHECK:       // %bb.0:
714 ; CHECK-NEXT:    ptrue p0.d, vl1
715 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
716 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
717 ; CHECK-NEXT:    smin z0.d, p0/m, z0.d, z1.d
718 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
719 ; CHECK-NEXT:    ret
720   %res = call <1 x i64> @llvm.smin.v1i64(<1 x i64> %op1, <1 x i64> %op2)
721   ret <1 x i64> %res
724 ; Vector i64 min are not legal for NEON so use SVE when available.
725 define <2 x i64> @smin_v2i64(<2 x i64> %op1, <2 x i64> %op2) vscale_range(2,0) #0 {
726 ; CHECK-LABEL: smin_v2i64:
727 ; CHECK:       // %bb.0:
728 ; CHECK-NEXT:    ptrue p0.d, vl2
729 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
730 ; CHECK-NEXT:    // kill: def $q1 killed $q1 def $z1
731 ; CHECK-NEXT:    smin z0.d, p0/m, z0.d, z1.d
732 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
733 ; CHECK-NEXT:    ret
734   %res = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %op1, <2 x i64> %op2)
735   ret <2 x i64> %res
738 define void @smin_v4i64(ptr %a, ptr %b) vscale_range(2,0) #0 {
739 ; CHECK-LABEL: smin_v4i64:
740 ; CHECK:       // %bb.0:
741 ; CHECK-NEXT:    ptrue p0.d, vl4
742 ; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0]
743 ; CHECK-NEXT:    ld1d { z1.d }, p0/z, [x1]
744 ; CHECK-NEXT:    smin z0.d, p0/m, z0.d, z1.d
745 ; CHECK-NEXT:    st1d { z0.d }, p0, [x0]
746 ; CHECK-NEXT:    ret
747   %op1 = load <4 x i64>, ptr %a
748   %op2 = load <4 x i64>, ptr %b
749   %res = call <4 x i64> @llvm.smin.v4i64(<4 x i64> %op1, <4 x i64> %op2)
750   store <4 x i64> %res, ptr %a
751   ret void
754 define void @smin_v8i64(ptr %a, ptr %b) #0 {
755 ; VBITS_GE_256-LABEL: smin_v8i64:
756 ; VBITS_GE_256:       // %bb.0:
757 ; VBITS_GE_256-NEXT:    ptrue p0.d, vl4
758 ; VBITS_GE_256-NEXT:    mov x8, #4 // =0x4
759 ; VBITS_GE_256-NEXT:    ld1d { z0.d }, p0/z, [x0, x8, lsl #3]
760 ; VBITS_GE_256-NEXT:    ld1d { z1.d }, p0/z, [x0]
761 ; VBITS_GE_256-NEXT:    ld1d { z2.d }, p0/z, [x1, x8, lsl #3]
762 ; VBITS_GE_256-NEXT:    ld1d { z3.d }, p0/z, [x1]
763 ; VBITS_GE_256-NEXT:    smin z0.d, p0/m, z0.d, z2.d
764 ; VBITS_GE_256-NEXT:    smin z1.d, p0/m, z1.d, z3.d
765 ; VBITS_GE_256-NEXT:    st1d { z0.d }, p0, [x0, x8, lsl #3]
766 ; VBITS_GE_256-NEXT:    st1d { z1.d }, p0, [x0]
767 ; VBITS_GE_256-NEXT:    ret
769 ; VBITS_GE_512-LABEL: smin_v8i64:
770 ; VBITS_GE_512:       // %bb.0:
771 ; VBITS_GE_512-NEXT:    ptrue p0.d, vl8
772 ; VBITS_GE_512-NEXT:    ld1d { z0.d }, p0/z, [x0]
773 ; VBITS_GE_512-NEXT:    ld1d { z1.d }, p0/z, [x1]
774 ; VBITS_GE_512-NEXT:    smin z0.d, p0/m, z0.d, z1.d
775 ; VBITS_GE_512-NEXT:    st1d { z0.d }, p0, [x0]
776 ; VBITS_GE_512-NEXT:    ret
777   %op1 = load <8 x i64>, ptr %a
778   %op2 = load <8 x i64>, ptr %b
779   %res = call <8 x i64> @llvm.smin.v8i64(<8 x i64> %op1, <8 x i64> %op2)
780   store <8 x i64> %res, ptr %a
781   ret void
784 define void @smin_v16i64(ptr %a, ptr %b) vscale_range(8,0) #0 {
785 ; CHECK-LABEL: smin_v16i64:
786 ; CHECK:       // %bb.0:
787 ; CHECK-NEXT:    ptrue p0.d, vl16
788 ; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0]
789 ; CHECK-NEXT:    ld1d { z1.d }, p0/z, [x1]
790 ; CHECK-NEXT:    smin z0.d, p0/m, z0.d, z1.d
791 ; CHECK-NEXT:    st1d { z0.d }, p0, [x0]
792 ; CHECK-NEXT:    ret
793   %op1 = load <16 x i64>, ptr %a
794   %op2 = load <16 x i64>, ptr %b
795   %res = call <16 x i64> @llvm.smin.v16i64(<16 x i64> %op1, <16 x i64> %op2)
796   store <16 x i64> %res, ptr %a
797   ret void
800 define void @smin_v32i64(ptr %a, ptr %b) vscale_range(16,0) #0 {
801 ; CHECK-LABEL: smin_v32i64:
802 ; CHECK:       // %bb.0:
803 ; CHECK-NEXT:    ptrue p0.d, vl32
804 ; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0]
805 ; CHECK-NEXT:    ld1d { z1.d }, p0/z, [x1]
806 ; CHECK-NEXT:    smin z0.d, p0/m, z0.d, z1.d
807 ; CHECK-NEXT:    st1d { z0.d }, p0, [x0]
808 ; CHECK-NEXT:    ret
809   %op1 = load <32 x i64>, ptr %a
810   %op2 = load <32 x i64>, ptr %b
811   %res = call <32 x i64> @llvm.smin.v32i64(<32 x i64> %op1, <32 x i64> %op2)
812   store <32 x i64> %res, ptr %a
813   ret void
817 ; UMAX
820 ; Don't use SVE for 64-bit vectors.
821 define <8 x i8> @umax_v8i8(<8 x i8> %op1, <8 x i8> %op2) vscale_range(2,0) #0 {
822 ; CHECK-LABEL: umax_v8i8:
823 ; CHECK:       // %bb.0:
824 ; CHECK-NEXT:    umax v0.8b, v0.8b, v1.8b
825 ; CHECK-NEXT:    ret
826   %res = call <8 x i8> @llvm.umax.v8i8(<8 x i8> %op1, <8 x i8> %op2)
827   ret <8 x i8> %res
830 ; Don't use SVE for 128-bit vectors.
831 define <16 x i8> @umax_v16i8(<16 x i8> %op1, <16 x i8> %op2) vscale_range(2,0) #0 {
832 ; CHECK-LABEL: umax_v16i8:
833 ; CHECK:       // %bb.0:
834 ; CHECK-NEXT:    umax v0.16b, v0.16b, v1.16b
835 ; CHECK-NEXT:    ret
836   %res = call <16 x i8> @llvm.umax.v16i8(<16 x i8> %op1, <16 x i8> %op2)
837   ret <16 x i8> %res
840 define void @umax_v32i8(ptr %a, ptr %b) vscale_range(2,0) #0 {
841 ; CHECK-LABEL: umax_v32i8:
842 ; CHECK:       // %bb.0:
843 ; CHECK-NEXT:    ptrue p0.b, vl32
844 ; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]
845 ; CHECK-NEXT:    ld1b { z1.b }, p0/z, [x1]
846 ; CHECK-NEXT:    umax z0.b, p0/m, z0.b, z1.b
847 ; CHECK-NEXT:    st1b { z0.b }, p0, [x0]
848 ; CHECK-NEXT:    ret
849   %op1 = load <32 x i8>, ptr %a
850   %op2 = load <32 x i8>, ptr %b
851   %res = call <32 x i8> @llvm.umax.v32i8(<32 x i8> %op1, <32 x i8> %op2)
852   store <32 x i8> %res, ptr %a
853   ret void
856 define void @umax_v64i8(ptr %a, ptr %b) #0 {
857 ; VBITS_GE_256-LABEL: umax_v64i8:
858 ; VBITS_GE_256:       // %bb.0:
859 ; VBITS_GE_256-NEXT:    ptrue p0.b, vl32
860 ; VBITS_GE_256-NEXT:    mov w8, #32 // =0x20
861 ; VBITS_GE_256-NEXT:    ld1b { z0.b }, p0/z, [x0, x8]
862 ; VBITS_GE_256-NEXT:    ld1b { z1.b }, p0/z, [x0]
863 ; VBITS_GE_256-NEXT:    ld1b { z2.b }, p0/z, [x1, x8]
864 ; VBITS_GE_256-NEXT:    ld1b { z3.b }, p0/z, [x1]
865 ; VBITS_GE_256-NEXT:    umax z0.b, p0/m, z0.b, z2.b
866 ; VBITS_GE_256-NEXT:    umax z1.b, p0/m, z1.b, z3.b
867 ; VBITS_GE_256-NEXT:    st1b { z0.b }, p0, [x0, x8]
868 ; VBITS_GE_256-NEXT:    st1b { z1.b }, p0, [x0]
869 ; VBITS_GE_256-NEXT:    ret
871 ; VBITS_GE_512-LABEL: umax_v64i8:
872 ; VBITS_GE_512:       // %bb.0:
873 ; VBITS_GE_512-NEXT:    ptrue p0.b, vl64
874 ; VBITS_GE_512-NEXT:    ld1b { z0.b }, p0/z, [x0]
875 ; VBITS_GE_512-NEXT:    ld1b { z1.b }, p0/z, [x1]
876 ; VBITS_GE_512-NEXT:    umax z0.b, p0/m, z0.b, z1.b
877 ; VBITS_GE_512-NEXT:    st1b { z0.b }, p0, [x0]
878 ; VBITS_GE_512-NEXT:    ret
879   %op1 = load <64 x i8>, ptr %a
880   %op2 = load <64 x i8>, ptr %b
881   %res = call <64 x i8> @llvm.umax.v64i8(<64 x i8> %op1, <64 x i8> %op2)
882   store <64 x i8> %res, ptr %a
883   ret void
886 define void @umax_v128i8(ptr %a, ptr %b) vscale_range(8,0) #0 {
887 ; CHECK-LABEL: umax_v128i8:
888 ; CHECK:       // %bb.0:
889 ; CHECK-NEXT:    ptrue p0.b, vl128
890 ; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]
891 ; CHECK-NEXT:    ld1b { z1.b }, p0/z, [x1]
892 ; CHECK-NEXT:    umax z0.b, p0/m, z0.b, z1.b
893 ; CHECK-NEXT:    st1b { z0.b }, p0, [x0]
894 ; CHECK-NEXT:    ret
895   %op1 = load <128 x i8>, ptr %a
896   %op2 = load <128 x i8>, ptr %b
897   %res = call <128 x i8> @llvm.umax.v128i8(<128 x i8> %op1, <128 x i8> %op2)
898   store <128 x i8> %res, ptr %a
899   ret void
902 define void @umax_v256i8(ptr %a, ptr %b) vscale_range(16,0) #0 {
903 ; CHECK-LABEL: umax_v256i8:
904 ; CHECK:       // %bb.0:
905 ; CHECK-NEXT:    ptrue p0.b, vl256
906 ; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]
907 ; CHECK-NEXT:    ld1b { z1.b }, p0/z, [x1]
908 ; CHECK-NEXT:    umax z0.b, p0/m, z0.b, z1.b
909 ; CHECK-NEXT:    st1b { z0.b }, p0, [x0]
910 ; CHECK-NEXT:    ret
911   %op1 = load <256 x i8>, ptr %a
912   %op2 = load <256 x i8>, ptr %b
913   %res = call <256 x i8> @llvm.umax.v256i8(<256 x i8> %op1, <256 x i8> %op2)
914   store <256 x i8> %res, ptr %a
915   ret void
918 ; Don't use SVE for 64-bit vectors.
919 define <4 x i16> @umax_v4i16(<4 x i16> %op1, <4 x i16> %op2) vscale_range(2,0) #0 {
920 ; CHECK-LABEL: umax_v4i16:
921 ; CHECK:       // %bb.0:
922 ; CHECK-NEXT:    umax v0.4h, v0.4h, v1.4h
923 ; CHECK-NEXT:    ret
924   %res = call <4 x i16> @llvm.umax.v4i16(<4 x i16> %op1, <4 x i16> %op2)
925   ret <4 x i16> %res
928 ; Don't use SVE for 128-bit vectors.
929 define <8 x i16> @umax_v8i16(<8 x i16> %op1, <8 x i16> %op2) vscale_range(2,0) #0 {
930 ; CHECK-LABEL: umax_v8i16:
931 ; CHECK:       // %bb.0:
932 ; CHECK-NEXT:    umax v0.8h, v0.8h, v1.8h
933 ; CHECK-NEXT:    ret
934   %res = call <8 x i16> @llvm.umax.v8i16(<8 x i16> %op1, <8 x i16> %op2)
935   ret <8 x i16> %res
938 define void @umax_v16i16(ptr %a, ptr %b) vscale_range(2,0) #0 {
939 ; CHECK-LABEL: umax_v16i16:
940 ; CHECK:       // %bb.0:
941 ; CHECK-NEXT:    ptrue p0.h, vl16
942 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]
943 ; CHECK-NEXT:    ld1h { z1.h }, p0/z, [x1]
944 ; CHECK-NEXT:    umax z0.h, p0/m, z0.h, z1.h
945 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
946 ; CHECK-NEXT:    ret
947   %op1 = load <16 x i16>, ptr %a
948   %op2 = load <16 x i16>, ptr %b
949   %res = call <16 x i16> @llvm.umax.v16i16(<16 x i16> %op1, <16 x i16> %op2)
950   store <16 x i16> %res, ptr %a
951   ret void
954 define void @umax_v32i16(ptr %a, ptr %b) #0 {
955 ; VBITS_GE_256-LABEL: umax_v32i16:
956 ; VBITS_GE_256:       // %bb.0:
957 ; VBITS_GE_256-NEXT:    ptrue p0.h, vl16
958 ; VBITS_GE_256-NEXT:    mov x8, #16 // =0x10
959 ; VBITS_GE_256-NEXT:    ld1h { z0.h }, p0/z, [x0, x8, lsl #1]
960 ; VBITS_GE_256-NEXT:    ld1h { z1.h }, p0/z, [x0]
961 ; VBITS_GE_256-NEXT:    ld1h { z2.h }, p0/z, [x1, x8, lsl #1]
962 ; VBITS_GE_256-NEXT:    ld1h { z3.h }, p0/z, [x1]
963 ; VBITS_GE_256-NEXT:    umax z0.h, p0/m, z0.h, z2.h
964 ; VBITS_GE_256-NEXT:    umax z1.h, p0/m, z1.h, z3.h
965 ; VBITS_GE_256-NEXT:    st1h { z0.h }, p0, [x0, x8, lsl #1]
966 ; VBITS_GE_256-NEXT:    st1h { z1.h }, p0, [x0]
967 ; VBITS_GE_256-NEXT:    ret
969 ; VBITS_GE_512-LABEL: umax_v32i16:
970 ; VBITS_GE_512:       // %bb.0:
971 ; VBITS_GE_512-NEXT:    ptrue p0.h, vl32
972 ; VBITS_GE_512-NEXT:    ld1h { z0.h }, p0/z, [x0]
973 ; VBITS_GE_512-NEXT:    ld1h { z1.h }, p0/z, [x1]
974 ; VBITS_GE_512-NEXT:    umax z0.h, p0/m, z0.h, z1.h
975 ; VBITS_GE_512-NEXT:    st1h { z0.h }, p0, [x0]
976 ; VBITS_GE_512-NEXT:    ret
977   %op1 = load <32 x i16>, ptr %a
978   %op2 = load <32 x i16>, ptr %b
979   %res = call <32 x i16> @llvm.umax.v32i16(<32 x i16> %op1, <32 x i16> %op2)
980   store <32 x i16> %res, ptr %a
981   ret void
984 define void @umax_v64i16(ptr %a, ptr %b) vscale_range(8,0) #0 {
985 ; CHECK-LABEL: umax_v64i16:
986 ; CHECK:       // %bb.0:
987 ; CHECK-NEXT:    ptrue p0.h, vl64
988 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]
989 ; CHECK-NEXT:    ld1h { z1.h }, p0/z, [x1]
990 ; CHECK-NEXT:    umax z0.h, p0/m, z0.h, z1.h
991 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
992 ; CHECK-NEXT:    ret
993   %op1 = load <64 x i16>, ptr %a
994   %op2 = load <64 x i16>, ptr %b
995   %res = call <64 x i16> @llvm.umax.v64i16(<64 x i16> %op1, <64 x i16> %op2)
996   store <64 x i16> %res, ptr %a
997   ret void
1000 define void @umax_v128i16(ptr %a, ptr %b) vscale_range(16,0) #0 {
1001 ; CHECK-LABEL: umax_v128i16:
1002 ; CHECK:       // %bb.0:
1003 ; CHECK-NEXT:    ptrue p0.h, vl128
1004 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]
1005 ; CHECK-NEXT:    ld1h { z1.h }, p0/z, [x1]
1006 ; CHECK-NEXT:    umax z0.h, p0/m, z0.h, z1.h
1007 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
1008 ; CHECK-NEXT:    ret
1009   %op1 = load <128 x i16>, ptr %a
1010   %op2 = load <128 x i16>, ptr %b
1011   %res = call <128 x i16> @llvm.umax.v128i16(<128 x i16> %op1, <128 x i16> %op2)
1012   store <128 x i16> %res, ptr %a
1013   ret void
1016 ; Don't use SVE for 64-bit vectors.
1017 define <2 x i32> @umax_v2i32(<2 x i32> %op1, <2 x i32> %op2) vscale_range(2,0) #0 {
1018 ; CHECK-LABEL: umax_v2i32:
1019 ; CHECK:       // %bb.0:
1020 ; CHECK-NEXT:    umax v0.2s, v0.2s, v1.2s
1021 ; CHECK-NEXT:    ret
1022   %res = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %op1, <2 x i32> %op2)
1023   ret <2 x i32> %res
1026 ; Don't use SVE for 128-bit vectors.
1027 define <4 x i32> @umax_v4i32(<4 x i32> %op1, <4 x i32> %op2) vscale_range(2,0) #0 {
1028 ; CHECK-LABEL: umax_v4i32:
1029 ; CHECK:       // %bb.0:
1030 ; CHECK-NEXT:    umax v0.4s, v0.4s, v1.4s
1031 ; CHECK-NEXT:    ret
1032   %res = call <4 x i32> @llvm.umax.v4i32(<4 x i32> %op1, <4 x i32> %op2)
1033   ret <4 x i32> %res
1036 define void @umax_v8i32(ptr %a, ptr %b) vscale_range(2,0) #0 {
1037 ; CHECK-LABEL: umax_v8i32:
1038 ; CHECK:       // %bb.0:
1039 ; CHECK-NEXT:    ptrue p0.s, vl8
1040 ; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0]
1041 ; CHECK-NEXT:    ld1w { z1.s }, p0/z, [x1]
1042 ; CHECK-NEXT:    umax z0.s, p0/m, z0.s, z1.s
1043 ; CHECK-NEXT:    st1w { z0.s }, p0, [x0]
1044 ; CHECK-NEXT:    ret
1045   %op1 = load <8 x i32>, ptr %a
1046   %op2 = load <8 x i32>, ptr %b
1047   %res = call <8 x i32> @llvm.umax.v8i32(<8 x i32> %op1, <8 x i32> %op2)
1048   store <8 x i32> %res, ptr %a
1049   ret void
1052 define void @umax_v16i32(ptr %a, ptr %b) #0 {
1053 ; VBITS_GE_256-LABEL: umax_v16i32:
1054 ; VBITS_GE_256:       // %bb.0:
1055 ; VBITS_GE_256-NEXT:    ptrue p0.s, vl8
1056 ; VBITS_GE_256-NEXT:    mov x8, #8 // =0x8
1057 ; VBITS_GE_256-NEXT:    ld1w { z0.s }, p0/z, [x0, x8, lsl #2]
1058 ; VBITS_GE_256-NEXT:    ld1w { z1.s }, p0/z, [x0]
1059 ; VBITS_GE_256-NEXT:    ld1w { z2.s }, p0/z, [x1, x8, lsl #2]
1060 ; VBITS_GE_256-NEXT:    ld1w { z3.s }, p0/z, [x1]
1061 ; VBITS_GE_256-NEXT:    umax z0.s, p0/m, z0.s, z2.s
1062 ; VBITS_GE_256-NEXT:    umax z1.s, p0/m, z1.s, z3.s
1063 ; VBITS_GE_256-NEXT:    st1w { z0.s }, p0, [x0, x8, lsl #2]
1064 ; VBITS_GE_256-NEXT:    st1w { z1.s }, p0, [x0]
1065 ; VBITS_GE_256-NEXT:    ret
1067 ; VBITS_GE_512-LABEL: umax_v16i32:
1068 ; VBITS_GE_512:       // %bb.0:
1069 ; VBITS_GE_512-NEXT:    ptrue p0.s, vl16
1070 ; VBITS_GE_512-NEXT:    ld1w { z0.s }, p0/z, [x0]
1071 ; VBITS_GE_512-NEXT:    ld1w { z1.s }, p0/z, [x1]
1072 ; VBITS_GE_512-NEXT:    umax z0.s, p0/m, z0.s, z1.s
1073 ; VBITS_GE_512-NEXT:    st1w { z0.s }, p0, [x0]
1074 ; VBITS_GE_512-NEXT:    ret
1075   %op1 = load <16 x i32>, ptr %a
1076   %op2 = load <16 x i32>, ptr %b
1077   %res = call <16 x i32> @llvm.umax.v16i32(<16 x i32> %op1, <16 x i32> %op2)
1078   store <16 x i32> %res, ptr %a
1079   ret void
1082 define void @umax_v32i32(ptr %a, ptr %b) vscale_range(8,0) #0 {
1083 ; CHECK-LABEL: umax_v32i32:
1084 ; CHECK:       // %bb.0:
1085 ; CHECK-NEXT:    ptrue p0.s, vl32
1086 ; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0]
1087 ; CHECK-NEXT:    ld1w { z1.s }, p0/z, [x1]
1088 ; CHECK-NEXT:    umax z0.s, p0/m, z0.s, z1.s
1089 ; CHECK-NEXT:    st1w { z0.s }, p0, [x0]
1090 ; CHECK-NEXT:    ret
1091   %op1 = load <32 x i32>, ptr %a
1092   %op2 = load <32 x i32>, ptr %b
1093   %res = call <32 x i32> @llvm.umax.v32i32(<32 x i32> %op1, <32 x i32> %op2)
1094   store <32 x i32> %res, ptr %a
1095   ret void
1098 define void @umax_v64i32(ptr %a, ptr %b) vscale_range(16,0) #0 {
1099 ; CHECK-LABEL: umax_v64i32:
1100 ; CHECK:       // %bb.0:
1101 ; CHECK-NEXT:    ptrue p0.s, vl64
1102 ; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0]
1103 ; CHECK-NEXT:    ld1w { z1.s }, p0/z, [x1]
1104 ; CHECK-NEXT:    umax z0.s, p0/m, z0.s, z1.s
1105 ; CHECK-NEXT:    st1w { z0.s }, p0, [x0]
1106 ; CHECK-NEXT:    ret
1107   %op1 = load <64 x i32>, ptr %a
1108   %op2 = load <64 x i32>, ptr %b
1109   %res = call <64 x i32> @llvm.umax.v64i32(<64 x i32> %op1, <64 x i32> %op2)
1110   store <64 x i32> %res, ptr %a
1111   ret void
1114 ; Vector i64 max are not legal for NEON so use SVE when available.
1115 define <1 x i64> @umax_v1i64(<1 x i64> %op1, <1 x i64> %op2) vscale_range(2,0) #0 {
1116 ; CHECK-LABEL: umax_v1i64:
1117 ; CHECK:       // %bb.0:
1118 ; CHECK-NEXT:    ptrue p0.d, vl1
1119 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
1120 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
1121 ; CHECK-NEXT:    umax z0.d, p0/m, z0.d, z1.d
1122 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
1123 ; CHECK-NEXT:    ret
1124   %res = call <1 x i64> @llvm.umax.v1i64(<1 x i64> %op1, <1 x i64> %op2)
1125   ret <1 x i64> %res
1128 ; Vector i64 max are not legal for NEON so use SVE when available.
1129 define <2 x i64> @umax_v2i64(<2 x i64> %op1, <2 x i64> %op2) vscale_range(2,0) #0 {
1130 ; CHECK-LABEL: umax_v2i64:
1131 ; CHECK:       // %bb.0:
1132 ; CHECK-NEXT:    ptrue p0.d, vl2
1133 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
1134 ; CHECK-NEXT:    // kill: def $q1 killed $q1 def $z1
1135 ; CHECK-NEXT:    umax z0.d, p0/m, z0.d, z1.d
1136 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
1137 ; CHECK-NEXT:    ret
1138   %res = call <2 x i64> @llvm.umax.v2i64(<2 x i64> %op1, <2 x i64> %op2)
1139   ret <2 x i64> %res
1142 define void @umax_v4i64(ptr %a, ptr %b) vscale_range(2,0) #0 {
1143 ; CHECK-LABEL: umax_v4i64:
1144 ; CHECK:       // %bb.0:
1145 ; CHECK-NEXT:    ptrue p0.d, vl4
1146 ; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0]
1147 ; CHECK-NEXT:    ld1d { z1.d }, p0/z, [x1]
1148 ; CHECK-NEXT:    umax z0.d, p0/m, z0.d, z1.d
1149 ; CHECK-NEXT:    st1d { z0.d }, p0, [x0]
1150 ; CHECK-NEXT:    ret
1151   %op1 = load <4 x i64>, ptr %a
1152   %op2 = load <4 x i64>, ptr %b
1153   %res = call <4 x i64> @llvm.umax.v4i64(<4 x i64> %op1, <4 x i64> %op2)
1154   store <4 x i64> %res, ptr %a
1155   ret void
1158 define void @umax_v8i64(ptr %a, ptr %b) #0 {
1159 ; VBITS_GE_256-LABEL: umax_v8i64:
1160 ; VBITS_GE_256:       // %bb.0:
1161 ; VBITS_GE_256-NEXT:    ptrue p0.d, vl4
1162 ; VBITS_GE_256-NEXT:    mov x8, #4 // =0x4
1163 ; VBITS_GE_256-NEXT:    ld1d { z0.d }, p0/z, [x0, x8, lsl #3]
1164 ; VBITS_GE_256-NEXT:    ld1d { z1.d }, p0/z, [x0]
1165 ; VBITS_GE_256-NEXT:    ld1d { z2.d }, p0/z, [x1, x8, lsl #3]
1166 ; VBITS_GE_256-NEXT:    ld1d { z3.d }, p0/z, [x1]
1167 ; VBITS_GE_256-NEXT:    umax z0.d, p0/m, z0.d, z2.d
1168 ; VBITS_GE_256-NEXT:    umax z1.d, p0/m, z1.d, z3.d
1169 ; VBITS_GE_256-NEXT:    st1d { z0.d }, p0, [x0, x8, lsl #3]
1170 ; VBITS_GE_256-NEXT:    st1d { z1.d }, p0, [x0]
1171 ; VBITS_GE_256-NEXT:    ret
1173 ; VBITS_GE_512-LABEL: umax_v8i64:
1174 ; VBITS_GE_512:       // %bb.0:
1175 ; VBITS_GE_512-NEXT:    ptrue p0.d, vl8
1176 ; VBITS_GE_512-NEXT:    ld1d { z0.d }, p0/z, [x0]
1177 ; VBITS_GE_512-NEXT:    ld1d { z1.d }, p0/z, [x1]
1178 ; VBITS_GE_512-NEXT:    umax z0.d, p0/m, z0.d, z1.d
1179 ; VBITS_GE_512-NEXT:    st1d { z0.d }, p0, [x0]
1180 ; VBITS_GE_512-NEXT:    ret
1181   %op1 = load <8 x i64>, ptr %a
1182   %op2 = load <8 x i64>, ptr %b
1183   %res = call <8 x i64> @llvm.umax.v8i64(<8 x i64> %op1, <8 x i64> %op2)
1184   store <8 x i64> %res, ptr %a
1185   ret void
1188 define void @umax_v16i64(ptr %a, ptr %b) vscale_range(8,0) #0 {
1189 ; CHECK-LABEL: umax_v16i64:
1190 ; CHECK:       // %bb.0:
1191 ; CHECK-NEXT:    ptrue p0.d, vl16
1192 ; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0]
1193 ; CHECK-NEXT:    ld1d { z1.d }, p0/z, [x1]
1194 ; CHECK-NEXT:    umax z0.d, p0/m, z0.d, z1.d
1195 ; CHECK-NEXT:    st1d { z0.d }, p0, [x0]
1196 ; CHECK-NEXT:    ret
1197   %op1 = load <16 x i64>, ptr %a
1198   %op2 = load <16 x i64>, ptr %b
1199   %res = call <16 x i64> @llvm.umax.v16i64(<16 x i64> %op1, <16 x i64> %op2)
1200   store <16 x i64> %res, ptr %a
1201   ret void
1204 define void @umax_v32i64(ptr %a, ptr %b) vscale_range(16,0) #0 {
1205 ; CHECK-LABEL: umax_v32i64:
1206 ; CHECK:       // %bb.0:
1207 ; CHECK-NEXT:    ptrue p0.d, vl32
1208 ; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0]
1209 ; CHECK-NEXT:    ld1d { z1.d }, p0/z, [x1]
1210 ; CHECK-NEXT:    umax z0.d, p0/m, z0.d, z1.d
1211 ; CHECK-NEXT:    st1d { z0.d }, p0, [x0]
1212 ; CHECK-NEXT:    ret
1213   %op1 = load <32 x i64>, ptr %a
1214   %op2 = load <32 x i64>, ptr %b
1215   %res = call <32 x i64> @llvm.umax.v32i64(<32 x i64> %op1, <32 x i64> %op2)
1216   store <32 x i64> %res, ptr %a
1217   ret void
1221 ; UMIN
1224 ; Don't use SVE for 64-bit vectors.
1225 define <8 x i8> @umin_v8i8(<8 x i8> %op1, <8 x i8> %op2) vscale_range(2,0) #0 {
1226 ; CHECK-LABEL: umin_v8i8:
1227 ; CHECK:       // %bb.0:
1228 ; CHECK-NEXT:    umin v0.8b, v0.8b, v1.8b
1229 ; CHECK-NEXT:    ret
1230   %res = call <8 x i8> @llvm.umin.v8i8(<8 x i8> %op1, <8 x i8> %op2)
1231   ret <8 x i8> %res
1234 ; Don't use SVE for 128-bit vectors.
1235 define <16 x i8> @umin_v16i8(<16 x i8> %op1, <16 x i8> %op2) vscale_range(2,0) #0 {
1236 ; CHECK-LABEL: umin_v16i8:
1237 ; CHECK:       // %bb.0:
1238 ; CHECK-NEXT:    umin v0.16b, v0.16b, v1.16b
1239 ; CHECK-NEXT:    ret
1240   %res = call <16 x i8> @llvm.umin.v16i8(<16 x i8> %op1, <16 x i8> %op2)
1241   ret <16 x i8> %res
1244 define void @umin_v32i8(ptr %a, ptr %b) vscale_range(2,0) #0 {
1245 ; CHECK-LABEL: umin_v32i8:
1246 ; CHECK:       // %bb.0:
1247 ; CHECK-NEXT:    ptrue p0.b, vl32
1248 ; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]
1249 ; CHECK-NEXT:    ld1b { z1.b }, p0/z, [x1]
1250 ; CHECK-NEXT:    umin z0.b, p0/m, z0.b, z1.b
1251 ; CHECK-NEXT:    st1b { z0.b }, p0, [x0]
1252 ; CHECK-NEXT:    ret
1253   %op1 = load <32 x i8>, ptr %a
1254   %op2 = load <32 x i8>, ptr %b
1255   %res = call <32 x i8> @llvm.umin.v32i8(<32 x i8> %op1, <32 x i8> %op2)
1256   store <32 x i8> %res, ptr %a
1257   ret void
1260 define void @umin_v64i8(ptr %a, ptr %b) #0 {
1261 ; VBITS_GE_256-LABEL: umin_v64i8:
1262 ; VBITS_GE_256:       // %bb.0:
1263 ; VBITS_GE_256-NEXT:    ptrue p0.b, vl32
1264 ; VBITS_GE_256-NEXT:    mov w8, #32 // =0x20
1265 ; VBITS_GE_256-NEXT:    ld1b { z0.b }, p0/z, [x0, x8]
1266 ; VBITS_GE_256-NEXT:    ld1b { z1.b }, p0/z, [x0]
1267 ; VBITS_GE_256-NEXT:    ld1b { z2.b }, p0/z, [x1, x8]
1268 ; VBITS_GE_256-NEXT:    ld1b { z3.b }, p0/z, [x1]
1269 ; VBITS_GE_256-NEXT:    umin z0.b, p0/m, z0.b, z2.b
1270 ; VBITS_GE_256-NEXT:    umin z1.b, p0/m, z1.b, z3.b
1271 ; VBITS_GE_256-NEXT:    st1b { z0.b }, p0, [x0, x8]
1272 ; VBITS_GE_256-NEXT:    st1b { z1.b }, p0, [x0]
1273 ; VBITS_GE_256-NEXT:    ret
1275 ; VBITS_GE_512-LABEL: umin_v64i8:
1276 ; VBITS_GE_512:       // %bb.0:
1277 ; VBITS_GE_512-NEXT:    ptrue p0.b, vl64
1278 ; VBITS_GE_512-NEXT:    ld1b { z0.b }, p0/z, [x0]
1279 ; VBITS_GE_512-NEXT:    ld1b { z1.b }, p0/z, [x1]
1280 ; VBITS_GE_512-NEXT:    umin z0.b, p0/m, z0.b, z1.b
1281 ; VBITS_GE_512-NEXT:    st1b { z0.b }, p0, [x0]
1282 ; VBITS_GE_512-NEXT:    ret
1283   %op1 = load <64 x i8>, ptr %a
1284   %op2 = load <64 x i8>, ptr %b
1285   %res = call <64 x i8> @llvm.umin.v64i8(<64 x i8> %op1, <64 x i8> %op2)
1286   store <64 x i8> %res, ptr %a
1287   ret void
1290 define void @umin_v128i8(ptr %a, ptr %b) vscale_range(8,0) #0 {
1291 ; CHECK-LABEL: umin_v128i8:
1292 ; CHECK:       // %bb.0:
1293 ; CHECK-NEXT:    ptrue p0.b, vl128
1294 ; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]
1295 ; CHECK-NEXT:    ld1b { z1.b }, p0/z, [x1]
1296 ; CHECK-NEXT:    umin z0.b, p0/m, z0.b, z1.b
1297 ; CHECK-NEXT:    st1b { z0.b }, p0, [x0]
1298 ; CHECK-NEXT:    ret
1299   %op1 = load <128 x i8>, ptr %a
1300   %op2 = load <128 x i8>, ptr %b
1301   %res = call <128 x i8> @llvm.umin.v128i8(<128 x i8> %op1, <128 x i8> %op2)
1302   store <128 x i8> %res, ptr %a
1303   ret void
1306 define void @umin_v256i8(ptr %a, ptr %b) vscale_range(16,0) #0 {
1307 ; CHECK-LABEL: umin_v256i8:
1308 ; CHECK:       // %bb.0:
1309 ; CHECK-NEXT:    ptrue p0.b, vl256
1310 ; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]
1311 ; CHECK-NEXT:    ld1b { z1.b }, p0/z, [x1]
1312 ; CHECK-NEXT:    umin z0.b, p0/m, z0.b, z1.b
1313 ; CHECK-NEXT:    st1b { z0.b }, p0, [x0]
1314 ; CHECK-NEXT:    ret
1315   %op1 = load <256 x i8>, ptr %a
1316   %op2 = load <256 x i8>, ptr %b
1317   %res = call <256 x i8> @llvm.umin.v256i8(<256 x i8> %op1, <256 x i8> %op2)
1318   store <256 x i8> %res, ptr %a
1319   ret void
1322 ; Don't use SVE for 64-bit vectors.
1323 define <4 x i16> @umin_v4i16(<4 x i16> %op1, <4 x i16> %op2) vscale_range(2,0) #0 {
1324 ; CHECK-LABEL: umin_v4i16:
1325 ; CHECK:       // %bb.0:
1326 ; CHECK-NEXT:    umin v0.4h, v0.4h, v1.4h
1327 ; CHECK-NEXT:    ret
1328   %res = call <4 x i16> @llvm.umin.v4i16(<4 x i16> %op1, <4 x i16> %op2)
1329   ret <4 x i16> %res
1332 ; Don't use SVE for 128-bit vectors.
1333 define <8 x i16> @umin_v8i16(<8 x i16> %op1, <8 x i16> %op2) vscale_range(2,0) #0 {
1334 ; CHECK-LABEL: umin_v8i16:
1335 ; CHECK:       // %bb.0:
1336 ; CHECK-NEXT:    umin v0.8h, v0.8h, v1.8h
1337 ; CHECK-NEXT:    ret
1338   %res = call <8 x i16> @llvm.umin.v8i16(<8 x i16> %op1, <8 x i16> %op2)
1339   ret <8 x i16> %res
1342 define void @umin_v16i16(ptr %a, ptr %b) vscale_range(2,0) #0 {
1343 ; CHECK-LABEL: umin_v16i16:
1344 ; CHECK:       // %bb.0:
1345 ; CHECK-NEXT:    ptrue p0.h, vl16
1346 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]
1347 ; CHECK-NEXT:    ld1h { z1.h }, p0/z, [x1]
1348 ; CHECK-NEXT:    umin z0.h, p0/m, z0.h, z1.h
1349 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
1350 ; CHECK-NEXT:    ret
1351   %op1 = load <16 x i16>, ptr %a
1352   %op2 = load <16 x i16>, ptr %b
1353   %res = call <16 x i16> @llvm.umin.v16i16(<16 x i16> %op1, <16 x i16> %op2)
1354   store <16 x i16> %res, ptr %a
1355   ret void
1358 define void @umin_v32i16(ptr %a, ptr %b) #0 {
1359 ; VBITS_GE_256-LABEL: umin_v32i16:
1360 ; VBITS_GE_256:       // %bb.0:
1361 ; VBITS_GE_256-NEXT:    ptrue p0.h, vl16
1362 ; VBITS_GE_256-NEXT:    mov x8, #16 // =0x10
1363 ; VBITS_GE_256-NEXT:    ld1h { z0.h }, p0/z, [x0, x8, lsl #1]
1364 ; VBITS_GE_256-NEXT:    ld1h { z1.h }, p0/z, [x0]
1365 ; VBITS_GE_256-NEXT:    ld1h { z2.h }, p0/z, [x1, x8, lsl #1]
1366 ; VBITS_GE_256-NEXT:    ld1h { z3.h }, p0/z, [x1]
1367 ; VBITS_GE_256-NEXT:    umin z0.h, p0/m, z0.h, z2.h
1368 ; VBITS_GE_256-NEXT:    umin z1.h, p0/m, z1.h, z3.h
1369 ; VBITS_GE_256-NEXT:    st1h { z0.h }, p0, [x0, x8, lsl #1]
1370 ; VBITS_GE_256-NEXT:    st1h { z1.h }, p0, [x0]
1371 ; VBITS_GE_256-NEXT:    ret
1373 ; VBITS_GE_512-LABEL: umin_v32i16:
1374 ; VBITS_GE_512:       // %bb.0:
1375 ; VBITS_GE_512-NEXT:    ptrue p0.h, vl32
1376 ; VBITS_GE_512-NEXT:    ld1h { z0.h }, p0/z, [x0]
1377 ; VBITS_GE_512-NEXT:    ld1h { z1.h }, p0/z, [x1]
1378 ; VBITS_GE_512-NEXT:    umin z0.h, p0/m, z0.h, z1.h
1379 ; VBITS_GE_512-NEXT:    st1h { z0.h }, p0, [x0]
1380 ; VBITS_GE_512-NEXT:    ret
1381   %op1 = load <32 x i16>, ptr %a
1382   %op2 = load <32 x i16>, ptr %b
1383   %res = call <32 x i16> @llvm.umin.v32i16(<32 x i16> %op1, <32 x i16> %op2)
1384   store <32 x i16> %res, ptr %a
1385   ret void
1388 define void @umin_v64i16(ptr %a, ptr %b) vscale_range(8,0) #0 {
1389 ; CHECK-LABEL: umin_v64i16:
1390 ; CHECK:       // %bb.0:
1391 ; CHECK-NEXT:    ptrue p0.h, vl64
1392 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]
1393 ; CHECK-NEXT:    ld1h { z1.h }, p0/z, [x1]
1394 ; CHECK-NEXT:    umin z0.h, p0/m, z0.h, z1.h
1395 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
1396 ; CHECK-NEXT:    ret
1397   %op1 = load <64 x i16>, ptr %a
1398   %op2 = load <64 x i16>, ptr %b
1399   %res = call <64 x i16> @llvm.umin.v64i16(<64 x i16> %op1, <64 x i16> %op2)
1400   store <64 x i16> %res, ptr %a
1401   ret void
1404 define void @umin_v128i16(ptr %a, ptr %b) vscale_range(16,0) #0 {
1405 ; CHECK-LABEL: umin_v128i16:
1406 ; CHECK:       // %bb.0:
1407 ; CHECK-NEXT:    ptrue p0.h, vl128
1408 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]
1409 ; CHECK-NEXT:    ld1h { z1.h }, p0/z, [x1]
1410 ; CHECK-NEXT:    umin z0.h, p0/m, z0.h, z1.h
1411 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
1412 ; CHECK-NEXT:    ret
1413   %op1 = load <128 x i16>, ptr %a
1414   %op2 = load <128 x i16>, ptr %b
1415   %res = call <128 x i16> @llvm.umin.v128i16(<128 x i16> %op1, <128 x i16> %op2)
1416   store <128 x i16> %res, ptr %a
1417   ret void
1420 ; Don't use SVE for 64-bit vectors.
1421 define <2 x i32> @umin_v2i32(<2 x i32> %op1, <2 x i32> %op2) vscale_range(2,0) #0 {
1422 ; CHECK-LABEL: umin_v2i32:
1423 ; CHECK:       // %bb.0:
1424 ; CHECK-NEXT:    umin v0.2s, v0.2s, v1.2s
1425 ; CHECK-NEXT:    ret
1426   %res = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %op1, <2 x i32> %op2)
1427   ret <2 x i32> %res
1430 ; Don't use SVE for 128-bit vectors.
1431 define <4 x i32> @umin_v4i32(<4 x i32> %op1, <4 x i32> %op2) vscale_range(2,0) #0 {
1432 ; CHECK-LABEL: umin_v4i32:
1433 ; CHECK:       // %bb.0:
1434 ; CHECK-NEXT:    umin v0.4s, v0.4s, v1.4s
1435 ; CHECK-NEXT:    ret
1436   %res = call <4 x i32> @llvm.umin.v4i32(<4 x i32> %op1, <4 x i32> %op2)
1437   ret <4 x i32> %res
1440 define void @umin_v8i32(ptr %a, ptr %b) vscale_range(2,0) #0 {
1441 ; CHECK-LABEL: umin_v8i32:
1442 ; CHECK:       // %bb.0:
1443 ; CHECK-NEXT:    ptrue p0.s, vl8
1444 ; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0]
1445 ; CHECK-NEXT:    ld1w { z1.s }, p0/z, [x1]
1446 ; CHECK-NEXT:    umin z0.s, p0/m, z0.s, z1.s
1447 ; CHECK-NEXT:    st1w { z0.s }, p0, [x0]
1448 ; CHECK-NEXT:    ret
1449   %op1 = load <8 x i32>, ptr %a
1450   %op2 = load <8 x i32>, ptr %b
1451   %res = call <8 x i32> @llvm.umin.v8i32(<8 x i32> %op1, <8 x i32> %op2)
1452   store <8 x i32> %res, ptr %a
1453   ret void
1456 define void @umin_v16i32(ptr %a, ptr %b) #0 {
1457 ; VBITS_GE_256-LABEL: umin_v16i32:
1458 ; VBITS_GE_256:       // %bb.0:
1459 ; VBITS_GE_256-NEXT:    ptrue p0.s, vl8
1460 ; VBITS_GE_256-NEXT:    mov x8, #8 // =0x8
1461 ; VBITS_GE_256-NEXT:    ld1w { z0.s }, p0/z, [x0, x8, lsl #2]
1462 ; VBITS_GE_256-NEXT:    ld1w { z1.s }, p0/z, [x0]
1463 ; VBITS_GE_256-NEXT:    ld1w { z2.s }, p0/z, [x1, x8, lsl #2]
1464 ; VBITS_GE_256-NEXT:    ld1w { z3.s }, p0/z, [x1]
1465 ; VBITS_GE_256-NEXT:    umin z0.s, p0/m, z0.s, z2.s
1466 ; VBITS_GE_256-NEXT:    umin z1.s, p0/m, z1.s, z3.s
1467 ; VBITS_GE_256-NEXT:    st1w { z0.s }, p0, [x0, x8, lsl #2]
1468 ; VBITS_GE_256-NEXT:    st1w { z1.s }, p0, [x0]
1469 ; VBITS_GE_256-NEXT:    ret
1471 ; VBITS_GE_512-LABEL: umin_v16i32:
1472 ; VBITS_GE_512:       // %bb.0:
1473 ; VBITS_GE_512-NEXT:    ptrue p0.s, vl16
1474 ; VBITS_GE_512-NEXT:    ld1w { z0.s }, p0/z, [x0]
1475 ; VBITS_GE_512-NEXT:    ld1w { z1.s }, p0/z, [x1]
1476 ; VBITS_GE_512-NEXT:    umin z0.s, p0/m, z0.s, z1.s
1477 ; VBITS_GE_512-NEXT:    st1w { z0.s }, p0, [x0]
1478 ; VBITS_GE_512-NEXT:    ret
1479   %op1 = load <16 x i32>, ptr %a
1480   %op2 = load <16 x i32>, ptr %b
1481   %res = call <16 x i32> @llvm.umin.v16i32(<16 x i32> %op1, <16 x i32> %op2)
1482   store <16 x i32> %res, ptr %a
1483   ret void
1486 define void @umin_v32i32(ptr %a, ptr %b) vscale_range(8,0) #0 {
1487 ; CHECK-LABEL: umin_v32i32:
1488 ; CHECK:       // %bb.0:
1489 ; CHECK-NEXT:    ptrue p0.s, vl32
1490 ; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0]
1491 ; CHECK-NEXT:    ld1w { z1.s }, p0/z, [x1]
1492 ; CHECK-NEXT:    umin z0.s, p0/m, z0.s, z1.s
1493 ; CHECK-NEXT:    st1w { z0.s }, p0, [x0]
1494 ; CHECK-NEXT:    ret
1495   %op1 = load <32 x i32>, ptr %a
1496   %op2 = load <32 x i32>, ptr %b
1497   %res = call <32 x i32> @llvm.umin.v32i32(<32 x i32> %op1, <32 x i32> %op2)
1498   store <32 x i32> %res, ptr %a
1499   ret void
1502 define void @umin_v64i32(ptr %a, ptr %b) vscale_range(16,0) #0 {
1503 ; CHECK-LABEL: umin_v64i32:
1504 ; CHECK:       // %bb.0:
1505 ; CHECK-NEXT:    ptrue p0.s, vl64
1506 ; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0]
1507 ; CHECK-NEXT:    ld1w { z1.s }, p0/z, [x1]
1508 ; CHECK-NEXT:    umin z0.s, p0/m, z0.s, z1.s
1509 ; CHECK-NEXT:    st1w { z0.s }, p0, [x0]
1510 ; CHECK-NEXT:    ret
1511   %op1 = load <64 x i32>, ptr %a
1512   %op2 = load <64 x i32>, ptr %b
1513   %res = call <64 x i32> @llvm.umin.v64i32(<64 x i32> %op1, <64 x i32> %op2)
1514   store <64 x i32> %res, ptr %a
1515   ret void
1518 ; Vector i64 min are not legal for NEON so use SVE when available.
1519 define <1 x i64> @umin_v1i64(<1 x i64> %op1, <1 x i64> %op2) vscale_range(2,0) #0 {
1520 ; CHECK-LABEL: umin_v1i64:
1521 ; CHECK:       // %bb.0:
1522 ; CHECK-NEXT:    ptrue p0.d, vl1
1523 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
1524 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
1525 ; CHECK-NEXT:    umin z0.d, p0/m, z0.d, z1.d
1526 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
1527 ; CHECK-NEXT:    ret
1528   %res = call <1 x i64> @llvm.umin.v1i64(<1 x i64> %op1, <1 x i64> %op2)
1529   ret <1 x i64> %res
1532 ; Vector i64 min are not legal for NEON so use SVE when available.
1533 define <2 x i64> @umin_v2i64(<2 x i64> %op1, <2 x i64> %op2) vscale_range(2,0) #0 {
1534 ; CHECK-LABEL: umin_v2i64:
1535 ; CHECK:       // %bb.0:
1536 ; CHECK-NEXT:    ptrue p0.d, vl2
1537 ; CHECK-NEXT:    // kill: def $q0 killed $q0 def $z0
1538 ; CHECK-NEXT:    // kill: def $q1 killed $q1 def $z1
1539 ; CHECK-NEXT:    umin z0.d, p0/m, z0.d, z1.d
1540 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
1541 ; CHECK-NEXT:    ret
1542   %res = call <2 x i64> @llvm.umin.v2i64(<2 x i64> %op1, <2 x i64> %op2)
1543   ret <2 x i64> %res
1546 define void @umin_v4i64(ptr %a, ptr %b) vscale_range(2,0) #0 {
1547 ; CHECK-LABEL: umin_v4i64:
1548 ; CHECK:       // %bb.0:
1549 ; CHECK-NEXT:    ptrue p0.d, vl4
1550 ; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0]
1551 ; CHECK-NEXT:    ld1d { z1.d }, p0/z, [x1]
1552 ; CHECK-NEXT:    umin z0.d, p0/m, z0.d, z1.d
1553 ; CHECK-NEXT:    st1d { z0.d }, p0, [x0]
1554 ; CHECK-NEXT:    ret
1555   %op1 = load <4 x i64>, ptr %a
1556   %op2 = load <4 x i64>, ptr %b
1557   %res = call <4 x i64> @llvm.umin.v4i64(<4 x i64> %op1, <4 x i64> %op2)
1558   store <4 x i64> %res, ptr %a
1559   ret void
1562 define void @umin_v8i64(ptr %a, ptr %b) #0 {
1563 ; VBITS_GE_256-LABEL: umin_v8i64:
1564 ; VBITS_GE_256:       // %bb.0:
1565 ; VBITS_GE_256-NEXT:    ptrue p0.d, vl4
1566 ; VBITS_GE_256-NEXT:    mov x8, #4 // =0x4
1567 ; VBITS_GE_256-NEXT:    ld1d { z0.d }, p0/z, [x0, x8, lsl #3]
1568 ; VBITS_GE_256-NEXT:    ld1d { z1.d }, p0/z, [x0]
1569 ; VBITS_GE_256-NEXT:    ld1d { z2.d }, p0/z, [x1, x8, lsl #3]
1570 ; VBITS_GE_256-NEXT:    ld1d { z3.d }, p0/z, [x1]
1571 ; VBITS_GE_256-NEXT:    umin z0.d, p0/m, z0.d, z2.d
1572 ; VBITS_GE_256-NEXT:    umin z1.d, p0/m, z1.d, z3.d
1573 ; VBITS_GE_256-NEXT:    st1d { z0.d }, p0, [x0, x8, lsl #3]
1574 ; VBITS_GE_256-NEXT:    st1d { z1.d }, p0, [x0]
1575 ; VBITS_GE_256-NEXT:    ret
1577 ; VBITS_GE_512-LABEL: umin_v8i64:
1578 ; VBITS_GE_512:       // %bb.0:
1579 ; VBITS_GE_512-NEXT:    ptrue p0.d, vl8
1580 ; VBITS_GE_512-NEXT:    ld1d { z0.d }, p0/z, [x0]
1581 ; VBITS_GE_512-NEXT:    ld1d { z1.d }, p0/z, [x1]
1582 ; VBITS_GE_512-NEXT:    umin z0.d, p0/m, z0.d, z1.d
1583 ; VBITS_GE_512-NEXT:    st1d { z0.d }, p0, [x0]
1584 ; VBITS_GE_512-NEXT:    ret
1585   %op1 = load <8 x i64>, ptr %a
1586   %op2 = load <8 x i64>, ptr %b
1587   %res = call <8 x i64> @llvm.umin.v8i64(<8 x i64> %op1, <8 x i64> %op2)
1588   store <8 x i64> %res, ptr %a
1589   ret void
1592 define void @umin_v16i64(ptr %a, ptr %b) vscale_range(8,0) #0 {
1593 ; CHECK-LABEL: umin_v16i64:
1594 ; CHECK:       // %bb.0:
1595 ; CHECK-NEXT:    ptrue p0.d, vl16
1596 ; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0]
1597 ; CHECK-NEXT:    ld1d { z1.d }, p0/z, [x1]
1598 ; CHECK-NEXT:    umin z0.d, p0/m, z0.d, z1.d
1599 ; CHECK-NEXT:    st1d { z0.d }, p0, [x0]
1600 ; CHECK-NEXT:    ret
1601   %op1 = load <16 x i64>, ptr %a
1602   %op2 = load <16 x i64>, ptr %b
1603   %res = call <16 x i64> @llvm.umin.v16i64(<16 x i64> %op1, <16 x i64> %op2)
1604   store <16 x i64> %res, ptr %a
1605   ret void
1608 define void @umin_v32i64(ptr %a, ptr %b) vscale_range(16,0) #0 {
1609 ; CHECK-LABEL: umin_v32i64:
1610 ; CHECK:       // %bb.0:
1611 ; CHECK-NEXT:    ptrue p0.d, vl32
1612 ; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0]
1613 ; CHECK-NEXT:    ld1d { z1.d }, p0/z, [x1]
1614 ; CHECK-NEXT:    umin z0.d, p0/m, z0.d, z1.d
1615 ; CHECK-NEXT:    st1d { z0.d }, p0, [x0]
1616 ; CHECK-NEXT:    ret
1617   %op1 = load <32 x i64>, ptr %a
1618   %op2 = load <32 x i64>, ptr %b
1619   %res = call <32 x i64> @llvm.umin.v32i64(<32 x i64> %op1, <32 x i64> %op2)
1620   store <32 x i64> %res, ptr %a
1621   ret void
1624 attributes #0 = { "target-features"="+sve" }
1626 declare <8 x i8> @llvm.smin.v8i8(<8 x i8>, <8 x i8>)
1627 declare <16 x i8> @llvm.smin.v16i8(<16 x i8>, <16 x i8>)
1628 declare <32 x i8> @llvm.smin.v32i8(<32 x i8>, <32 x i8>)
1629 declare <64 x i8> @llvm.smin.v64i8(<64 x i8>, <64 x i8>)
1630 declare <128 x i8> @llvm.smin.v128i8(<128 x i8>, <128 x i8>)
1631 declare <256 x i8> @llvm.smin.v256i8(<256 x i8>, <256 x i8>)
1632 declare <4 x i16> @llvm.smin.v4i16(<4 x i16>, <4 x i16>)
1633 declare <8 x i16> @llvm.smin.v8i16(<8 x i16>, <8 x i16>)
1634 declare <16 x i16> @llvm.smin.v16i16(<16 x i16>, <16 x i16>)
1635 declare <32 x i16> @llvm.smin.v32i16(<32 x i16>, <32 x i16>)
1636 declare <64 x i16> @llvm.smin.v64i16(<64 x i16>, <64 x i16>)
1637 declare <128 x i16> @llvm.smin.v128i16(<128 x i16>, <128 x i16>)
1638 declare <2 x i32> @llvm.smin.v2i32(<2 x i32>, <2 x i32>)
1639 declare <4 x i32> @llvm.smin.v4i32(<4 x i32>, <4 x i32>)
1640 declare <8 x i32> @llvm.smin.v8i32(<8 x i32>, <8 x i32>)
1641 declare <16 x i32> @llvm.smin.v16i32(<16 x i32>, <16 x i32>)
1642 declare <32 x i32> @llvm.smin.v32i32(<32 x i32>, <32 x i32>)
1643 declare <64 x i32> @llvm.smin.v64i32(<64 x i32>, <64 x i32>)
1644 declare <1 x i64> @llvm.smin.v1i64(<1 x i64>, <1 x i64>)
1645 declare <2 x i64> @llvm.smin.v2i64(<2 x i64>, <2 x i64>)
1646 declare <4 x i64> @llvm.smin.v4i64(<4 x i64>, <4 x i64>)
1647 declare <8 x i64> @llvm.smin.v8i64(<8 x i64>, <8 x i64>)
1648 declare <16 x i64> @llvm.smin.v16i64(<16 x i64>, <16 x i64>)
1649 declare <32 x i64> @llvm.smin.v32i64(<32 x i64>, <32 x i64>)
1651 declare <8 x i8> @llvm.smax.v8i8(<8 x i8>, <8 x i8>)
1652 declare <16 x i8> @llvm.smax.v16i8(<16 x i8>, <16 x i8>)
1653 declare <32 x i8> @llvm.smax.v32i8(<32 x i8>, <32 x i8>)
1654 declare <64 x i8> @llvm.smax.v64i8(<64 x i8>, <64 x i8>)
1655 declare <128 x i8> @llvm.smax.v128i8(<128 x i8>, <128 x i8>)
1656 declare <256 x i8> @llvm.smax.v256i8(<256 x i8>, <256 x i8>)
1657 declare <4 x i16> @llvm.smax.v4i16(<4 x i16>, <4 x i16>)
1658 declare <8 x i16> @llvm.smax.v8i16(<8 x i16>, <8 x i16>)
1659 declare <16 x i16> @llvm.smax.v16i16(<16 x i16>, <16 x i16>)
1660 declare <32 x i16> @llvm.smax.v32i16(<32 x i16>, <32 x i16>)
1661 declare <64 x i16> @llvm.smax.v64i16(<64 x i16>, <64 x i16>)
1662 declare <128 x i16> @llvm.smax.v128i16(<128 x i16>, <128 x i16>)
1663 declare <2 x i32> @llvm.smax.v2i32(<2 x i32>, <2 x i32>)
1664 declare <4 x i32> @llvm.smax.v4i32(<4 x i32>, <4 x i32>)
1665 declare <8 x i32> @llvm.smax.v8i32(<8 x i32>, <8 x i32>)
1666 declare <16 x i32> @llvm.smax.v16i32(<16 x i32>, <16 x i32>)
1667 declare <32 x i32> @llvm.smax.v32i32(<32 x i32>, <32 x i32>)
1668 declare <64 x i32> @llvm.smax.v64i32(<64 x i32>, <64 x i32>)
1669 declare <1 x i64> @llvm.smax.v1i64(<1 x i64>, <1 x i64>)
1670 declare <2 x i64> @llvm.smax.v2i64(<2 x i64>, <2 x i64>)
1671 declare <4 x i64> @llvm.smax.v4i64(<4 x i64>, <4 x i64>)
1672 declare <8 x i64> @llvm.smax.v8i64(<8 x i64>, <8 x i64>)
1673 declare <16 x i64> @llvm.smax.v16i64(<16 x i64>, <16 x i64>)
1674 declare <32 x i64> @llvm.smax.v32i64(<32 x i64>, <32 x i64>)
1676 declare <8 x i8> @llvm.umin.v8i8(<8 x i8>, <8 x i8>)
1677 declare <16 x i8> @llvm.umin.v16i8(<16 x i8>, <16 x i8>)
1678 declare <32 x i8> @llvm.umin.v32i8(<32 x i8>, <32 x i8>)
1679 declare <64 x i8> @llvm.umin.v64i8(<64 x i8>, <64 x i8>)
1680 declare <128 x i8> @llvm.umin.v128i8(<128 x i8>, <128 x i8>)
1681 declare <256 x i8> @llvm.umin.v256i8(<256 x i8>, <256 x i8>)
1682 declare <4 x i16> @llvm.umin.v4i16(<4 x i16>, <4 x i16>)
1683 declare <8 x i16> @llvm.umin.v8i16(<8 x i16>, <8 x i16>)
1684 declare <16 x i16> @llvm.umin.v16i16(<16 x i16>, <16 x i16>)
1685 declare <32 x i16> @llvm.umin.v32i16(<32 x i16>, <32 x i16>)
1686 declare <64 x i16> @llvm.umin.v64i16(<64 x i16>, <64 x i16>)
1687 declare <128 x i16> @llvm.umin.v128i16(<128 x i16>, <128 x i16>)
1688 declare <2 x i32> @llvm.umin.v2i32(<2 x i32>, <2 x i32>)
1689 declare <4 x i32> @llvm.umin.v4i32(<4 x i32>, <4 x i32>)
1690 declare <8 x i32> @llvm.umin.v8i32(<8 x i32>, <8 x i32>)
1691 declare <16 x i32> @llvm.umin.v16i32(<16 x i32>, <16 x i32>)
1692 declare <32 x i32> @llvm.umin.v32i32(<32 x i32>, <32 x i32>)
1693 declare <64 x i32> @llvm.umin.v64i32(<64 x i32>, <64 x i32>)
1694 declare <1 x i64> @llvm.umin.v1i64(<1 x i64>, <1 x i64>)
1695 declare <2 x i64> @llvm.umin.v2i64(<2 x i64>, <2 x i64>)
1696 declare <4 x i64> @llvm.umin.v4i64(<4 x i64>, <4 x i64>)
1697 declare <8 x i64> @llvm.umin.v8i64(<8 x i64>, <8 x i64>)
1698 declare <16 x i64> @llvm.umin.v16i64(<16 x i64>, <16 x i64>)
1699 declare <32 x i64> @llvm.umin.v32i64(<32 x i64>, <32 x i64>)
1701 declare <8 x i8> @llvm.umax.v8i8(<8 x i8>, <8 x i8>)
1702 declare <16 x i8> @llvm.umax.v16i8(<16 x i8>, <16 x i8>)
1703 declare <32 x i8> @llvm.umax.v32i8(<32 x i8>, <32 x i8>)
1704 declare <64 x i8> @llvm.umax.v64i8(<64 x i8>, <64 x i8>)
1705 declare <128 x i8> @llvm.umax.v128i8(<128 x i8>, <128 x i8>)
1706 declare <256 x i8> @llvm.umax.v256i8(<256 x i8>, <256 x i8>)
1707 declare <4 x i16> @llvm.umax.v4i16(<4 x i16>, <4 x i16>)
1708 declare <8 x i16> @llvm.umax.v8i16(<8 x i16>, <8 x i16>)
1709 declare <16 x i16> @llvm.umax.v16i16(<16 x i16>, <16 x i16>)
1710 declare <32 x i16> @llvm.umax.v32i16(<32 x i16>, <32 x i16>)
1711 declare <64 x i16> @llvm.umax.v64i16(<64 x i16>, <64 x i16>)
1712 declare <128 x i16> @llvm.umax.v128i16(<128 x i16>, <128 x i16>)
1713 declare <2 x i32> @llvm.umax.v2i32(<2 x i32>, <2 x i32>)
1714 declare <4 x i32> @llvm.umax.v4i32(<4 x i32>, <4 x i32>)
1715 declare <8 x i32> @llvm.umax.v8i32(<8 x i32>, <8 x i32>)
1716 declare <16 x i32> @llvm.umax.v16i32(<16 x i32>, <16 x i32>)
1717 declare <32 x i32> @llvm.umax.v32i32(<32 x i32>, <32 x i32>)
1718 declare <64 x i32> @llvm.umax.v64i32(<64 x i32>, <64 x i32>)
1719 declare <1 x i64> @llvm.umax.v1i64(<1 x i64>, <1 x i64>)
1720 declare <2 x i64> @llvm.umax.v2i64(<2 x i64>, <2 x i64>)
1721 declare <4 x i64> @llvm.umax.v4i64(<4 x i64>, <4 x i64>)
1722 declare <8 x i64> @llvm.umax.v8i64(<8 x i64>, <8 x i64>)
1723 declare <16 x i64> @llvm.umax.v16i64(<16 x i64>, <16 x i64>)
1724 declare <32 x i64> @llvm.umax.v32i64(<32 x i64>, <32 x i64>)