[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / sve-fixed-length-int-shifts.ll
blob0424773c14fd08cc0865357bfc1fbc1b39739844
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 ; ASHR
12 ; Don't use SVE for 64-bit vectors.
13 define <8 x i8> @ashr_v8i8(<8 x i8> %op1, <8 x i8> %op2) vscale_range(2,0) #0 {
14 ; CHECK-LABEL: ashr_v8i8:
15 ; CHECK:       // %bb.0:
16 ; CHECK-NEXT:    neg v1.8b, v1.8b
17 ; CHECK-NEXT:    sshl v0.8b, v0.8b, v1.8b
18 ; CHECK-NEXT:    ret
19   %res = ashr <8 x i8> %op1, %op2
20   ret <8 x i8> %res
23 ; Don't use SVE for 128-bit vectors.
24 define <16 x i8> @ashr_v16i8(<16 x i8> %op1, <16 x i8> %op2) vscale_range(2,0) #0 {
25 ; CHECK-LABEL: ashr_v16i8:
26 ; CHECK:       // %bb.0:
27 ; CHECK-NEXT:    neg v1.16b, v1.16b
28 ; CHECK-NEXT:    sshl v0.16b, v0.16b, v1.16b
29 ; CHECK-NEXT:    ret
30   %res = ashr <16 x i8> %op1, %op2
31   ret <16 x i8> %res
34 define void @ashr_v32i8(ptr %a, ptr %b) vscale_range(2,0) #0 {
35 ; CHECK-LABEL: ashr_v32i8:
36 ; CHECK:       // %bb.0:
37 ; CHECK-NEXT:    ptrue p0.b, vl32
38 ; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]
39 ; CHECK-NEXT:    ld1b { z1.b }, p0/z, [x1]
40 ; CHECK-NEXT:    asr z0.b, p0/m, z0.b, z1.b
41 ; CHECK-NEXT:    st1b { z0.b }, p0, [x0]
42 ; CHECK-NEXT:    ret
43   %op1 = load <32 x i8>, ptr %a
44   %op2 = load <32 x i8>, ptr %b
45   %res = ashr <32 x i8> %op1, %op2
46   store <32 x i8> %res, ptr %a
47   ret void
50 define void @ashr_v64i8(ptr %a, ptr %b) #0 {
51 ; VBITS_GE_256-LABEL: ashr_v64i8:
52 ; VBITS_GE_256:       // %bb.0:
53 ; VBITS_GE_256-NEXT:    ptrue p0.b, vl32
54 ; VBITS_GE_256-NEXT:    mov w8, #32 // =0x20
55 ; VBITS_GE_256-NEXT:    ld1b { z0.b }, p0/z, [x0, x8]
56 ; VBITS_GE_256-NEXT:    ld1b { z1.b }, p0/z, [x0]
57 ; VBITS_GE_256-NEXT:    ld1b { z2.b }, p0/z, [x1, x8]
58 ; VBITS_GE_256-NEXT:    ld1b { z3.b }, p0/z, [x1]
59 ; VBITS_GE_256-NEXT:    asr z0.b, p0/m, z0.b, z2.b
60 ; VBITS_GE_256-NEXT:    asr z1.b, p0/m, z1.b, z3.b
61 ; VBITS_GE_256-NEXT:    st1b { z0.b }, p0, [x0, x8]
62 ; VBITS_GE_256-NEXT:    st1b { z1.b }, p0, [x0]
63 ; VBITS_GE_256-NEXT:    ret
65 ; VBITS_GE_512-LABEL: ashr_v64i8:
66 ; VBITS_GE_512:       // %bb.0:
67 ; VBITS_GE_512-NEXT:    ptrue p0.b, vl64
68 ; VBITS_GE_512-NEXT:    ld1b { z0.b }, p0/z, [x0]
69 ; VBITS_GE_512-NEXT:    ld1b { z1.b }, p0/z, [x1]
70 ; VBITS_GE_512-NEXT:    asr z0.b, p0/m, z0.b, z1.b
71 ; VBITS_GE_512-NEXT:    st1b { z0.b }, p0, [x0]
72 ; VBITS_GE_512-NEXT:    ret
73   %op1 = load <64 x i8>, ptr %a
74   %op2 = load <64 x i8>, ptr %b
75   %res = ashr <64 x i8> %op1, %op2
76   store <64 x i8> %res, ptr %a
77   ret void
80 define void @ashr_v128i8(ptr %a, ptr %b) vscale_range(8,0) #0 {
81 ; CHECK-LABEL: ashr_v128i8:
82 ; CHECK:       // %bb.0:
83 ; CHECK-NEXT:    ptrue p0.b, vl128
84 ; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]
85 ; CHECK-NEXT:    ld1b { z1.b }, p0/z, [x1]
86 ; CHECK-NEXT:    asr z0.b, p0/m, z0.b, z1.b
87 ; CHECK-NEXT:    st1b { z0.b }, p0, [x0]
88 ; CHECK-NEXT:    ret
89   %op1 = load <128 x i8>, ptr %a
90   %op2 = load <128 x i8>, ptr %b
91   %res = ashr <128 x i8> %op1, %op2
92   store <128 x i8> %res, ptr %a
93   ret void
96 define void @ashr_v256i8(ptr %a, ptr %b) vscale_range(16,0) #0 {
97 ; CHECK-LABEL: ashr_v256i8:
98 ; CHECK:       // %bb.0:
99 ; CHECK-NEXT:    ptrue p0.b, vl256
100 ; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]
101 ; CHECK-NEXT:    ld1b { z1.b }, p0/z, [x1]
102 ; CHECK-NEXT:    asr z0.b, p0/m, z0.b, z1.b
103 ; CHECK-NEXT:    st1b { z0.b }, p0, [x0]
104 ; CHECK-NEXT:    ret
105   %op1 = load <256 x i8>, ptr %a
106   %op2 = load <256 x i8>, ptr %b
107   %res = ashr <256 x i8> %op1, %op2
108   store <256 x i8> %res, ptr %a
109   ret void
112 ; Don't use SVE for 64-bit vectors.
113 define <4 x i16> @ashr_v4i16(<4 x i16> %op1, <4 x i16> %op2) vscale_range(2,0) #0 {
114 ; CHECK-LABEL: ashr_v4i16:
115 ; CHECK:       // %bb.0:
116 ; CHECK-NEXT:    neg v1.4h, v1.4h
117 ; CHECK-NEXT:    sshl v0.4h, v0.4h, v1.4h
118 ; CHECK-NEXT:    ret
119   %res = ashr <4 x i16> %op1, %op2
120   ret <4 x i16> %res
123 ; Don't use SVE for 128-bit vectors.
124 define <8 x i16> @ashr_v8i16(<8 x i16> %op1, <8 x i16> %op2) vscale_range(2,0) #0 {
125 ; CHECK-LABEL: ashr_v8i16:
126 ; CHECK:       // %bb.0:
127 ; CHECK-NEXT:    neg v1.8h, v1.8h
128 ; CHECK-NEXT:    sshl v0.8h, v0.8h, v1.8h
129 ; CHECK-NEXT:    ret
130   %res = ashr <8 x i16> %op1, %op2
131   ret <8 x i16> %res
134 define void @ashr_v16i16(ptr %a, ptr %b) vscale_range(2,0) #0 {
135 ; CHECK-LABEL: ashr_v16i16:
136 ; CHECK:       // %bb.0:
137 ; CHECK-NEXT:    ptrue p0.h, vl16
138 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]
139 ; CHECK-NEXT:    ld1h { z1.h }, p0/z, [x1]
140 ; CHECK-NEXT:    asr z0.h, p0/m, z0.h, z1.h
141 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
142 ; CHECK-NEXT:    ret
143   %op1 = load <16 x i16>, ptr %a
144   %op2 = load <16 x i16>, ptr %b
145   %res = ashr <16 x i16> %op1, %op2
146   store <16 x i16> %res, ptr %a
147   ret void
150 define void @ashr_v32i16(ptr %a, ptr %b) #0 {
151 ; VBITS_GE_256-LABEL: ashr_v32i16:
152 ; VBITS_GE_256:       // %bb.0:
153 ; VBITS_GE_256-NEXT:    ptrue p0.h, vl16
154 ; VBITS_GE_256-NEXT:    mov x8, #16 // =0x10
155 ; VBITS_GE_256-NEXT:    ld1h { z0.h }, p0/z, [x0, x8, lsl #1]
156 ; VBITS_GE_256-NEXT:    ld1h { z1.h }, p0/z, [x0]
157 ; VBITS_GE_256-NEXT:    ld1h { z2.h }, p0/z, [x1, x8, lsl #1]
158 ; VBITS_GE_256-NEXT:    ld1h { z3.h }, p0/z, [x1]
159 ; VBITS_GE_256-NEXT:    asr z0.h, p0/m, z0.h, z2.h
160 ; VBITS_GE_256-NEXT:    asr z1.h, p0/m, z1.h, z3.h
161 ; VBITS_GE_256-NEXT:    st1h { z0.h }, p0, [x0, x8, lsl #1]
162 ; VBITS_GE_256-NEXT:    st1h { z1.h }, p0, [x0]
163 ; VBITS_GE_256-NEXT:    ret
165 ; VBITS_GE_512-LABEL: ashr_v32i16:
166 ; VBITS_GE_512:       // %bb.0:
167 ; VBITS_GE_512-NEXT:    ptrue p0.h, vl32
168 ; VBITS_GE_512-NEXT:    ld1h { z0.h }, p0/z, [x0]
169 ; VBITS_GE_512-NEXT:    ld1h { z1.h }, p0/z, [x1]
170 ; VBITS_GE_512-NEXT:    asr z0.h, p0/m, z0.h, z1.h
171 ; VBITS_GE_512-NEXT:    st1h { z0.h }, p0, [x0]
172 ; VBITS_GE_512-NEXT:    ret
173   %op1 = load <32 x i16>, ptr %a
174   %op2 = load <32 x i16>, ptr %b
175   %res = ashr <32 x i16> %op1, %op2
176   store <32 x i16> %res, ptr %a
177   ret void
180 define void @ashr_v64i16(ptr %a, ptr %b) vscale_range(8,0) #0 {
181 ; CHECK-LABEL: ashr_v64i16:
182 ; CHECK:       // %bb.0:
183 ; CHECK-NEXT:    ptrue p0.h, vl64
184 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]
185 ; CHECK-NEXT:    ld1h { z1.h }, p0/z, [x1]
186 ; CHECK-NEXT:    asr z0.h, p0/m, z0.h, z1.h
187 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
188 ; CHECK-NEXT:    ret
189   %op1 = load <64 x i16>, ptr %a
190   %op2 = load <64 x i16>, ptr %b
191   %res = ashr <64 x i16> %op1, %op2
192   store <64 x i16> %res, ptr %a
193   ret void
196 define void @ashr_v128i16(ptr %a, ptr %b) vscale_range(16,0) #0 {
197 ; CHECK-LABEL: ashr_v128i16:
198 ; CHECK:       // %bb.0:
199 ; CHECK-NEXT:    ptrue p0.h, vl128
200 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]
201 ; CHECK-NEXT:    ld1h { z1.h }, p0/z, [x1]
202 ; CHECK-NEXT:    asr z0.h, p0/m, z0.h, z1.h
203 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
204 ; CHECK-NEXT:    ret
205   %op1 = load <128 x i16>, ptr %a
206   %op2 = load <128 x i16>, ptr %b
207   %res = ashr <128 x i16> %op1, %op2
208   store <128 x i16> %res, ptr %a
209   ret void
212 ; Don't use SVE for 64-bit vectors.
213 define <2 x i32> @ashr_v2i32(<2 x i32> %op1, <2 x i32> %op2) vscale_range(2,0) #0 {
214 ; CHECK-LABEL: ashr_v2i32:
215 ; CHECK:       // %bb.0:
216 ; CHECK-NEXT:    neg v1.2s, v1.2s
217 ; CHECK-NEXT:    sshl v0.2s, v0.2s, v1.2s
218 ; CHECK-NEXT:    ret
219   %res = ashr <2 x i32> %op1, %op2
220   ret <2 x i32> %res
223 ; Don't use SVE for 128-bit vectors.
224 define <4 x i32> @ashr_v4i32(<4 x i32> %op1, <4 x i32> %op2) vscale_range(2,0) #0 {
225 ; CHECK-LABEL: ashr_v4i32:
226 ; CHECK:       // %bb.0:
227 ; CHECK-NEXT:    neg v1.4s, v1.4s
228 ; CHECK-NEXT:    sshl v0.4s, v0.4s, v1.4s
229 ; CHECK-NEXT:    ret
230   %res = ashr <4 x i32> %op1, %op2
231   ret <4 x i32> %res
234 define void @ashr_v8i32(ptr %a, ptr %b) vscale_range(2,0) #0 {
235 ; CHECK-LABEL: ashr_v8i32:
236 ; CHECK:       // %bb.0:
237 ; CHECK-NEXT:    ptrue p0.s, vl8
238 ; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0]
239 ; CHECK-NEXT:    ld1w { z1.s }, p0/z, [x1]
240 ; CHECK-NEXT:    asr z0.s, p0/m, z0.s, z1.s
241 ; CHECK-NEXT:    st1w { z0.s }, p0, [x0]
242 ; CHECK-NEXT:    ret
243   %op1 = load <8 x i32>, ptr %a
244   %op2 = load <8 x i32>, ptr %b
245   %res = ashr <8 x i32> %op1, %op2
246   store <8 x i32> %res, ptr %a
247   ret void
250 define void @ashr_v16i32(ptr %a, ptr %b) #0 {
251 ; VBITS_GE_256-LABEL: ashr_v16i32:
252 ; VBITS_GE_256:       // %bb.0:
253 ; VBITS_GE_256-NEXT:    ptrue p0.s, vl8
254 ; VBITS_GE_256-NEXT:    mov x8, #8 // =0x8
255 ; VBITS_GE_256-NEXT:    ld1w { z0.s }, p0/z, [x0, x8, lsl #2]
256 ; VBITS_GE_256-NEXT:    ld1w { z1.s }, p0/z, [x0]
257 ; VBITS_GE_256-NEXT:    ld1w { z2.s }, p0/z, [x1, x8, lsl #2]
258 ; VBITS_GE_256-NEXT:    ld1w { z3.s }, p0/z, [x1]
259 ; VBITS_GE_256-NEXT:    asr z0.s, p0/m, z0.s, z2.s
260 ; VBITS_GE_256-NEXT:    asr z1.s, p0/m, z1.s, z3.s
261 ; VBITS_GE_256-NEXT:    st1w { z0.s }, p0, [x0, x8, lsl #2]
262 ; VBITS_GE_256-NEXT:    st1w { z1.s }, p0, [x0]
263 ; VBITS_GE_256-NEXT:    ret
265 ; VBITS_GE_512-LABEL: ashr_v16i32:
266 ; VBITS_GE_512:       // %bb.0:
267 ; VBITS_GE_512-NEXT:    ptrue p0.s, vl16
268 ; VBITS_GE_512-NEXT:    ld1w { z0.s }, p0/z, [x0]
269 ; VBITS_GE_512-NEXT:    ld1w { z1.s }, p0/z, [x1]
270 ; VBITS_GE_512-NEXT:    asr z0.s, p0/m, z0.s, z1.s
271 ; VBITS_GE_512-NEXT:    st1w { z0.s }, p0, [x0]
272 ; VBITS_GE_512-NEXT:    ret
273   %op1 = load <16 x i32>, ptr %a
274   %op2 = load <16 x i32>, ptr %b
275   %res = ashr <16 x i32> %op1, %op2
276   store <16 x i32> %res, ptr %a
277   ret void
280 define void @ashr_v32i32(ptr %a, ptr %b) vscale_range(8,0) #0 {
281 ; CHECK-LABEL: ashr_v32i32:
282 ; CHECK:       // %bb.0:
283 ; CHECK-NEXT:    ptrue p0.s, vl32
284 ; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0]
285 ; CHECK-NEXT:    ld1w { z1.s }, p0/z, [x1]
286 ; CHECK-NEXT:    asr z0.s, p0/m, z0.s, z1.s
287 ; CHECK-NEXT:    st1w { z0.s }, p0, [x0]
288 ; CHECK-NEXT:    ret
289   %op1 = load <32 x i32>, ptr %a
290   %op2 = load <32 x i32>, ptr %b
291   %res = ashr <32 x i32> %op1, %op2
292   store <32 x i32> %res, ptr %a
293   ret void
296 define void @ashr_v64i32(ptr %a, ptr %b) vscale_range(16,0) #0 {
297 ; CHECK-LABEL: ashr_v64i32:
298 ; CHECK:       // %bb.0:
299 ; CHECK-NEXT:    ptrue p0.s, vl64
300 ; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0]
301 ; CHECK-NEXT:    ld1w { z1.s }, p0/z, [x1]
302 ; CHECK-NEXT:    asr z0.s, p0/m, z0.s, z1.s
303 ; CHECK-NEXT:    st1w { z0.s }, p0, [x0]
304 ; CHECK-NEXT:    ret
305   %op1 = load <64 x i32>, ptr %a
306   %op2 = load <64 x i32>, ptr %b
307   %res = ashr <64 x i32> %op1, %op2
308   store <64 x i32> %res, ptr %a
309   ret void
312 ; Don't use SVE for 64-bit vectors.
313 define <1 x i64> @ashr_v1i64(<1 x i64> %op1, <1 x i64> %op2) vscale_range(2,0) #0 {
314 ; CHECK-LABEL: ashr_v1i64:
315 ; CHECK:       // %bb.0:
316 ; CHECK-NEXT:    neg d1, d1
317 ; CHECK-NEXT:    sshl d0, d0, d1
318 ; CHECK-NEXT:    ret
319   %res = ashr <1 x i64> %op1, %op2
320   ret <1 x i64> %res
323 ; Don't use SVE for 128-bit vectors.
324 define <2 x i64> @ashr_v2i64(<2 x i64> %op1, <2 x i64> %op2) vscale_range(2,0) #0 {
325 ; CHECK-LABEL: ashr_v2i64:
326 ; CHECK:       // %bb.0:
327 ; CHECK-NEXT:    neg v1.2d, v1.2d
328 ; CHECK-NEXT:    sshl v0.2d, v0.2d, v1.2d
329 ; CHECK-NEXT:    ret
330   %res = ashr <2 x i64> %op1, %op2
331   ret <2 x i64> %res
334 define void @ashr_v4i64(ptr %a, ptr %b) vscale_range(2,0) #0 {
335 ; CHECK-LABEL: ashr_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:    asr 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 = ashr <4 x i64> %op1, %op2
346   store <4 x i64> %res, ptr %a
347   ret void
350 define void @ashr_v8i64(ptr %a, ptr %b) #0 {
351 ; VBITS_GE_256-LABEL: ashr_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:    asr z0.d, p0/m, z0.d, z2.d
360 ; VBITS_GE_256-NEXT:    asr 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: ashr_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:    asr 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 = ashr <8 x i64> %op1, %op2
376   store <8 x i64> %res, ptr %a
377   ret void
380 define void @ashr_v16i64(ptr %a, ptr %b) vscale_range(8,0) #0 {
381 ; CHECK-LABEL: ashr_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:    asr 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 = ashr <16 x i64> %op1, %op2
392   store <16 x i64> %res, ptr %a
393   ret void
396 define void @ashr_v32i64(ptr %a, ptr %b) vscale_range(16,0) #0 {
397 ; CHECK-LABEL: ashr_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:    asr 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 = ashr <32 x i64> %op1, %op2
408   store <32 x i64> %res, ptr %a
409   ret void
413 ; LSHR
416 ; Don't use SVE for 64-bit vectors.
417 define <8 x i8> @lshr_v8i8(<8 x i8> %op1, <8 x i8> %op2) vscale_range(2,0) #0 {
418 ; CHECK-LABEL: lshr_v8i8:
419 ; CHECK:       // %bb.0:
420 ; CHECK-NEXT:    neg v1.8b, v1.8b
421 ; CHECK-NEXT:    ushl v0.8b, v0.8b, v1.8b
422 ; CHECK-NEXT:    ret
423   %res = lshr <8 x i8> %op1, %op2
424   ret <8 x i8> %res
427 ; Don't use SVE for 128-bit vectors.
428 define <16 x i8> @lshr_v16i8(<16 x i8> %op1, <16 x i8> %op2) vscale_range(2,0) #0 {
429 ; CHECK-LABEL: lshr_v16i8:
430 ; CHECK:       // %bb.0:
431 ; CHECK-NEXT:    neg v1.16b, v1.16b
432 ; CHECK-NEXT:    ushl v0.16b, v0.16b, v1.16b
433 ; CHECK-NEXT:    ret
434   %res = lshr <16 x i8> %op1, %op2
435   ret <16 x i8> %res
438 define void @lshr_v32i8(ptr %a, ptr %b) vscale_range(2,0) #0 {
439 ; CHECK-LABEL: lshr_v32i8:
440 ; CHECK:       // %bb.0:
441 ; CHECK-NEXT:    ptrue p0.b, vl32
442 ; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]
443 ; CHECK-NEXT:    ld1b { z1.b }, p0/z, [x1]
444 ; CHECK-NEXT:    lsr z0.b, p0/m, z0.b, z1.b
445 ; CHECK-NEXT:    st1b { z0.b }, p0, [x0]
446 ; CHECK-NEXT:    ret
447   %op1 = load <32 x i8>, ptr %a
448   %op2 = load <32 x i8>, ptr %b
449   %res = lshr <32 x i8> %op1, %op2
450   store <32 x i8> %res, ptr %a
451   ret void
454 define void @lshr_v64i8(ptr %a, ptr %b) #0 {
455 ; VBITS_GE_256-LABEL: lshr_v64i8:
456 ; VBITS_GE_256:       // %bb.0:
457 ; VBITS_GE_256-NEXT:    ptrue p0.b, vl32
458 ; VBITS_GE_256-NEXT:    mov w8, #32 // =0x20
459 ; VBITS_GE_256-NEXT:    ld1b { z0.b }, p0/z, [x0, x8]
460 ; VBITS_GE_256-NEXT:    ld1b { z1.b }, p0/z, [x0]
461 ; VBITS_GE_256-NEXT:    ld1b { z2.b }, p0/z, [x1, x8]
462 ; VBITS_GE_256-NEXT:    ld1b { z3.b }, p0/z, [x1]
463 ; VBITS_GE_256-NEXT:    lsr z0.b, p0/m, z0.b, z2.b
464 ; VBITS_GE_256-NEXT:    lsr z1.b, p0/m, z1.b, z3.b
465 ; VBITS_GE_256-NEXT:    st1b { z0.b }, p0, [x0, x8]
466 ; VBITS_GE_256-NEXT:    st1b { z1.b }, p0, [x0]
467 ; VBITS_GE_256-NEXT:    ret
469 ; VBITS_GE_512-LABEL: lshr_v64i8:
470 ; VBITS_GE_512:       // %bb.0:
471 ; VBITS_GE_512-NEXT:    ptrue p0.b, vl64
472 ; VBITS_GE_512-NEXT:    ld1b { z0.b }, p0/z, [x0]
473 ; VBITS_GE_512-NEXT:    ld1b { z1.b }, p0/z, [x1]
474 ; VBITS_GE_512-NEXT:    lsr z0.b, p0/m, z0.b, z1.b
475 ; VBITS_GE_512-NEXT:    st1b { z0.b }, p0, [x0]
476 ; VBITS_GE_512-NEXT:    ret
477   %op1 = load <64 x i8>, ptr %a
478   %op2 = load <64 x i8>, ptr %b
479   %res = lshr <64 x i8> %op1, %op2
480   store <64 x i8> %res, ptr %a
481   ret void
484 define void @lshr_v128i8(ptr %a, ptr %b) vscale_range(8,0) #0 {
485 ; CHECK-LABEL: lshr_v128i8:
486 ; CHECK:       // %bb.0:
487 ; CHECK-NEXT:    ptrue p0.b, vl128
488 ; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]
489 ; CHECK-NEXT:    ld1b { z1.b }, p0/z, [x1]
490 ; CHECK-NEXT:    lsr z0.b, p0/m, z0.b, z1.b
491 ; CHECK-NEXT:    st1b { z0.b }, p0, [x0]
492 ; CHECK-NEXT:    ret
493   %op1 = load <128 x i8>, ptr %a
494   %op2 = load <128 x i8>, ptr %b
495   %res = lshr <128 x i8> %op1, %op2
496   store <128 x i8> %res, ptr %a
497   ret void
500 define void @lshr_v256i8(ptr %a, ptr %b) vscale_range(16,0) #0 {
501 ; CHECK-LABEL: lshr_v256i8:
502 ; CHECK:       // %bb.0:
503 ; CHECK-NEXT:    ptrue p0.b, vl256
504 ; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]
505 ; CHECK-NEXT:    ld1b { z1.b }, p0/z, [x1]
506 ; CHECK-NEXT:    lsr z0.b, p0/m, z0.b, z1.b
507 ; CHECK-NEXT:    st1b { z0.b }, p0, [x0]
508 ; CHECK-NEXT:    ret
509   %op1 = load <256 x i8>, ptr %a
510   %op2 = load <256 x i8>, ptr %b
511   %res = lshr <256 x i8> %op1, %op2
512   store <256 x i8> %res, ptr %a
513   ret void
516 ; Don't use SVE for 64-bit vectors.
517 define <4 x i16> @lshr_v4i16(<4 x i16> %op1, <4 x i16> %op2) vscale_range(2,0) #0 {
518 ; CHECK-LABEL: lshr_v4i16:
519 ; CHECK:       // %bb.0:
520 ; CHECK-NEXT:    neg v1.4h, v1.4h
521 ; CHECK-NEXT:    ushl v0.4h, v0.4h, v1.4h
522 ; CHECK-NEXT:    ret
523   %res = lshr <4 x i16> %op1, %op2
524   ret <4 x i16> %res
527 ; Don't use SVE for 128-bit vectors.
528 define <8 x i16> @lshr_v8i16(<8 x i16> %op1, <8 x i16> %op2) vscale_range(2,0) #0 {
529 ; CHECK-LABEL: lshr_v8i16:
530 ; CHECK:       // %bb.0:
531 ; CHECK-NEXT:    neg v1.8h, v1.8h
532 ; CHECK-NEXT:    ushl v0.8h, v0.8h, v1.8h
533 ; CHECK-NEXT:    ret
534   %res = lshr <8 x i16> %op1, %op2
535   ret <8 x i16> %res
538 define void @lshr_v16i16(ptr %a, ptr %b) vscale_range(2,0) #0 {
539 ; CHECK-LABEL: lshr_v16i16:
540 ; CHECK:       // %bb.0:
541 ; CHECK-NEXT:    ptrue p0.h, vl16
542 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]
543 ; CHECK-NEXT:    ld1h { z1.h }, p0/z, [x1]
544 ; CHECK-NEXT:    lsr z0.h, p0/m, z0.h, z1.h
545 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
546 ; CHECK-NEXT:    ret
547   %op1 = load <16 x i16>, ptr %a
548   %op2 = load <16 x i16>, ptr %b
549   %res = lshr <16 x i16> %op1, %op2
550   store <16 x i16> %res, ptr %a
551   ret void
554 define void @lshr_v32i16(ptr %a, ptr %b) #0 {
555 ; VBITS_GE_256-LABEL: lshr_v32i16:
556 ; VBITS_GE_256:       // %bb.0:
557 ; VBITS_GE_256-NEXT:    ptrue p0.h, vl16
558 ; VBITS_GE_256-NEXT:    mov x8, #16 // =0x10
559 ; VBITS_GE_256-NEXT:    ld1h { z0.h }, p0/z, [x0, x8, lsl #1]
560 ; VBITS_GE_256-NEXT:    ld1h { z1.h }, p0/z, [x0]
561 ; VBITS_GE_256-NEXT:    ld1h { z2.h }, p0/z, [x1, x8, lsl #1]
562 ; VBITS_GE_256-NEXT:    ld1h { z3.h }, p0/z, [x1]
563 ; VBITS_GE_256-NEXT:    lsr z0.h, p0/m, z0.h, z2.h
564 ; VBITS_GE_256-NEXT:    lsr z1.h, p0/m, z1.h, z3.h
565 ; VBITS_GE_256-NEXT:    st1h { z0.h }, p0, [x0, x8, lsl #1]
566 ; VBITS_GE_256-NEXT:    st1h { z1.h }, p0, [x0]
567 ; VBITS_GE_256-NEXT:    ret
569 ; VBITS_GE_512-LABEL: lshr_v32i16:
570 ; VBITS_GE_512:       // %bb.0:
571 ; VBITS_GE_512-NEXT:    ptrue p0.h, vl32
572 ; VBITS_GE_512-NEXT:    ld1h { z0.h }, p0/z, [x0]
573 ; VBITS_GE_512-NEXT:    ld1h { z1.h }, p0/z, [x1]
574 ; VBITS_GE_512-NEXT:    lsr z0.h, p0/m, z0.h, z1.h
575 ; VBITS_GE_512-NEXT:    st1h { z0.h }, p0, [x0]
576 ; VBITS_GE_512-NEXT:    ret
577   %op1 = load <32 x i16>, ptr %a
578   %op2 = load <32 x i16>, ptr %b
579   %res = lshr <32 x i16> %op1, %op2
580   store <32 x i16> %res, ptr %a
581   ret void
584 define void @lshr_v64i16(ptr %a, ptr %b) vscale_range(8,0) #0 {
585 ; CHECK-LABEL: lshr_v64i16:
586 ; CHECK:       // %bb.0:
587 ; CHECK-NEXT:    ptrue p0.h, vl64
588 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]
589 ; CHECK-NEXT:    ld1h { z1.h }, p0/z, [x1]
590 ; CHECK-NEXT:    lsr z0.h, p0/m, z0.h, z1.h
591 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
592 ; CHECK-NEXT:    ret
593   %op1 = load <64 x i16>, ptr %a
594   %op2 = load <64 x i16>, ptr %b
595   %res = lshr <64 x i16> %op1, %op2
596   store <64 x i16> %res, ptr %a
597   ret void
600 define void @lshr_v128i16(ptr %a, ptr %b) vscale_range(16,0) #0 {
601 ; CHECK-LABEL: lshr_v128i16:
602 ; CHECK:       // %bb.0:
603 ; CHECK-NEXT:    ptrue p0.h, vl128
604 ; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]
605 ; CHECK-NEXT:    ld1h { z1.h }, p0/z, [x1]
606 ; CHECK-NEXT:    lsr z0.h, p0/m, z0.h, z1.h
607 ; CHECK-NEXT:    st1h { z0.h }, p0, [x0]
608 ; CHECK-NEXT:    ret
609   %op1 = load <128 x i16>, ptr %a
610   %op2 = load <128 x i16>, ptr %b
611   %res = lshr <128 x i16> %op1, %op2
612   store <128 x i16> %res, ptr %a
613   ret void
616 ; Don't use SVE for 64-bit vectors.
617 define <2 x i32> @lshr_v2i32(<2 x i32> %op1, <2 x i32> %op2) vscale_range(2,0) #0 {
618 ; CHECK-LABEL: lshr_v2i32:
619 ; CHECK:       // %bb.0:
620 ; CHECK-NEXT:    neg v1.2s, v1.2s
621 ; CHECK-NEXT:    ushl v0.2s, v0.2s, v1.2s
622 ; CHECK-NEXT:    ret
623   %res = lshr <2 x i32> %op1, %op2
624   ret <2 x i32> %res
627 ; Don't use SVE for 128-bit vectors.
628 define <4 x i32> @lshr_v4i32(<4 x i32> %op1, <4 x i32> %op2) vscale_range(2,0) #0 {
629 ; CHECK-LABEL: lshr_v4i32:
630 ; CHECK:       // %bb.0:
631 ; CHECK-NEXT:    neg v1.4s, v1.4s
632 ; CHECK-NEXT:    ushl v0.4s, v0.4s, v1.4s
633 ; CHECK-NEXT:    ret
634   %res = lshr <4 x i32> %op1, %op2
635   ret <4 x i32> %res
638 define void @lshr_v8i32(ptr %a, ptr %b) vscale_range(2,0) #0 {
639 ; CHECK-LABEL: lshr_v8i32:
640 ; CHECK:       // %bb.0:
641 ; CHECK-NEXT:    ptrue p0.s, vl8
642 ; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0]
643 ; CHECK-NEXT:    ld1w { z1.s }, p0/z, [x1]
644 ; CHECK-NEXT:    lsr z0.s, p0/m, z0.s, z1.s
645 ; CHECK-NEXT:    st1w { z0.s }, p0, [x0]
646 ; CHECK-NEXT:    ret
647   %op1 = load <8 x i32>, ptr %a
648   %op2 = load <8 x i32>, ptr %b
649   %res = lshr <8 x i32> %op1, %op2
650   store <8 x i32> %res, ptr %a
651   ret void
654 define void @lshr_v16i32(ptr %a, ptr %b) #0 {
655 ; VBITS_GE_256-LABEL: lshr_v16i32:
656 ; VBITS_GE_256:       // %bb.0:
657 ; VBITS_GE_256-NEXT:    ptrue p0.s, vl8
658 ; VBITS_GE_256-NEXT:    mov x8, #8 // =0x8
659 ; VBITS_GE_256-NEXT:    ld1w { z0.s }, p0/z, [x0, x8, lsl #2]
660 ; VBITS_GE_256-NEXT:    ld1w { z1.s }, p0/z, [x0]
661 ; VBITS_GE_256-NEXT:    ld1w { z2.s }, p0/z, [x1, x8, lsl #2]
662 ; VBITS_GE_256-NEXT:    ld1w { z3.s }, p0/z, [x1]
663 ; VBITS_GE_256-NEXT:    lsr z0.s, p0/m, z0.s, z2.s
664 ; VBITS_GE_256-NEXT:    lsr z1.s, p0/m, z1.s, z3.s
665 ; VBITS_GE_256-NEXT:    st1w { z0.s }, p0, [x0, x8, lsl #2]
666 ; VBITS_GE_256-NEXT:    st1w { z1.s }, p0, [x0]
667 ; VBITS_GE_256-NEXT:    ret
669 ; VBITS_GE_512-LABEL: lshr_v16i32:
670 ; VBITS_GE_512:       // %bb.0:
671 ; VBITS_GE_512-NEXT:    ptrue p0.s, vl16
672 ; VBITS_GE_512-NEXT:    ld1w { z0.s }, p0/z, [x0]
673 ; VBITS_GE_512-NEXT:    ld1w { z1.s }, p0/z, [x1]
674 ; VBITS_GE_512-NEXT:    lsr z0.s, p0/m, z0.s, z1.s
675 ; VBITS_GE_512-NEXT:    st1w { z0.s }, p0, [x0]
676 ; VBITS_GE_512-NEXT:    ret
677   %op1 = load <16 x i32>, ptr %a
678   %op2 = load <16 x i32>, ptr %b
679   %res = lshr <16 x i32> %op1, %op2
680   store <16 x i32> %res, ptr %a
681   ret void
684 define void @lshr_v32i32(ptr %a, ptr %b) vscale_range(8,0) #0 {
685 ; CHECK-LABEL: lshr_v32i32:
686 ; CHECK:       // %bb.0:
687 ; CHECK-NEXT:    ptrue p0.s, vl32
688 ; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0]
689 ; CHECK-NEXT:    ld1w { z1.s }, p0/z, [x1]
690 ; CHECK-NEXT:    lsr z0.s, p0/m, z0.s, z1.s
691 ; CHECK-NEXT:    st1w { z0.s }, p0, [x0]
692 ; CHECK-NEXT:    ret
693   %op1 = load <32 x i32>, ptr %a
694   %op2 = load <32 x i32>, ptr %b
695   %res = lshr <32 x i32> %op1, %op2
696   store <32 x i32> %res, ptr %a
697   ret void
700 define void @lshr_v64i32(ptr %a, ptr %b) vscale_range(16,0) #0 {
701 ; CHECK-LABEL: lshr_v64i32:
702 ; CHECK:       // %bb.0:
703 ; CHECK-NEXT:    ptrue p0.s, vl64
704 ; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0]
705 ; CHECK-NEXT:    ld1w { z1.s }, p0/z, [x1]
706 ; CHECK-NEXT:    lsr z0.s, p0/m, z0.s, z1.s
707 ; CHECK-NEXT:    st1w { z0.s }, p0, [x0]
708 ; CHECK-NEXT:    ret
709   %op1 = load <64 x i32>, ptr %a
710   %op2 = load <64 x i32>, ptr %b
711   %res = lshr <64 x i32> %op1, %op2
712   store <64 x i32> %res, ptr %a
713   ret void
716 ; Don't use SVE for 64-bit vectors.
717 define <1 x i64> @lshr_v1i64(<1 x i64> %op1, <1 x i64> %op2) vscale_range(2,0) #0 {
718 ; CHECK-LABEL: lshr_v1i64:
719 ; CHECK:       // %bb.0:
720 ; CHECK-NEXT:    neg d1, d1
721 ; CHECK-NEXT:    ushl d0, d0, d1
722 ; CHECK-NEXT:    ret
723   %res = lshr <1 x i64> %op1, %op2
724   ret <1 x i64> %res
727 ; Don't use SVE for 128-bit vectors.
728 define <2 x i64> @lshr_v2i64(<2 x i64> %op1, <2 x i64> %op2) vscale_range(2,0) #0 {
729 ; CHECK-LABEL: lshr_v2i64:
730 ; CHECK:       // %bb.0:
731 ; CHECK-NEXT:    neg v1.2d, v1.2d
732 ; CHECK-NEXT:    ushl v0.2d, v0.2d, v1.2d
733 ; CHECK-NEXT:    ret
734   %res = lshr <2 x i64> %op1, %op2
735   ret <2 x i64> %res
738 define void @lshr_v4i64(ptr %a, ptr %b) vscale_range(2,0) #0 {
739 ; CHECK-LABEL: lshr_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:    lsr 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 = lshr <4 x i64> %op1, %op2
750   store <4 x i64> %res, ptr %a
751   ret void
754 define void @lshr_v8i64(ptr %a, ptr %b) #0 {
755 ; VBITS_GE_256-LABEL: lshr_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:    lsr z0.d, p0/m, z0.d, z2.d
764 ; VBITS_GE_256-NEXT:    lsr 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: lshr_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:    lsr 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 = lshr <8 x i64> %op1, %op2
780   store <8 x i64> %res, ptr %a
781   ret void
784 define void @lshr_v16i64(ptr %a, ptr %b) vscale_range(8,0) #0 {
785 ; CHECK-LABEL: lshr_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:    lsr 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 = lshr <16 x i64> %op1, %op2
796   store <16 x i64> %res, ptr %a
797   ret void
800 define void @lshr_v32i64(ptr %a, ptr %b) vscale_range(16,0) #0 {
801 ; CHECK-LABEL: lshr_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:    lsr 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 = lshr <32 x i64> %op1, %op2
812   store <32 x i64> %res, ptr %a
813   ret void
817 ; SHL
820 ; Don't use SVE for 64-bit vectors.
821 define <8 x i8> @shl_v8i8(<8 x i8> %op1, <8 x i8> %op2) vscale_range(2,0) #0 {
822 ; CHECK-LABEL: shl_v8i8:
823 ; CHECK:       // %bb.0:
824 ; CHECK-NEXT:    ushl v0.8b, v0.8b, v1.8b
825 ; CHECK-NEXT:    ret
826   %res = shl <8 x i8> %op1, %op2
827   ret <8 x i8> %res
830 ; Don't use SVE for 128-bit vectors.
831 define <16 x i8> @shl_v16i8(<16 x i8> %op1, <16 x i8> %op2) vscale_range(2,0) #0 {
832 ; CHECK-LABEL: shl_v16i8:
833 ; CHECK:       // %bb.0:
834 ; CHECK-NEXT:    ushl v0.16b, v0.16b, v1.16b
835 ; CHECK-NEXT:    ret
836   %res = shl <16 x i8> %op1, %op2
837   ret <16 x i8> %res
840 define void @shl_v32i8(ptr %a, ptr %b) vscale_range(2,0) #0 {
841 ; CHECK-LABEL: shl_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:    lsl 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 = shl <32 x i8> %op1, %op2
852   store <32 x i8> %res, ptr %a
853   ret void
856 define void @shl_v64i8(ptr %a, ptr %b) #0 {
857 ; VBITS_GE_256-LABEL: shl_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:    lsl z0.b, p0/m, z0.b, z2.b
866 ; VBITS_GE_256-NEXT:    lsl 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: shl_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:    lsl 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 = shl <64 x i8> %op1, %op2
882   store <64 x i8> %res, ptr %a
883   ret void
886 define void @shl_v128i8(ptr %a, ptr %b) vscale_range(8,0) #0 {
887 ; CHECK-LABEL: shl_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:    lsl 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 = shl <128 x i8> %op1, %op2
898   store <128 x i8> %res, ptr %a
899   ret void
902 define void @shl_v256i8(ptr %a, ptr %b) vscale_range(16,0) #0 {
903 ; CHECK-LABEL: shl_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:    lsl 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 = shl <256 x i8> %op1, %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> @shl_v4i16(<4 x i16> %op1, <4 x i16> %op2) vscale_range(2,0) #0 {
920 ; CHECK-LABEL: shl_v4i16:
921 ; CHECK:       // %bb.0:
922 ; CHECK-NEXT:    ushl v0.4h, v0.4h, v1.4h
923 ; CHECK-NEXT:    ret
924   %res = shl <4 x i16> %op1, %op2
925   ret <4 x i16> %res
928 ; Don't use SVE for 128-bit vectors.
929 define <8 x i16> @shl_v8i16(<8 x i16> %op1, <8 x i16> %op2) vscale_range(2,0) #0 {
930 ; CHECK-LABEL: shl_v8i16:
931 ; CHECK:       // %bb.0:
932 ; CHECK-NEXT:    ushl v0.8h, v0.8h, v1.8h
933 ; CHECK-NEXT:    ret
934   %res = shl <8 x i16> %op1, %op2
935   ret <8 x i16> %res
938 define void @shl_v16i16(ptr %a, ptr %b) vscale_range(2,0) #0 {
939 ; CHECK-LABEL: shl_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:    lsl 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 = shl <16 x i16> %op1, %op2
950   store <16 x i16> %res, ptr %a
951   ret void
954 define void @shl_v32i16(ptr %a, ptr %b) #0 {
955 ; VBITS_GE_256-LABEL: shl_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:    lsl z0.h, p0/m, z0.h, z2.h
964 ; VBITS_GE_256-NEXT:    lsl 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: shl_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:    lsl 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 = shl <32 x i16> %op1, %op2
980   store <32 x i16> %res, ptr %a
981   ret void
984 define void @shl_v64i16(ptr %a, ptr %b) vscale_range(8,0) #0 {
985 ; CHECK-LABEL: shl_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:    lsl 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 = shl <64 x i16> %op1, %op2
996   store <64 x i16> %res, ptr %a
997   ret void
1000 define void @shl_v128i16(ptr %a, ptr %b) vscale_range(16,0) #0 {
1001 ; CHECK-LABEL: shl_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:    lsl 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 = shl <128 x i16> %op1, %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> @shl_v2i32(<2 x i32> %op1, <2 x i32> %op2) vscale_range(2,0) #0 {
1018 ; CHECK-LABEL: shl_v2i32:
1019 ; CHECK:       // %bb.0:
1020 ; CHECK-NEXT:    ushl v0.2s, v0.2s, v1.2s
1021 ; CHECK-NEXT:    ret
1022   %res = shl <2 x i32> %op1, %op2
1023   ret <2 x i32> %res
1026 ; Don't use SVE for 128-bit vectors.
1027 define <4 x i32> @shl_v4i32(<4 x i32> %op1, <4 x i32> %op2) vscale_range(2,0) #0 {
1028 ; CHECK-LABEL: shl_v4i32:
1029 ; CHECK:       // %bb.0:
1030 ; CHECK-NEXT:    ushl v0.4s, v0.4s, v1.4s
1031 ; CHECK-NEXT:    ret
1032   %res = shl <4 x i32> %op1, %op2
1033   ret <4 x i32> %res
1036 define void @shl_v8i32(ptr %a, ptr %b) vscale_range(2,0) #0 {
1037 ; CHECK-LABEL: shl_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:    lsl 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 = shl <8 x i32> %op1, %op2
1048   store <8 x i32> %res, ptr %a
1049   ret void
1052 define void @shl_v16i32(ptr %a, ptr %b) #0 {
1053 ; VBITS_GE_256-LABEL: shl_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:    lsl z0.s, p0/m, z0.s, z2.s
1062 ; VBITS_GE_256-NEXT:    lsl 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: shl_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:    lsl 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 = shl <16 x i32> %op1, %op2
1078   store <16 x i32> %res, ptr %a
1079   ret void
1082 define void @shl_v32i32(ptr %a, ptr %b) vscale_range(8,0) #0 {
1083 ; CHECK-LABEL: shl_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:    lsl 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 = shl <32 x i32> %op1, %op2
1094   store <32 x i32> %res, ptr %a
1095   ret void
1098 define void @shl_v64i32(ptr %a, ptr %b) vscale_range(16,0) #0 {
1099 ; CHECK-LABEL: shl_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:    lsl 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 = shl <64 x i32> %op1, %op2
1110   store <64 x i32> %res, ptr %a
1111   ret void
1114 ; Don't use SVE for 64-bit vectors.
1115 define <1 x i64> @shl_v1i64(<1 x i64> %op1, <1 x i64> %op2) vscale_range(2,0) #0 {
1116 ; CHECK-LABEL: shl_v1i64:
1117 ; CHECK:       // %bb.0:
1118 ; CHECK-NEXT:    ushl d0, d0, d1
1119 ; CHECK-NEXT:    ret
1120   %res = shl <1 x i64> %op1, %op2
1121   ret <1 x i64> %res
1124 ; Don't use SVE for 128-bit vectors.
1125 define <2 x i64> @shl_v2i64(<2 x i64> %op1, <2 x i64> %op2) vscale_range(2,0) #0 {
1126 ; CHECK-LABEL: shl_v2i64:
1127 ; CHECK:       // %bb.0:
1128 ; CHECK-NEXT:    ushl v0.2d, v0.2d, v1.2d
1129 ; CHECK-NEXT:    ret
1130   %res = shl <2 x i64> %op1, %op2
1131   ret <2 x i64> %res
1134 define void @shl_v4i64(ptr %a, ptr %b) vscale_range(2,0) #0 {
1135 ; CHECK-LABEL: shl_v4i64:
1136 ; CHECK:       // %bb.0:
1137 ; CHECK-NEXT:    ptrue p0.d, vl4
1138 ; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0]
1139 ; CHECK-NEXT:    ld1d { z1.d }, p0/z, [x1]
1140 ; CHECK-NEXT:    lsl z0.d, p0/m, z0.d, z1.d
1141 ; CHECK-NEXT:    st1d { z0.d }, p0, [x0]
1142 ; CHECK-NEXT:    ret
1143   %op1 = load <4 x i64>, ptr %a
1144   %op2 = load <4 x i64>, ptr %b
1145   %res = shl <4 x i64> %op1, %op2
1146   store <4 x i64> %res, ptr %a
1147   ret void
1150 define void @shl_v8i64(ptr %a, ptr %b) #0 {
1151 ; VBITS_GE_256-LABEL: shl_v8i64:
1152 ; VBITS_GE_256:       // %bb.0:
1153 ; VBITS_GE_256-NEXT:    ptrue p0.d, vl4
1154 ; VBITS_GE_256-NEXT:    mov x8, #4 // =0x4
1155 ; VBITS_GE_256-NEXT:    ld1d { z0.d }, p0/z, [x0, x8, lsl #3]
1156 ; VBITS_GE_256-NEXT:    ld1d { z1.d }, p0/z, [x0]
1157 ; VBITS_GE_256-NEXT:    ld1d { z2.d }, p0/z, [x1, x8, lsl #3]
1158 ; VBITS_GE_256-NEXT:    ld1d { z3.d }, p0/z, [x1]
1159 ; VBITS_GE_256-NEXT:    lsl z0.d, p0/m, z0.d, z2.d
1160 ; VBITS_GE_256-NEXT:    lsl z1.d, p0/m, z1.d, z3.d
1161 ; VBITS_GE_256-NEXT:    st1d { z0.d }, p0, [x0, x8, lsl #3]
1162 ; VBITS_GE_256-NEXT:    st1d { z1.d }, p0, [x0]
1163 ; VBITS_GE_256-NEXT:    ret
1165 ; VBITS_GE_512-LABEL: shl_v8i64:
1166 ; VBITS_GE_512:       // %bb.0:
1167 ; VBITS_GE_512-NEXT:    ptrue p0.d, vl8
1168 ; VBITS_GE_512-NEXT:    ld1d { z0.d }, p0/z, [x0]
1169 ; VBITS_GE_512-NEXT:    ld1d { z1.d }, p0/z, [x1]
1170 ; VBITS_GE_512-NEXT:    lsl z0.d, p0/m, z0.d, z1.d
1171 ; VBITS_GE_512-NEXT:    st1d { z0.d }, p0, [x0]
1172 ; VBITS_GE_512-NEXT:    ret
1173   %op1 = load <8 x i64>, ptr %a
1174   %op2 = load <8 x i64>, ptr %b
1175   %res = shl <8 x i64> %op1, %op2
1176   store <8 x i64> %res, ptr %a
1177   ret void
1180 define void @shl_v16i64(ptr %a, ptr %b) vscale_range(8,0) #0 {
1181 ; CHECK-LABEL: shl_v16i64:
1182 ; CHECK:       // %bb.0:
1183 ; CHECK-NEXT:    ptrue p0.d, vl16
1184 ; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0]
1185 ; CHECK-NEXT:    ld1d { z1.d }, p0/z, [x1]
1186 ; CHECK-NEXT:    lsl z0.d, p0/m, z0.d, z1.d
1187 ; CHECK-NEXT:    st1d { z0.d }, p0, [x0]
1188 ; CHECK-NEXT:    ret
1189   %op1 = load <16 x i64>, ptr %a
1190   %op2 = load <16 x i64>, ptr %b
1191   %res = shl <16 x i64> %op1, %op2
1192   store <16 x i64> %res, ptr %a
1193   ret void
1196 define void @shl_v32i64(ptr %a, ptr %b) vscale_range(16,0) #0 {
1197 ; CHECK-LABEL: shl_v32i64:
1198 ; CHECK:       // %bb.0:
1199 ; CHECK-NEXT:    ptrue p0.d, vl32
1200 ; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0]
1201 ; CHECK-NEXT:    ld1d { z1.d }, p0/z, [x1]
1202 ; CHECK-NEXT:    lsl z0.d, p0/m, z0.d, z1.d
1203 ; CHECK-NEXT:    st1d { z0.d }, p0, [x0]
1204 ; CHECK-NEXT:    ret
1205   %op1 = load <32 x i64>, ptr %a
1206   %op2 = load <32 x i64>, ptr %b
1207   %res = shl <32 x i64> %op1, %op2
1208   store <32 x i64> %res, ptr %a
1209   ret void
1212 attributes #0 = { "target-features"="+sve" }