1 ; RUN: llc -aarch64-sve-vector-bits-min=128 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefix=NO_SVE
2 ; RUN: llc -aarch64-sve-vector-bits-min=256 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK
3 ; RUN: llc -aarch64-sve-vector-bits-min=384 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK
4 ; RUN: llc -aarch64-sve-vector-bits-min=512 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512
5 ; RUN: llc -aarch64-sve-vector-bits-min=640 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512
6 ; RUN: llc -aarch64-sve-vector-bits-min=768 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512
7 ; RUN: llc -aarch64-sve-vector-bits-min=896 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512
8 ; RUN: llc -aarch64-sve-vector-bits-min=1024 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
9 ; RUN: llc -aarch64-sve-vector-bits-min=1152 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
10 ; RUN: llc -aarch64-sve-vector-bits-min=1280 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
11 ; RUN: llc -aarch64-sve-vector-bits-min=1408 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
12 ; RUN: llc -aarch64-sve-vector-bits-min=1536 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
13 ; RUN: llc -aarch64-sve-vector-bits-min=1664 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
14 ; RUN: llc -aarch64-sve-vector-bits-min=1792 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
15 ; RUN: llc -aarch64-sve-vector-bits-min=1920 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
16 ; RUN: llc -aarch64-sve-vector-bits-min=2048 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024,VBITS_GE_2048
18 ; Test we can code generater patterns of the form:
19 ; fixed_length_vector = ISD::EXTRACT_SUBVECTOR scalable_vector, 0
20 ; scalable_vector = ISD::INSERT_SUBVECTOR scalable_vector, fixed_length_vector, 0
22 ; NOTE: Currently shufflevector does not support scalable vectors so it cannot
23 ; be used to model the above operations. Instead these tests rely on knowing
24 ; how fixed length operation are lowered to scalable ones, with multiple blocks
25 ; ensuring insert/extract sequences are not folded away.
27 target triple = "aarch64-unknown-linux-gnu"
29 ; Don't use SVE when its registers are no bigger than NEON.
32 define void @subvector_v8i16(<8 x i16> *%in, <8 x i16>* %out) #0 {
33 ; CHECK-LABEL: subvector_v8i16:
34 ; CHECK: ldr [[DATA:q[0-9]+]], [x0]
35 ; CHECK: str [[DATA]], [x1]
37 %a = load <8 x i16>, <8 x i16>* %in
41 store <8 x i16> %a, <8 x i16>* %out
45 define void @subvector_v16i16(<16 x i16> *%in, <16 x i16>* %out) #0 {
46 ; CHECK-LABEL: subvector_v16i16:
47 ; CHECK: ptrue [[PG:p[0-9]+]].h, vl16
48 ; CHECK: ld1h { [[DATA:z[0-9]+.h]] }, [[PG]]/z, [x0]
49 ; CHECK: st1h { [[DATA]] }, [[PG]], [x1]
51 %a = load <16 x i16>, <16 x i16>* %in
55 store <16 x i16> %a, <16 x i16>* %out
59 define void @subvector_v32i16(<32 x i16> *%in, <32 x i16>* %out) #0 {
60 ; CHECK-LABEL: subvector_v32i16:
61 ; VBITS_GE_512: ptrue [[PG:p[0-9]+]].h, vl32
62 ; VBITS_GE_512: ld1h { [[DATA:z[0-9]+.h]] }, [[PG]]/z, [x0]
63 ; VBITS_GE_512: st1h { [[DATA]] }, [[PG]], [x1]
65 %a = load <32 x i16>, <32 x i16>* %in
69 store <32 x i16> %a, <32 x i16>* %out
73 define void @subvector_v64i16(<64 x i16> *%in, <64 x i16>* %out) #0 {
74 ; CHECK-LABEL: subvector_v64i16:
75 ; VBITS_GE_1024: ptrue [[PG:p[0-9]+]].h, vl64
76 ; VBITS_GE_1024: ld1h { [[DATA:z[0-9]+.h]] }, [[PG]]/z, [x0]
77 ; VBITS_GE_1024: st1h { [[DATA]] }, [[PG]], [x1]
79 %a = load <64 x i16>, <64 x i16>* %in
83 store <64 x i16> %a, <64 x i16>* %out
87 define void @subvector_v8i32(<8 x i32> *%in, <8 x i32>* %out) #0 {
88 ; CHECK-LABEL: subvector_v8i32:
89 ; CHECK: ptrue [[PG:p[0-9]+]].s, vl8
90 ; CHECK: ld1w { [[DATA:z[0-9]+.s]] }, [[PG]]/z, [x0]
91 ; CHECK: st1w { [[DATA]] }, [[PG]], [x1]
93 %a = load <8 x i32>, <8 x i32>* %in
97 store <8 x i32> %a, <8 x i32>* %out
101 define void @subvector_v16i32(<16 x i32> *%in, <16 x i32>* %out) #0 {
102 ; CHECK-LABEL: subvector_v16i32:
103 ; VBITS_GE_512: ptrue [[PG:p[0-9]+]].s, vl16
104 ; VBITS_GE_512: ld1w { [[DATA:z[0-9]+.s]] }, [[PG]]/z, [x0]
105 ; VBITS_GE_512: st1w { [[DATA]] }, [[PG]], [x1]
107 %a = load <16 x i32>, <16 x i32>* %in
111 store <16 x i32> %a, <16 x i32>* %out
115 define void @subvector_v32i32(<32 x i32> *%in, <32 x i32>* %out) #0 {
116 ; CHECK-LABEL: subvector_v32i32:
117 ; VBITS_GE_1024: ptrue [[PG:p[0-9]+]].s, vl32
118 ; VBITS_GE_1024: ld1w { [[DATA:z[0-9]+.s]] }, [[PG]]/z, [x0]
119 ; VBITS_GE_1024: st1w { [[DATA]] }, [[PG]], [x1]
121 %a = load <32 x i32>, <32 x i32>* %in
125 store <32 x i32> %a, <32 x i32>* %out
129 define void @subvector_v64i32(<64 x i32> *%in, <64 x i32>* %out) #0 {
130 ; CHECK-LABEL: subvector_v64i32:
131 ; VBITS_GE_2048: ptrue [[PG:p[0-9]+]].s, vl64
132 ; VBITS_GE_2048: ld1w { [[DATA:z[0-9]+.s]] }, [[PG]]/z, [x0]
133 ; VBITS_GE_2048: st1w { [[DATA]] }, [[PG]], [x1]
135 %a = load <64 x i32>, <64 x i32>* %in
139 store <64 x i32> %a, <64 x i32>* %out
144 define void @subvector_v8i64(<8 x i64> *%in, <8 x i64>* %out) #0 {
145 ; CHECK-LABEL: subvector_v8i64:
146 ; VBITS_GE_512: ptrue [[PG:p[0-9]+]].d, vl8
147 ; VBITS_GE_512: ld1d { [[DATA:z[0-9]+.d]] }, [[PG]]/z, [x0]
148 ; VBITS_GE_512: st1d { [[DATA]] }, [[PG]], [x1]
150 %a = load <8 x i64>, <8 x i64>* %in
154 store <8 x i64> %a, <8 x i64>* %out
158 define void @subvector_v16i64(<16 x i64> *%in, <16 x i64>* %out) #0 {
159 ; CHECK-LABEL: subvector_v16i64:
160 ; VBITS_GE_1024: ptrue [[PG:p[0-9]+]].d, vl16
161 ; VBITS_GE_1024: ld1d { [[DATA:z[0-9]+.d]] }, [[PG]]/z, [x0]
162 ; VBITS_GE_1024: st1d { [[DATA]] }, [[PG]], [x1]
164 %a = load <16 x i64>, <16 x i64>* %in
168 store <16 x i64> %a, <16 x i64>* %out
172 define void @subvector_v32i64(<32 x i64> *%in, <32 x i64>* %out) #0 {
173 ; CHECK-LABEL: subvector_v32i64:
174 ; VBITS_GE_2048: ptrue [[PG:p[0-9]+]].d, vl32
175 ; VBITS_GE_2048: ld1d { [[DATA:z[0-9]+.d]] }, [[PG]]/z, [x0]
176 ; VBITS_GE_2048: st1d { [[DATA]] }, [[PG]], [x1]
178 %a = load <32 x i64>, <32 x i64>* %in
182 store <32 x i64> %a, <32 x i64>* %out
186 define void @subvector_v8f16(<8 x half> *%in, <8 x half>* %out) #0 {
187 ; CHECK-LABEL: subvector_v8f16:
188 ; CHECK: ldr [[DATA:q[0-9]+]], [x0]
189 ; CHECK: str [[DATA]], [x1]
191 %a = load <8 x half>, <8 x half>* %in
195 store <8 x half> %a, <8 x half>* %out
199 define void @subvector_v16f16(<16 x half> *%in, <16 x half>* %out) #0 {
200 ; CHECK-LABEL: subvector_v16f16:
201 ; CHECK: ptrue [[PG:p[0-9]+]].h, vl16
202 ; CHECK: ld1h { [[DATA:z[0-9]+.h]] }, [[PG]]/z, [x0]
203 ; CHECK: st1h { [[DATA]] }, [[PG]], [x1]
205 %a = load <16 x half>, <16 x half>* %in
209 store <16 x half> %a, <16 x half>* %out
213 define void @subvector_v32f16(<32 x half> *%in, <32 x half>* %out) #0 {
214 ; CHECK-LABEL: subvector_v32f16:
215 ; VBITS_GE_512: ptrue [[PG:p[0-9]+]].h, vl32
216 ; VBITS_GE_512: ld1h { [[DATA:z[0-9]+.h]] }, [[PG]]/z, [x0]
217 ; VBITS_GE_512: st1h { [[DATA]] }, [[PG]], [x1]
219 %a = load <32 x half>, <32 x half>* %in
223 store <32 x half> %a, <32 x half>* %out
227 define void @subvector_v64f16(<64 x half> *%in, <64 x half>* %out) #0 {
228 ; CHECK-LABEL: subvector_v64f16:
229 ; VBITS_GE_1024: ptrue [[PG:p[0-9]+]].h, vl64
230 ; VBITS_GE_1024: ld1h { [[DATA:z[0-9]+.h]] }, [[PG]]/z, [x0]
231 ; VBITS_GE_1024: st1h { [[DATA]] }, [[PG]], [x1]
233 %a = load <64 x half>, <64 x half>* %in
237 store <64 x half> %a, <64 x half>* %out
241 define void @subvector_v8f32(<8 x float> *%in, <8 x float>* %out) #0 {
242 ; CHECK-LABEL: subvector_v8f32:
243 ; CHECK: ptrue [[PG:p[0-9]+]].s, vl8
244 ; CHECK: ld1w { [[DATA:z[0-9]+.s]] }, [[PG]]/z, [x0]
245 ; CHECK: st1w { [[DATA]] }, [[PG]], [x1]
247 %a = load <8 x float>, <8 x float>* %in
251 store <8 x float> %a, <8 x float>* %out
255 define void @subvector_v16f32(<16 x float> *%in, <16 x float>* %out) #0 {
256 ; CHECK-LABEL: subvector_v16f32:
257 ; VBITS_GE_512: ptrue [[PG:p[0-9]+]].s, vl16
258 ; VBITS_GE_512: ld1w { [[DATA:z[0-9]+.s]] }, [[PG]]/z, [x0]
259 ; VBITS_GE_512: st1w { [[DATA]] }, [[PG]], [x1]
261 %a = load <16 x float>, <16 x float>* %in
265 store <16 x float> %a, <16 x float>* %out
269 define void @subvector_v32f32(<32 x float> *%in, <32 x float>* %out) #0 {
270 ; CHECK-LABEL: subvector_v32f32:
271 ; VBITS_GE_1024: ptrue [[PG:p[0-9]+]].s, vl32
272 ; VBITS_GE_1024: ld1w { [[DATA:z[0-9]+.s]] }, [[PG]]/z, [x0]
273 ; VBITS_GE_1024: st1w { [[DATA]] }, [[PG]], [x1]
275 %a = load <32 x float>, <32 x float>* %in
279 store <32 x float> %a, <32 x float>* %out
283 define void @subvector_v64f32(<64 x float> *%in, <64 x float>* %out) #0 {
284 ; CHECK-LABEL: subvector_v64f32:
285 ; VBITS_GE_2048: ptrue [[PG:p[0-9]+]].s, vl64
286 ; VBITS_GE_2048: ld1w { [[DATA:z[0-9]+.s]] }, [[PG]]/z, [x0]
287 ; VBITS_GE_2048: st1w { [[DATA]] }, [[PG]], [x1]
289 %a = load <64 x float>, <64 x float>* %in
293 store <64 x float> %a, <64 x float>* %out
296 define void @subvector_v8f64(<8 x double> *%in, <8 x double>* %out) #0 {
297 ; CHECK-LABEL: subvector_v8f64:
298 ; VBITS_GE_512: ptrue [[PG:p[0-9]+]].d, vl8
299 ; VBITS_GE_512: ld1d { [[DATA:z[0-9]+.d]] }, [[PG]]/z, [x0]
300 ; VBITS_GE_512: st1d { [[DATA]] }, [[PG]], [x1]
302 %a = load <8 x double>, <8 x double>* %in
306 store <8 x double> %a, <8 x double>* %out
310 define void @subvector_v16f64(<16 x double> *%in, <16 x double>* %out) #0 {
311 ; CHECK-LABEL: subvector_v16f64:
312 ; VBITS_GE_1024: ptrue [[PG:p[0-9]+]].d, vl16
313 ; VBITS_GE_1024: ld1d { [[DATA:z[0-9]+.d]] }, [[PG]]/z, [x0]
314 ; VBITS_GE_1024: st1d { [[DATA]] }, [[PG]], [x1]
316 %a = load <16 x double>, <16 x double>* %in
320 store <16 x double> %a, <16 x double>* %out
324 define void @subvector_v32f64(<32 x double> *%in, <32 x double>* %out) #0 {
325 ; CHECK-LABEL: subvector_v32f64:
326 ; VBITS_GE_2048: ptrue [[PG:p[0-9]+]].d, vl32
327 ; VBITS_GE_2048: ld1d { [[DATA:z[0-9]+.d]] }, [[PG]]/z, [x0]
328 ; VBITS_GE_2048: st1d { [[DATA]] }, [[PG]], [x1]
330 %a = load <32 x double>, <32 x double>* %in
334 store <32 x double> %a, <32 x double>* %out
338 define <8 x i1> @no_warn_dropped_scalable(<8 x i32>* %in) #0 {
339 ; CHECK-LABEL: no_warn_dropped_scalable:
340 ; CHECK: ptrue [[PG:p[0-9]+]].s, vl8
341 ; CHECK: ld1w { [[A:z[0-9]+]].s }, [[PG]]/z, [x0]
342 ; CHECK: cmpgt p{{[0-9]}}.s, [[PG]]/z, [[A]].s, #0
344 %a = load <8 x i32>, <8 x i32>* %in
348 %cond = icmp sgt <8 x i32> %a, zeroinitializer
352 ; binop(insert_subvec(a), insert_subvec(b)) -> insert_subvec(binop(a,b)) like
353 ; combines remove redundant subvector operations. This test ensures it's not
354 ; performed when the input idiom is the result of operation legalisation. When
355 ; not prevented the test triggers infinite combine->legalise->combine->...
356 define void @no_subvector_binop_hang(<8 x i32>* %in, <8 x i32>* %out, i1 %cond) #0 {
357 ; CHECK-LABEL: no_subvector_binop_hang:
359 ; CHECK-NEXT: ptrue [[PG:p[0-9]+]].s, vl8
360 ; CHECK-NEXT: ld1w { [[A:z[0-9]+]].s }, [[PG]]/z, [x0]
361 ; CHECK-NEXT: ld1w { [[B:z[0-9]+]].s }, [[PG]]/z, [x1]
362 ; CHECK-NEXT: tbz w2, #0, [[LABEL:\.[A-z0-9_]+]]
363 ; CHECK-NEXT: // %bb.1: // %bb.1
364 ; CHECK-NEXT: orr [[OR:z[0-9]+]].d, [[A]].d, [[B]].d
365 ; CHECK-NEXT: st1w { [[OR]].s }, [[PG]], [x1]
366 ; CHECK-NEXT: [[LABEL]]: // %bb.2
368 %a = load <8 x i32>, <8 x i32>* %in
369 %b = load <8 x i32>, <8 x i32>* %out
370 br i1 %cond, label %bb.1, label %bb.2
373 %or = or <8 x i32> %a, %b
374 store <8 x i32> %or, <8 x i32>* %out
381 attributes #0 = { "target-features"="+sve" }