1; RUN: llc -mtriple=aarch64--linux-gnu -mattr=+sve -asm-verbose=0 < %s 2>%t | FileCheck %s
2; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t
3
4; If this check fails please read test/CodeGen/AArch64/README for instructions on how to resolve it.
5; WARN-NOT: warning
6
7; Test that scalable vectors that are a multiple of the legal vector size
8; can be properly broken down into part vectors.
9
10declare void @bar()
11
12;
13; Vectors twice the size
14;
15
16define <vscale x 32 x i8> @wide_32i8(i1 %b, <vscale x 16 x i8> %legal, <vscale x 32 x i8> %illegal) nounwind {
17; CHECK-LABEL: wide_32i8
18; CHECK:      mov     z0.d, z1.d
19; CHECK-NEXT: mov     z1.d, z2.d
20; CHECK-NEXT: ret
21  br i1 %b, label %L1, label %L2
22L1:
23  call void @bar()
24  ret <vscale x 32 x i8> undef
25L2:
26  ret <vscale x 32 x i8> %illegal
27}
28
29define <vscale x 16 x i16> @wide_16i16(i1 %b, <vscale x 16 x i8> %legal, <vscale x 16 x i16> %illegal) nounwind {
30; CHECK-LABEL: wide_16i16
31; CHECK:      mov     z0.d, z1.d
32; CHECK-NEXT: mov     z1.d, z2.d
33; CHECK-NEXT: ret
34  br i1 %b, label %L1, label %L2
35L1:
36  call void @bar()
37  ret <vscale x 16 x i16> undef
38L2:
39  ret <vscale x 16 x i16> %illegal
40}
41
42define <vscale x 8 x i32> @wide_8i32(i1 %b, <vscale x 16 x i8> %legal, <vscale x 8 x i32> %illegal) nounwind {
43; CHECK-LABEL: wide_8i32
44; CHECK:      mov     z0.d, z1.d
45; CHECK-NEXT: mov     z1.d, z2.d
46; CHECK-NEXT: ret
47  br i1 %b, label %L1, label %L2
48L1:
49  call void @bar()
50  ret <vscale x 8 x i32> undef
51L2:
52  ret <vscale x 8 x i32> %illegal
53}
54
55define <vscale x 4 x i64> @wide_4i64(i1 %b, <vscale x 16 x i8> %legal, <vscale x 4 x i64> %illegal) nounwind {
56; CHECK-LABEL: wide_4i64
57; CHECK:      mov     z0.d, z1.d
58; CHECK-NEXT: mov     z1.d, z2.d
59; CHECK-NEXT: ret
60  br i1 %b, label %L1, label %L2
61L1:
62  call void @bar()
63  ret <vscale x 4 x i64> undef
64L2:
65  ret <vscale x 4 x i64> %illegal
66}
67
68define <vscale x 16 x half> @wide_16f16(i1 %b, <vscale x 16 x i8> %legal, <vscale x 16 x half> %illegal) nounwind {
69; CHECK-LABEL: wide_16f16
70; CHECK:      mov     z0.d, z1.d
71; CHECK-NEXT: mov     z1.d, z2.d
72; CHECK-NEXT: ret
73  br i1 %b, label %L1, label %L2
74L1:
75  call void @bar()
76  ret <vscale x 16 x half> undef
77L2:
78  ret <vscale x 16 x half> %illegal
79}
80
81define <vscale x 8 x float> @wide_8f32(i1 %b, <vscale x 16 x i8> %legal, <vscale x 8 x float> %illegal) nounwind {
82; CHECK-LABEL: wide_8f32
83; CHECK:      mov     z0.d, z1.d
84; CHECK-NEXT: mov     z1.d, z2.d
85; CHECK-NEXT: ret
86  br i1 %b, label %L1, label %L2
87L1:
88  call void @bar()
89  ret <vscale x 8 x float> undef
90L2:
91  ret <vscale x 8 x float> %illegal
92}
93
94define <vscale x 4 x double> @wide_4f64(i1 %b, <vscale x 16 x i8> %legal, <vscale x 4 x double> %illegal) nounwind {
95; CHECK-LABEL: wide_4f64
96; CHECK:      mov     z0.d, z1.d
97; CHECK-NEXT: mov     z1.d, z2.d
98; CHECK-NEXT: ret
99  br i1 %b, label %L1, label %L2
100L1:
101  call void @bar()
102  ret <vscale x 4 x double> undef
103L2:
104  ret <vscale x 4 x double> %illegal
105}
106
107;
108; Vectors three times the size
109;
110
111define <vscale x 48 x i8> @wide_48i8(i1 %b, <vscale x 16 x i8> %legal, <vscale x 48 x i8> %illegal) nounwind {
112; CHECK-LABEL: wide_48i8
113; CHECK:      mov     z0.d, z1.d
114; CHECK-NEXT: mov     z1.d, z2.d
115; CHECK-NEXT: mov     z2.d, z3.d
116; CHECK-NEXT: ret
117  br i1 %b, label %L1, label %L2
118L1:
119  call void @bar()
120  ret <vscale x 48 x i8> undef
121L2:
122  ret <vscale x 48 x i8> %illegal
123}
124
125define <vscale x 24 x i16> @wide_24i16(i1 %b, <vscale x 16 x i8> %legal, <vscale x 24 x i16> %illegal) nounwind {
126; CHECK-LABEL: wide_24i16
127; CHECK:      mov     z0.d, z1.d
128; CHECK-NEXT: mov     z1.d, z2.d
129; CHECK-NEXT: mov     z2.d, z3.d
130; CHECK-NEXT: ret
131  br i1 %b, label %L1, label %L2
132L1:
133  call void @bar()
134  ret <vscale x 24 x i16> undef
135L2:
136  ret <vscale x 24 x i16> %illegal
137}
138
139define <vscale x 12 x i32> @wide_12i32(i1 %b, <vscale x 16 x i8> %legal, <vscale x 12 x i32> %illegal) nounwind {
140; CHECK-LABEL: wide_12i32
141; CHECK:      mov     z0.d, z1.d
142; CHECK-NEXT: mov     z1.d, z2.d
143; CHECK-NEXT: mov     z2.d, z3.d
144; CHECK-NEXT: ret
145  br i1 %b, label %L1, label %L2
146L1:
147  call void @bar()
148  ret <vscale x 12 x i32> undef
149L2:
150  ret <vscale x 12 x i32> %illegal
151}
152
153define <vscale x 6 x i64> @wide_6i64(i1 %b, <vscale x 16 x i8> %legal, <vscale x 6 x i64> %illegal) nounwind {
154; CHECK-LABEL: wide_6i64
155; CHECK:      mov     z0.d, z1.d
156; CHECK-NEXT: mov     z1.d, z2.d
157; CHECK-NEXT: mov     z2.d, z3.d
158; CHECK-NEXT: ret
159  br i1 %b, label %L1, label %L2
160L1:
161  call void @bar()
162  ret <vscale x 6 x i64> undef
163L2:
164  ret <vscale x 6 x i64> %illegal
165}
166
167define <vscale x 24 x half> @wide_24f16(i1 %b, <vscale x 16 x i8> %legal, <vscale x 24 x half> %illegal) nounwind {
168; CHECK-LABEL: wide_24f16
169; CHECK:      mov     z0.d, z1.d
170; CHECK-NEXT: mov     z1.d, z2.d
171; CHECK-NEXT: mov     z2.d, z3.d
172; CHECK-NEXT: ret
173  br i1 %b, label %L1, label %L2
174L1:
175  call void @bar()
176  ret <vscale x 24 x half> undef
177L2:
178  ret <vscale x 24 x half> %illegal
179}
180
181define <vscale x 12 x float> @wide_12f32(i1 %b, <vscale x 16 x i8> %legal, <vscale x 12 x float> %illegal) nounwind {
182; CHECK-LABEL: wide_12f32
183; CHECK:      mov     z0.d, z1.d
184; CHECK-NEXT: mov     z1.d, z2.d
185; CHECK-NEXT: mov     z2.d, z3.d
186; CHECK-NEXT: ret
187  br i1 %b, label %L1, label %L2
188L1:
189  call void @bar()
190  ret <vscale x 12 x float> undef
191L2:
192  ret <vscale x 12 x float> %illegal
193}
194
195define <vscale x 6 x double> @wide_6f64(i1 %b, <vscale x 16 x i8> %legal, <vscale x 6 x double> %illegal) nounwind {
196; CHECK-LABEL: wide_6f64
197; CHECK:      mov     z0.d, z1.d
198; CHECK-NEXT: mov     z1.d, z2.d
199; CHECK-NEXT: mov     z2.d, z3.d
200; CHECK-NEXT: ret
201  br i1 %b, label %L1, label %L2
202L1:
203  call void @bar()
204  ret <vscale x 6 x double> undef
205L2:
206  ret <vscale x 6 x double> %illegal
207}
208
209;
210; Vectors four times the size
211;
212
213define <vscale x 64 x i8> @wide_64i8(i1 %b, <vscale x 16 x i8> %legal, <vscale x 64 x i8> %illegal) nounwind {
214; CHECK-LABEL: wide_64i8
215; CHECK:      mov     z0.d, z1.d
216; CHECK-NEXT: mov     z1.d, z2.d
217; CHECK-NEXT: mov     z2.d, z3.d
218; CHECK-NEXT: mov     z3.d, z4.d
219; CHECK-NEXT: ret
220  br i1 %b, label %L1, label %L2
221L1:
222  call void @bar()
223  ret <vscale x 64 x i8> undef
224L2:
225  ret <vscale x 64 x i8> %illegal
226}
227
228define <vscale x 32 x i16> @wide_32i16(i1 %b, <vscale x 16 x i8> %legal, <vscale x 32 x i16> %illegal) nounwind {
229; CHECK-LABEL: wide_32i16
230; CHECK:      mov     z0.d, z1.d
231; CHECK-NEXT: mov     z1.d, z2.d
232; CHECK-NEXT: mov     z2.d, z3.d
233; CHECK-NEXT: mov     z3.d, z4.d
234; CHECK-NEXT: ret
235  br i1 %b, label %L1, label %L2
236L1:
237  call void @bar()
238  ret <vscale x 32 x i16> undef
239L2:
240  ret <vscale x 32 x i16> %illegal
241}
242
243define <vscale x 16 x i32> @wide_16i32(i1 %b, <vscale x 16 x i8> %legal, <vscale x 16 x i32> %illegal) nounwind {
244; CHECK-LABEL: wide_16i32
245; CHECK:      mov     z0.d, z1.d
246; CHECK-NEXT: mov     z1.d, z2.d
247; CHECK-NEXT: mov     z2.d, z3.d
248; CHECK-NEXT: mov     z3.d, z4.d
249; CHECK-NEXT: ret
250  br i1 %b, label %L1, label %L2
251L1:
252  call void @bar()
253  ret <vscale x 16 x i32> undef
254L2:
255  ret <vscale x 16 x i32> %illegal
256}
257
258define <vscale x 8 x i64> @wide_8i64(i1 %b, <vscale x 16 x i8> %legal, <vscale x 8 x i64> %illegal) nounwind {
259; CHECK-LABEL: wide_8i64
260; CHECK:      mov     z0.d, z1.d
261; CHECK-NEXT: mov     z1.d, z2.d
262; CHECK-NEXT: mov     z2.d, z3.d
263; CHECK-NEXT: mov     z3.d, z4.d
264; CHECK-NEXT: ret
265  br i1 %b, label %L1, label %L2
266L1:
267  call void @bar()
268  ret <vscale x 8 x i64> undef
269L2:
270  ret <vscale x 8 x i64> %illegal
271}
272
273define <vscale x 32 x half> @wide_32f16(i1 %b, <vscale x 16 x i8> %legal, <vscale x 32 x half> %illegal) nounwind {
274; CHECK-LABEL: wide_32f16
275; CHECK:      mov     z0.d, z1.d
276; CHECK-NEXT: mov     z1.d, z2.d
277; CHECK-NEXT: mov     z2.d, z3.d
278; CHECK-NEXT: mov     z3.d, z4.d
279; CHECK-NEXT: ret
280  br i1 %b, label %L1, label %L2
281L1:
282  call void @bar()
283  ret <vscale x 32 x half> undef
284L2:
285  ret <vscale x 32 x half> %illegal
286}
287
288define <vscale x 16 x float> @wide_16f32(i1 %b, <vscale x 16 x i8> %legal, <vscale x 16 x float> %illegal) nounwind {
289; CHECK-LABEL: wide_16f32
290; CHECK:      mov     z0.d, z1.d
291; CHECK-NEXT: mov     z1.d, z2.d
292; CHECK-NEXT: mov     z2.d, z3.d
293; CHECK-NEXT: mov     z3.d, z4.d
294; CHECK-NEXT: ret
295  br i1 %b, label %L1, label %L2
296L1:
297  call void @bar()
298  ret <vscale x 16 x float> undef
299L2:
300  ret <vscale x 16 x float> %illegal
301}
302
303define <vscale x 8 x double> @wide_8f64(i1 %b, <vscale x 16 x i8> %legal, <vscale x 8 x double> %illegal) nounwind {
304; CHECK-LABEL: wide_8f64
305; CHECK:      mov     z0.d, z1.d
306; CHECK-NEXT: mov     z1.d, z2.d
307; CHECK-NEXT: mov     z2.d, z3.d
308; CHECK-NEXT: mov     z3.d, z4.d
309; CHECK-NEXT: ret
310  br i1 %b, label %L1, label %L2
311L1:
312  call void @bar()
313  ret <vscale x 8 x double> undef
314L2:
315  ret <vscale x 8 x double> %illegal
316}
317