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, z1.d, z0.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_bigconst_nxv2i64(i64 %x) {
293; CHECK-LABEL: mul_add_stepvector_bigconst_nxv2i64:
294; CHECK:       // %bb.0: // %entry
295; CHECK-NEXT:    mov x8, #146028888064
296; CHECK-NEXT:    index z0.d, x0, x8
297; CHECK-NEXT:    ret
298entry:
299  %0 = insertelement <vscale x 2 x i64> poison, i64 146028888064, i32 0
300  %1 = shufflevector <vscale x 2 x i64> %0, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
301  %2 = call <vscale x 2 x i64> @llvm.experimental.stepvector.nxv2i64()
302  %3 = mul <vscale x 2 x i64> %2, %1
303  %4 = insertelement <vscale x 2 x i64> poison, i64 %x, i32 0
304  %5 = shufflevector <vscale x 2 x i64> %4, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
305  %6 = add <vscale x 2 x i64> %3, %5
306  ret <vscale x 2 x i64> %6
307}
308
309define <vscale x 2 x i64> @mul_mul_add_stepvector_nxv2i64(i64 %x, i64 %y) {
310; CHECK-LABEL: mul_mul_add_stepvector_nxv2i64:
311; CHECK:       // %bb.0: // %entry
312; CHECK-NEXT:    add x8, x0, x0, lsl #1
313; CHECK-NEXT:    index z0.d, x1, x8
314; CHECK-NEXT:    ret
315entry:
316  %xmul = mul i64 %x, 3
317  %0 = insertelement <vscale x 2 x i64> poison, i64 %xmul, i32 0
318  %1 = shufflevector <vscale x 2 x i64> %0, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
319  %2 = call <vscale x 2 x i64> @llvm.experimental.stepvector.nxv2i64()
320  %3 = mul <vscale x 2 x i64> %2, %1
321  %4 = insertelement <vscale x 2 x i64> poison, i64 %y, i32 0
322  %5 = shufflevector <vscale x 2 x i64> %4, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
323  %6 = add <vscale x 2 x i64> %3, %5
324  ret <vscale x 2 x i64> %6
325}
326
327define <vscale x 8 x i8> @shl_stepvector_nxv8i8() {
328; CHECK-LABEL: shl_stepvector_nxv8i8:
329; CHECK:       // %bb.0: // %entry
330; CHECK-NEXT:    index z0.h, #0, #4
331; CHECK-NEXT:    ret
332entry:
333  %0 = insertelement <vscale x 8 x i8> poison, i8 2, i32 0
334  %1 = shufflevector <vscale x 8 x i8> %0, <vscale x 8 x i8> poison, <vscale x 8 x i32> zeroinitializer
335  %2 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
336  %3 = shl <vscale x 8 x i8> %2, %1
337  ret <vscale x 8 x i8> %3
338}
339
340define <vscale x 8 x i16> @sub_multiple_use_stepvector_nxv8i16() {
341; CHECK-LABEL: sub_multiple_use_stepvector_nxv8i16:
342; CHECK:       // %bb.0: // %entry
343; CHECK-NEXT:    index z0.h, #0, #1
344; CHECK-NEXT:    ptrue p0.h
345; CHECK-NEXT:    mov z1.d, z0.d
346; CHECK-NEXT:    subr z1.h, z1.h, #2 // =0x2
347; CHECK-NEXT:    lsl z0.h, p0/m, z0.h, z1.h
348; CHECK-NEXT:    ret
349entry:
350  %0 = insertelement <vscale x 8 x i16> poison, i16 2, i32 0
351  %1 = shufflevector <vscale x 8 x i16> %0, <vscale x 8 x i16> poison, <vscale x 8 x i32> zeroinitializer
352  %2 = call <vscale x 8 x i16> @llvm.experimental.stepvector.nxv8i16()
353  %3 = sub <vscale x 8 x i16> %1, %2
354  %4 = shl <vscale x 8 x i16> %2, %3
355  ret <vscale x 8 x i16> %4
356}
357
358define <vscale x 8 x i16> @sub_stepvector_nxv8i16() {
359; CHECK-LABEL: sub_stepvector_nxv8i16:
360; CHECK:       // %bb.0: // %entry
361; CHECK-NEXT:    index z0.h, #2, #-1
362; CHECK-NEXT:    ret
363entry:
364  %0 = insertelement <vscale x 8 x i16> poison, i16 2, i32 0
365  %1 = shufflevector <vscale x 8 x i16> %0, <vscale x 8 x i16> poison, <vscale x 8 x i32> zeroinitializer
366  %2 = call <vscale x 8 x i16> @llvm.experimental.stepvector.nxv8i16()
367  %3 = sub <vscale x 8 x i16> %1, %2
368  ret <vscale x 8 x i16> %3
369}
370
371define <vscale x 8 x i8> @promote_sub_stepvector_nxv8i8() {
372; CHECK-LABEL: promote_sub_stepvector_nxv8i8:
373; CHECK:       // %bb.0: // %entry
374; CHECK-NEXT:    index z0.h, #2, #-1
375; CHECK-NEXT:    ret
376entry:
377  %0 = insertelement <vscale x 8 x i8> poison, i8 2, i32 0
378  %1 = shufflevector <vscale x 8 x i8> %0, <vscale x 8 x i8> poison, <vscale x 8 x i32> zeroinitializer
379  %2 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
380  %3 = sub <vscale x 8 x i8> %1, %2
381  ret <vscale x 8 x i8> %3
382}
383
384define <vscale x 16 x i32> @split_sub_stepvector_nxv16i32() {
385; CHECK-LABEL: split_sub_stepvector_nxv16i32:
386; CHECK:       // %bb.0: // %entry
387; CHECK-NEXT:    cntw x8
388; CHECK-NEXT:    cnth x9
389; CHECK-NEXT:    neg x8, x8
390; CHECK-NEXT:    neg x9, x9
391; CHECK-NEXT:    index z0.s, #0, #-1
392; CHECK-NEXT:    mov z1.s, w8
393; CHECK-NEXT:    mov z3.s, w9
394; CHECK-NEXT:    add z1.s, z0.s, z1.s
395; CHECK-NEXT:    add z2.s, z0.s, z3.s
396; CHECK-NEXT:    add z3.s, z1.s, z3.s
397; CHECK-NEXT:    ret
398entry:
399  %0 = call <vscale x 16 x i32> @llvm.experimental.stepvector.nxv16i32()
400  %1 = sub <vscale x 16 x i32> zeroinitializer, %0
401  ret <vscale x 16 x i32> %1
402}
403
404declare <vscale x 2 x i64> @llvm.experimental.stepvector.nxv2i64()
405declare <vscale x 4 x i32> @llvm.experimental.stepvector.nxv4i32()
406declare <vscale x 8 x i16> @llvm.experimental.stepvector.nxv8i16()
407declare <vscale x 16 x i8> @llvm.experimental.stepvector.nxv16i8()
408
409declare <vscale x 4 x i64> @llvm.experimental.stepvector.nxv4i64()
410declare <vscale x 16 x i32> @llvm.experimental.stepvector.nxv16i32()
411declare <vscale x 2 x i32> @llvm.experimental.stepvector.nxv2i32()
412declare <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
413declare <vscale x 4 x i16> @llvm.experimental.stepvector.nxv4i16()
414