[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / AArch64 / sve-fixed-length-subvector.ll
blob334d0830037cd9f4d4cf6d322a1c0c0efdcf93cb
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.
30 ; NO_SVE-NOT: ptrue
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]
36 ; CHECK: ret
37   %a = load <8 x i16>, <8 x i16>* %in
38   br label %bb1
40 bb1:
41   store <8 x i16> %a, <8 x i16>* %out
42   ret void
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]
50 ; CHECK: ret
51   %a = load <16 x i16>, <16 x i16>* %in
52   br label %bb1
54 bb1:
55   store <16 x i16> %a, <16 x i16>* %out
56   ret void
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]
64 ; CHECK: ret
65   %a = load <32 x i16>, <32 x i16>* %in
66   br label %bb1
68 bb1:
69   store <32 x i16> %a, <32 x i16>* %out
70   ret void
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]
78 ; CHECK: ret
79   %a = load <64 x i16>, <64 x i16>* %in
80   br label %bb1
82 bb1:
83   store <64 x i16> %a, <64 x i16>* %out
84   ret void
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]
92 ; CHECK: ret
93   %a = load <8 x i32>, <8 x i32>* %in
94   br label %bb1
96 bb1:
97   store <8 x i32> %a, <8 x i32>* %out
98   ret void
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]
106 ; CHECK: ret
107   %a = load <16 x i32>, <16 x i32>* %in
108   br label %bb1
110 bb1:
111   store <16 x i32> %a, <16 x i32>* %out
112   ret void
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]
120 ; CHECK: ret
121   %a = load <32 x i32>, <32 x i32>* %in
122   br label %bb1
124 bb1:
125   store <32 x i32> %a, <32 x i32>* %out
126   ret void
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]
134 ; CHECK: ret
135   %a = load <64 x i32>, <64 x i32>* %in
136   br label %bb1
138 bb1:
139   store <64 x i32> %a, <64 x i32>* %out
140   ret void
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]
149 ; CHECK: ret
150   %a = load <8 x i64>, <8 x i64>* %in
151   br label %bb1
153 bb1:
154   store <8 x i64> %a, <8 x i64>* %out
155   ret void
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]
163 ; CHECK: ret
164   %a = load <16 x i64>, <16 x i64>* %in
165   br label %bb1
167 bb1:
168   store <16 x i64> %a, <16 x i64>* %out
169   ret void
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]
177 ; CHECK: ret
178   %a = load <32 x i64>, <32 x i64>* %in
179   br label %bb1
181 bb1:
182   store <32 x i64> %a, <32 x i64>* %out
183   ret void
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]
190 ; CHECK: ret
191   %a = load <8 x half>, <8 x half>* %in
192   br label %bb1
194 bb1:
195   store <8 x half> %a, <8 x half>* %out
196   ret void
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]
204 ; CHECK: ret
205   %a = load <16 x half>, <16 x half>* %in
206   br label %bb1
208 bb1:
209   store <16 x half> %a, <16 x half>* %out
210   ret void
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]
218 ; CHECK: ret
219   %a = load <32 x half>, <32 x half>* %in
220   br label %bb1
222 bb1:
223   store <32 x half> %a, <32 x half>* %out
224   ret void
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]
232 ; CHECK: ret
233   %a = load <64 x half>, <64 x half>* %in
234   br label %bb1
236 bb1:
237   store <64 x half> %a, <64 x half>* %out
238   ret void
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]
246 ; CHECK: ret
247   %a = load <8 x float>, <8 x float>* %in
248   br label %bb1
250 bb1:
251   store <8 x float> %a, <8 x float>* %out
252   ret void
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]
260 ; CHECK: ret
261   %a = load <16 x float>, <16 x float>* %in
262   br label %bb1
264 bb1:
265   store <16 x float> %a, <16 x float>* %out
266   ret void
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]
274 ; CHECK: ret
275   %a = load <32 x float>, <32 x float>* %in
276   br label %bb1
278 bb1:
279   store <32 x float> %a, <32 x float>* %out
280   ret void
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]
288 ; CHECK: ret
289   %a = load <64 x float>, <64 x float>* %in
290   br label %bb1
292 bb1:
293   store <64 x float> %a, <64 x float>* %out
294   ret void
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]
301 ; CHECK: ret
302   %a = load <8 x double>, <8 x double>* %in
303   br label %bb1
305 bb1:
306   store <8 x double> %a, <8 x double>* %out
307   ret void
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]
315 ; CHECK: ret
316   %a = load <16 x double>, <16 x double>* %in
317   br label %bb1
319 bb1:
320   store <16 x double> %a, <16 x double>* %out
321   ret void
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]
329 ; CHECK: ret
330   %a = load <32 x double>, <32 x double>* %in
331   br label %bb1
333 bb1:
334   store <32 x double> %a, <32 x double>* %out
335   ret void
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
343 ; CHECK: ret
344   %a = load <8 x i32>, <8 x i32>* %in
345   br label %bb1
347 bb1:
348   %cond = icmp sgt <8 x i32> %a, zeroinitializer
349   ret <8 x i1> %cond
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:
358 ; CHECK:       // %bb.0:
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
367 ; CHECK-NEXT:    ret
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
372 bb.1:
373   %or = or <8 x i32> %a, %b
374   store <8 x i32> %or, <8 x i32>* %out
375   br label %bb.2
377 bb.2:
378   ret void
381 attributes #0 = { "target-features"="+sve" }