1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s --check-prefixes=CHECK
3
4; LEGAL INTEGER TYPES
5
6define <vscale x 2 x i64> @stepvector_nxv2i64() {
7; CHECK-LABEL: stepvector_nxv2i64:
8; CHECK:       // %bb.0: // %entry
9; CHECK-NEXT:    index z0.d, #0, #1
10; CHECK-NEXT:    ret
11entry:
12  %0 = call <vscale x 2 x i64> @llvm.experimental.stepvector.nxv2i64()
13  ret <vscale x 2 x i64> %0
14}
15
16define <vscale x 4 x i32> @stepvector_nxv4i32() {
17; CHECK-LABEL: stepvector_nxv4i32:
18; CHECK:       // %bb.0: // %entry
19; CHECK-NEXT:    index z0.s, #0, #1
20; CHECK-NEXT:    ret
21entry:
22  %0 = call <vscale x 4 x i32> @llvm.experimental.stepvector.nxv4i32()
23  ret <vscale x 4 x i32> %0
24}
25
26define <vscale x 8 x i16> @stepvector_nxv8i16() {
27; CHECK-LABEL: stepvector_nxv8i16:
28; CHECK:       // %bb.0: // %entry
29; CHECK-NEXT:    index z0.h, #0, #1
30; CHECK-NEXT:    ret
31entry:
32  %0 = call <vscale x 8 x i16> @llvm.experimental.stepvector.nxv8i16()
33  ret <vscale x 8 x i16> %0
34}
35
36define <vscale x 16 x i8> @stepvector_nxv16i8() {
37; CHECK-LABEL: stepvector_nxv16i8:
38; CHECK:       // %bb.0: // %entry
39; CHECK-NEXT:    index z0.b, #0, #1
40; CHECK-NEXT:    ret
41entry:
42  %0 = call <vscale x 16 x i8> @llvm.experimental.stepvector.nxv16i8()
43  ret <vscale x 16 x i8> %0
44}
45
46; ILLEGAL INTEGER TYPES
47
48define <vscale x 4 x i64> @stepvector_nxv4i64() {
49; CHECK-LABEL: stepvector_nxv4i64:
50; CHECK:       // %bb.0: // %entry
51; CHECK-NEXT:    index z0.d, #0, #1
52; CHECK-NEXT:    mov z1.d, z0.d
53; CHECK-NEXT:    incd z1.d
54; CHECK-NEXT:    ret
55entry:
56  %0 = call <vscale x 4 x i64> @llvm.experimental.stepvector.nxv4i64()
57  ret <vscale x 4 x i64> %0
58}
59
60define <vscale x 16 x i32> @stepvector_nxv16i32() {
61; CHECK-LABEL: stepvector_nxv16i32:
62; CHECK:       // %bb.0: // %entry
63; CHECK-NEXT:    index z0.s, #0, #1
64; CHECK-NEXT:    mov z1.d, z0.d
65; CHECK-NEXT:    mov z2.d, z0.d
66; CHECK-NEXT:    incw z1.s
67; CHECK-NEXT:    incw z2.s, all, mul #2
68; CHECK-NEXT:    mov z3.d, z1.d
69; CHECK-NEXT:    incw z3.s, all, mul #2
70; CHECK-NEXT:    ret
71entry:
72  %0 = call <vscale x 16 x i32> @llvm.experimental.stepvector.nxv16i32()
73  ret <vscale x 16 x i32> %0
74}
75
76define <vscale x 2 x i32> @stepvector_nxv2i32() {
77; CHECK-LABEL: stepvector_nxv2i32:
78; CHECK:       // %bb.0: // %entry
79; CHECK-NEXT:    index z0.d, #0, #1
80; CHECK-NEXT:    ret
81entry:
82  %0 = call <vscale x 2 x i32> @llvm.experimental.stepvector.nxv2i32()
83  ret <vscale x 2 x i32> %0
84}
85
86define <vscale x 4 x i16> @stepvector_nxv4i16() {
87; CHECK-LABEL: stepvector_nxv4i16:
88; CHECK:       // %bb.0: // %entry
89; CHECK-NEXT:    index z0.s, #0, #1
90; CHECK-NEXT:    ret
91entry:
92  %0 = call <vscale x 4 x i16> @llvm.experimental.stepvector.nxv4i16()
93  ret <vscale x 4 x i16> %0
94}
95
96define <vscale x 8 x i8> @stepvector_nxv8i8() {
97; CHECK-LABEL: stepvector_nxv8i8:
98; CHECK:       // %bb.0: // %entry
99; CHECK-NEXT:    index z0.h, #0, #1
100; CHECK-NEXT:    ret
101entry:
102  %0 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
103  ret <vscale x 8 x i8> %0
104}
105
106define <vscale x 8 x i8> @add_stepvector_nxv8i8() {
107; CHECK-LABEL: add_stepvector_nxv8i8:
108; CHECK:       // %bb.0: // %entry
109; CHECK-NEXT:    index z0.h, #0, #2
110; CHECK-NEXT:    ret
111entry:
112  %0 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
113  %1 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
114  %2 = add <vscale x 8 x i8> %0, %1
115  ret <vscale x 8 x i8> %2
116}
117
118define <vscale x 8 x i8> @add_stepvector_nxv8i8_1(<vscale x 8 x i8> %p) {
119; CHECK-LABEL: add_stepvector_nxv8i8_1:
120; CHECK:       // %bb.0: // %entry
121; CHECK-NEXT:    index z1.h, #0, #2
122; CHECK-NEXT:    add z0.h, z0.h, z1.h
123; CHECK-NEXT:    ret
124entry:
125  %0 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
126  %1 = add <vscale x 8 x i8> %p, %0
127  %2 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
128  %3 = add <vscale x 8 x i8> %1, %2
129  ret <vscale x 8 x i8> %3
130}
131
132define <vscale x 8 x i8> @add_stepvector_nxv8i8_2() {
133; CHECK-LABEL: add_stepvector_nxv8i8_2:
134; CHECK:       // %bb.0: // %entry
135; CHECK-NEXT:    index z0.h, #2, #1
136; CHECK-NEXT:    ret
137entry:
138  %0 = insertelement <vscale x 8 x i8> poison, i8 2, i32 0
139  %1 = shufflevector <vscale x 8 x i8> %0, <vscale x 8 x i8> poison, <vscale x 8 x i32> zeroinitializer
140  %2 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
141  %3 = add <vscale x 8 x i8> %2, %1
142  ret <vscale x 8 x i8> %3
143}
144
145define <vscale x 8 x i8> @add_stepvector_nxv8i8_2_commutative() {
146; CHECK-LABEL: add_stepvector_nxv8i8_2_commutative:
147; CHECK:       // %bb.0: // %entry
148; CHECK-NEXT:    index z0.h, #2, #1
149; CHECK-NEXT:    ret
150entry:
151  %0 = insertelement <vscale x 8 x i8> poison, i8 2, i32 0
152  %1 = shufflevector <vscale x 8 x i8> %0, <vscale x 8 x i8> poison, <vscale x 8 x i32> zeroinitializer
153  %2 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
154  %3 = add <vscale x 8 x i8> %1, %2
155  ret <vscale x 8 x i8> %3
156}
157
158define <vscale x 8 x i16> @add_stepvector_nxv8i16_1(i16 %data) {
159; CHECK-LABEL: add_stepvector_nxv8i16_1:
160; CHECK:       // %bb.0: // %entry
161; CHECK-NEXT:    index z0.h, w0, #1
162; CHECK-NEXT:    ret
163entry:
164  %0 = insertelement <vscale x 8 x i16> poison, i16 %data, i32 0
165  %1 = shufflevector <vscale x 8 x i16> %0, <vscale x 8 x i16> poison, <vscale x 8 x i32> zeroinitializer
166  %2 = call <vscale x 8 x i16> @llvm.experimental.stepvector.nxv8i16()
167  %3 = add <vscale x 8 x i16> %2, %1
168  ret <vscale x 8 x i16> %3
169}
170
171define <vscale x 4 x i32> @add_stepvector_nxv4i32_1(i32 %data) {
172; CHECK-LABEL: add_stepvector_nxv4i32_1:
173; CHECK:       // %bb.0: // %entry
174; CHECK-NEXT:    index z0.s, w0, #1
175; CHECK-NEXT:    ret
176entry:
177  %0 = insertelement <vscale x 4 x i32> poison, i32 %data, i32 0
178  %1 = shufflevector <vscale x 4 x i32> %0, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer
179  %2 = call <vscale x 4 x i32> @llvm.experimental.stepvector.nxv4i32()
180  %3 = add <vscale x 4 x i32> %2, %1
181  ret <vscale x 4 x i32> %3
182}
183
184define <vscale x 4 x i32> @multiple_use_stepvector_nxv4i32_1(i32 %data) {
185; CHECK-LABEL: multiple_use_stepvector_nxv4i32_1:
186; CHECK:       // %bb.0: // %entry
187; CHECK-NEXT:    ptrue p0.s
188; CHECK-NEXT:    mov z0.s, w0
189; CHECK-NEXT:    index z1.s, w0, #1
190; CHECK-NEXT:    mul z0.s, p0/m, z0.s, z1.s
191; CHECK-NEXT:    sub z0.s, z0.s, z1.s
192; CHECK-NEXT:    ret
193entry:
194  %0 = insertelement <vscale x 4 x i32> poison, i32 %data, i32 0
195  %1 = shufflevector <vscale x 4 x i32> %0, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer
196  %2 = call <vscale x 4 x i32> @llvm.experimental.stepvector.nxv4i32()
197  %3 = add <vscale x 4 x i32> %2, %1
198  %4 = mul <vscale x 4 x i32> %1, %3
199  %5 = sub <vscale x 4 x i32> %4, %3
200  ret <vscale x 4 x i32> %5
201}
202
203define <vscale x 2 x i64> @add_stepvector_nxv2i64_1(i64 %data) {
204; CHECK-LABEL: add_stepvector_nxv2i64_1:
205; CHECK:       // %bb.0: // %entry
206; CHECK-NEXT:    index z0.d, x0, #1
207; CHECK-NEXT:    ret
208entry:
209  %0 = insertelement <vscale x 2 x i64> poison, i64 %data, i32 0
210  %1 = shufflevector <vscale x 2 x i64> %0, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
211  %2 = call <vscale x 2 x i64> @llvm.experimental.stepvector.nxv2i64()
212  %3 = add <vscale x 2 x i64> %1, %2
213  ret <vscale x 2 x i64> %3
214}
215
216define <vscale x 2 x i64> @multiple_use_stepvector_nxv2i64_1(i64 %data) {
217; CHECK-LABEL: multiple_use_stepvector_nxv2i64_1:
218; CHECK:       // %bb.0: // %entry
219; CHECK-NEXT:    index z0.d, #0, #1
220; CHECK-NEXT:    mov z1.d, x0
221; CHECK-NEXT:    add z1.d, z0.d, z1.d
222; CHECK-NEXT:    ptrue p0.d
223; CHECK-NEXT:    mul z0.d, p0/m, z0.d, z1.d
224; CHECK-NEXT:    ret
225entry:
226  %0 = insertelement <vscale x 2 x i64> poison, i64 %data, i32 0
227  %1 = shufflevector <vscale x 2 x i64> %0, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
228  %2 = call <vscale x 2 x i64> @llvm.experimental.stepvector.nxv2i64()
229  %3 = add <vscale x 2 x i64> %1, %2
230  %4 = mul <vscale x 2 x i64> %3, %2
231  ret <vscale x 2 x i64> %4
232}
233
234define <vscale x 8 x i8> @mul_stepvector_nxv8i8() {
235; CHECK-LABEL: mul_stepvector_nxv8i8:
236; CHECK:       // %bb.0: // %entry
237; CHECK-NEXT:    index z0.h, #0, #2
238; CHECK-NEXT:    ret
239entry:
240  %0 = insertelement <vscale x 8 x i8> poison, i8 2, i32 0
241  %1 = shufflevector <vscale x 8 x i8> %0, <vscale x 8 x i8> poison, <vscale x 8 x i32> zeroinitializer
242  %2 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
243  %3 = mul <vscale x 8 x i8> %2, %1
244  ret <vscale x 8 x i8> %3
245}
246
247define <vscale x 2 x i64> @mul_stepvector_nxv2i64() {
248; CHECK-LABEL: mul_stepvector_nxv2i64:
249; CHECK:       // %bb.0: // %entry
250; CHECK-NEXT:    mov w8, #2222
251; CHECK-NEXT:    index z0.d, #0, x8
252; CHECK-NEXT:    ret
253entry:
254  %0 = insertelement <vscale x 2 x i64> poison, i64 2222, i32 0
255  %1 = shufflevector <vscale x 2 x i64> %0, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
256  %2 = call <vscale x 2 x i64> @llvm.experimental.stepvector.nxv2i64()
257  %3 = mul <vscale x 2 x i64> %2, %1
258  ret <vscale x 2 x i64> %3
259}
260
261define <vscale x 2 x i64> @mul_stepvector_bigconst_nxv2i64() {
262; CHECK-LABEL: mul_stepvector_bigconst_nxv2i64:
263; CHECK:       // %bb.0: // %entry
264; CHECK-NEXT:    mov x8, #146028888064
265; CHECK-NEXT:    index z0.d, #0, x8
266; CHECK-NEXT:    ret
267entry:
268  %0 = insertelement <vscale x 2 x i64> poison, i64 146028888064, i32 0
269  %1 = shufflevector <vscale x 2 x i64> %0, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
270  %2 = call <vscale x 2 x i64> @llvm.experimental.stepvector.nxv2i64()
271  %3 = mul <vscale x 2 x i64> %2, %1
272  ret <vscale x 2 x i64> %3
273}
274
275define <vscale x 2 x i64> @mul_add_stepvector_nxv2i64(i64 %x) {
276; CHECK-LABEL: mul_add_stepvector_nxv2i64:
277; CHECK:       // %bb.0: // %entry
278; CHECK-NEXT:    mov w8, #2222
279; CHECK-NEXT:    index z0.d, x0, x8
280; CHECK-NEXT:    ret
281entry:
282  %0 = insertelement <vscale x 2 x i64> poison, i64 2222, i32 0
283  %1 = shufflevector <vscale x 2 x i64> %0, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
284  %2 = call <vscale x 2 x i64> @llvm.experimental.stepvector.nxv2i64()
285  %3 = mul <vscale x 2 x i64> %2, %1
286  %4 = insertelement <vscale x 2 x i64> poison, i64 %x, i32 0
287  %5 = shufflevector <vscale x 2 x i64> %4, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
288  %6 = add <vscale x 2 x i64> %3, %5
289  ret <vscale x 2 x i64> %6
290}
291
292define <vscale x 2 x i64> @mul_add_stepvector_nxv2i64_commutative(i64 %x, i64 %y) {
293; CHECK-LABEL: mul_add_stepvector_nxv2i64_commutative:
294; CHECK:       // %bb.0: // %entry
295; CHECK-NEXT:    index z0.d, x0, x1
296; CHECK-NEXT:    ret
297entry:
298  %0 = insertelement <vscale x 2 x i64> poison, i64 %y, i32 0
299  %1 = shufflevector <vscale x 2 x i64> %0, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
300  %2 = call <vscale x 2 x i64> @llvm.experimental.stepvector.nxv2i64()
301  %3 = mul <vscale x 2 x i64> %1, %2
302  %4 = insertelement <vscale x 2 x i64> poison, i64 %x, i32 0
303  %5 = shufflevector <vscale x 2 x i64> %4, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
304  %6 = add <vscale x 2 x i64> %5, %3
305  ret <vscale x 2 x i64> %6
306}
307
308define <vscale x 2 x i64> @mul_add_stepvector_bigconst_nxv2i64(i64 %x) {
309; CHECK-LABEL: mul_add_stepvector_bigconst_nxv2i64:
310; CHECK:       // %bb.0: // %entry
311; CHECK-NEXT:    mov x8, #146028888064
312; CHECK-NEXT:    index z0.d, x0, x8
313; CHECK-NEXT:    ret
314entry:
315  %0 = insertelement <vscale x 2 x i64> poison, i64 146028888064, i32 0
316  %1 = shufflevector <vscale x 2 x i64> %0, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
317  %2 = call <vscale x 2 x i64> @llvm.experimental.stepvector.nxv2i64()
318  %3 = mul <vscale x 2 x i64> %2, %1
319  %4 = insertelement <vscale x 2 x i64> poison, i64 %x, i32 0
320  %5 = shufflevector <vscale x 2 x i64> %4, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
321  %6 = add <vscale x 2 x i64> %3, %5
322  ret <vscale x 2 x i64> %6
323}
324
325define <vscale x 2 x i64> @mul_mul_add_stepvector_nxv2i64(i64 %x, i64 %y) {
326; CHECK-LABEL: mul_mul_add_stepvector_nxv2i64:
327; CHECK:       // %bb.0: // %entry
328; CHECK-NEXT:    add x8, x0, x0, lsl #1
329; CHECK-NEXT:    index z0.d, x1, x8
330; CHECK-NEXT:    ret
331entry:
332  %xmul = mul i64 %x, 3
333  %0 = insertelement <vscale x 2 x i64> poison, i64 %xmul, i32 0
334  %1 = shufflevector <vscale x 2 x i64> %0, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
335  %2 = call <vscale x 2 x i64> @llvm.experimental.stepvector.nxv2i64()
336  %3 = mul <vscale x 2 x i64> %2, %1
337  %4 = insertelement <vscale x 2 x i64> poison, i64 %y, i32 0
338  %5 = shufflevector <vscale x 2 x i64> %4, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
339  %6 = add <vscale x 2 x i64> %3, %5
340  ret <vscale x 2 x i64> %6
341}
342
343define <vscale x 8 x i8> @shl_stepvector_nxv8i8() {
344; CHECK-LABEL: shl_stepvector_nxv8i8:
345; CHECK:       // %bb.0: // %entry
346; CHECK-NEXT:    index z0.h, #0, #4
347; CHECK-NEXT:    ret
348entry:
349  %0 = insertelement <vscale x 8 x i8> poison, i8 2, i32 0
350  %1 = shufflevector <vscale x 8 x i8> %0, <vscale x 8 x i8> poison, <vscale x 8 x i32> zeroinitializer
351  %2 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
352  %3 = shl <vscale x 8 x i8> %2, %1
353  ret <vscale x 8 x i8> %3
354}
355
356define <vscale x 8 x i16> @sub_multiple_use_stepvector_nxv8i16() {
357; CHECK-LABEL: sub_multiple_use_stepvector_nxv8i16:
358; CHECK:       // %bb.0: // %entry
359; CHECK-NEXT:    index z0.h, #0, #1
360; CHECK-NEXT:    ptrue p0.h
361; CHECK-NEXT:    mov z1.d, z0.d
362; CHECK-NEXT:    subr z1.h, z1.h, #2 // =0x2
363; CHECK-NEXT:    lsl z0.h, p0/m, z0.h, z1.h
364; CHECK-NEXT:    ret
365entry:
366  %0 = insertelement <vscale x 8 x i16> poison, i16 2, i32 0
367  %1 = shufflevector <vscale x 8 x i16> %0, <vscale x 8 x i16> poison, <vscale x 8 x i32> zeroinitializer
368  %2 = call <vscale x 8 x i16> @llvm.experimental.stepvector.nxv8i16()
369  %3 = sub <vscale x 8 x i16> %1, %2
370  %4 = shl <vscale x 8 x i16> %2, %3
371  ret <vscale x 8 x i16> %4
372}
373
374define <vscale x 8 x i16> @sub_stepvector_nxv8i16() {
375; CHECK-LABEL: sub_stepvector_nxv8i16:
376; CHECK:       // %bb.0: // %entry
377; CHECK-NEXT:    index z0.h, #2, #-1
378; CHECK-NEXT:    ret
379entry:
380  %0 = insertelement <vscale x 8 x i16> poison, i16 2, i32 0
381  %1 = shufflevector <vscale x 8 x i16> %0, <vscale x 8 x i16> poison, <vscale x 8 x i32> zeroinitializer
382  %2 = call <vscale x 8 x i16> @llvm.experimental.stepvector.nxv8i16()
383  %3 = sub <vscale x 8 x i16> %1, %2
384  ret <vscale x 8 x i16> %3
385}
386
387define <vscale x 8 x i8> @promote_sub_stepvector_nxv8i8() {
388; CHECK-LABEL: promote_sub_stepvector_nxv8i8:
389; CHECK:       // %bb.0: // %entry
390; CHECK-NEXT:    index z0.h, #2, #-1
391; CHECK-NEXT:    ret
392entry:
393  %0 = insertelement <vscale x 8 x i8> poison, i8 2, i32 0
394  %1 = shufflevector <vscale x 8 x i8> %0, <vscale x 8 x i8> poison, <vscale x 8 x i32> zeroinitializer
395  %2 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
396  %3 = sub <vscale x 8 x i8> %1, %2
397  ret <vscale x 8 x i8> %3
398}
399
400define <vscale x 16 x i32> @split_sub_stepvector_nxv16i32() {
401; CHECK-LABEL: split_sub_stepvector_nxv16i32:
402; CHECK:       // %bb.0: // %entry
403; CHECK-NEXT:    cntw x8
404; CHECK-NEXT:    cnth x9
405; CHECK-NEXT:    neg x8, x8
406; CHECK-NEXT:    neg x9, x9
407; CHECK-NEXT:    index z0.s, #0, #-1
408; CHECK-NEXT:    mov z1.s, w8
409; CHECK-NEXT:    mov z3.s, w9
410; CHECK-NEXT:    add z1.s, z0.s, z1.s
411; CHECK-NEXT:    add z2.s, z0.s, z3.s
412; CHECK-NEXT:    add z3.s, z1.s, z3.s
413; CHECK-NEXT:    ret
414entry:
415  %0 = call <vscale x 16 x i32> @llvm.experimental.stepvector.nxv16i32()
416  %1 = sub <vscale x 16 x i32> zeroinitializer, %0
417  ret <vscale x 16 x i32> %1
418}
419
420declare <vscale x 2 x i64> @llvm.experimental.stepvector.nxv2i64()
421declare <vscale x 4 x i32> @llvm.experimental.stepvector.nxv4i32()
422declare <vscale x 8 x i16> @llvm.experimental.stepvector.nxv8i16()
423declare <vscale x 16 x i8> @llvm.experimental.stepvector.nxv16i8()
424
425declare <vscale x 4 x i64> @llvm.experimental.stepvector.nxv4i64()
426declare <vscale x 16 x i32> @llvm.experimental.stepvector.nxv16i32()
427declare <vscale x 2 x i32> @llvm.experimental.stepvector.nxv2i32()
428declare <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
429declare <vscale x 4 x i16> @llvm.experimental.stepvector.nxv4i16()
430