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:    cntd x8
52; CHECK-NEXT:    mov z1.d, x8
53; CHECK-NEXT:    index z0.d, #0, #1
54; CHECK-NEXT:    add z1.d, z0.d, z1.d
55; CHECK-NEXT:    ret
56entry:
57  %0 = call <vscale x 4 x i64> @llvm.experimental.stepvector.nxv4i64()
58  ret <vscale x 4 x i64> %0
59}
60
61define <vscale x 16 x i32> @stepvector_nxv16i32() {
62; CHECK-LABEL: stepvector_nxv16i32:
63; CHECK:       // %bb.0: // %entry
64; CHECK-NEXT:    cntw x9
65; CHECK-NEXT:    cnth x8
66; CHECK-NEXT:    index z0.s, #0, #1
67; CHECK-NEXT:    mov z1.s, w9
68; CHECK-NEXT:    mov z3.s, w8
69; CHECK-NEXT:    add z1.s, z0.s, z1.s
70; CHECK-NEXT:    add z2.s, z0.s, z3.s
71; CHECK-NEXT:    add z3.s, z1.s, z3.s
72; CHECK-NEXT:    ret
73entry:
74  %0 = call <vscale x 16 x i32> @llvm.experimental.stepvector.nxv16i32()
75  ret <vscale x 16 x i32> %0
76}
77
78define <vscale x 2 x i32> @stepvector_nxv2i32() {
79; CHECK-LABEL: stepvector_nxv2i32:
80; CHECK:       // %bb.0: // %entry
81; CHECK-NEXT:    index z0.d, #0, #1
82; CHECK-NEXT:    ret
83entry:
84  %0 = call <vscale x 2 x i32> @llvm.experimental.stepvector.nxv2i32()
85  ret <vscale x 2 x i32> %0
86}
87
88define <vscale x 4 x i16> @stepvector_nxv4i16() {
89; CHECK-LABEL: stepvector_nxv4i16:
90; CHECK:       // %bb.0: // %entry
91; CHECK-NEXT:    index z0.s, #0, #1
92; CHECK-NEXT:    ret
93entry:
94  %0 = call <vscale x 4 x i16> @llvm.experimental.stepvector.nxv4i16()
95  ret <vscale x 4 x i16> %0
96}
97
98define <vscale x 8 x i8> @stepvector_nxv8i8() {
99; CHECK-LABEL: stepvector_nxv8i8:
100; CHECK:       // %bb.0: // %entry
101; CHECK-NEXT:    index z0.h, #0, #1
102; CHECK-NEXT:    ret
103entry:
104  %0 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
105  ret <vscale x 8 x i8> %0
106}
107
108define <vscale x 8 x i8> @add_stepvector_nxv8i8() {
109; CHECK-LABEL: add_stepvector_nxv8i8:
110; CHECK:       // %bb.0: // %entry
111; CHECK-NEXT:    index z0.h, #0, #2
112; CHECK-NEXT:    ret
113entry:
114  %0 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
115  %1 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
116  %2 = add <vscale x 8 x i8> %0, %1
117  ret <vscale x 8 x i8> %2
118}
119
120define <vscale x 8 x i8> @add_stepvector_nxv8i8_1(<vscale x 8 x i8> %p) {
121; CHECK-LABEL: add_stepvector_nxv8i8_1:
122; CHECK:       // %bb.0: // %entry
123; CHECK-NEXT:    index z1.h, #0, #2
124; CHECK-NEXT:    add z0.h, z0.h, z1.h
125; CHECK-NEXT:    ret
126entry:
127  %0 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
128  %1 = add <vscale x 8 x i8> %p, %0
129  %2 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
130  %3 = add <vscale x 8 x i8> %1, %2
131  ret <vscale x 8 x i8> %3
132}
133
134define <vscale x 8 x i8> @add_stepvector_nxv8i8_2() {
135; CHECK-LABEL: add_stepvector_nxv8i8_2:
136; CHECK:       // %bb.0: // %entry
137; CHECK-NEXT:    index z0.h, #2, #1
138; CHECK-NEXT:    ret
139entry:
140  %0 = insertelement <vscale x 8 x i8> poison, i8 2, i32 0
141  %1 = shufflevector <vscale x 8 x i8> %0, <vscale x 8 x i8> poison, <vscale x 8 x i32> zeroinitializer
142  %2 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
143  %3 = add <vscale x 8 x i8> %2, %1
144  ret <vscale x 8 x i8> %3
145}
146
147define <vscale x 8 x i8> @add_stepvector_nxv8i8_2_commutative() {
148; CHECK-LABEL: add_stepvector_nxv8i8_2_commutative:
149; CHECK:       // %bb.0: // %entry
150; CHECK-NEXT:    index z0.h, #2, #1
151; CHECK-NEXT:    ret
152entry:
153  %0 = insertelement <vscale x 8 x i8> poison, i8 2, i32 0
154  %1 = shufflevector <vscale x 8 x i8> %0, <vscale x 8 x i8> poison, <vscale x 8 x i32> zeroinitializer
155  %2 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
156  %3 = add <vscale x 8 x i8> %1, %2
157  ret <vscale x 8 x i8> %3
158}
159
160define <vscale x 8 x i16> @add_stepvector_nxv8i16_1(i16 %data) {
161; CHECK-LABEL: add_stepvector_nxv8i16_1:
162; CHECK:       // %bb.0: // %entry
163; CHECK-NEXT:    index z0.h, w0, #1
164; CHECK-NEXT:    ret
165entry:
166  %0 = insertelement <vscale x 8 x i16> poison, i16 %data, i32 0
167  %1 = shufflevector <vscale x 8 x i16> %0, <vscale x 8 x i16> poison, <vscale x 8 x i32> zeroinitializer
168  %2 = call <vscale x 8 x i16> @llvm.experimental.stepvector.nxv8i16()
169  %3 = add <vscale x 8 x i16> %2, %1
170  ret <vscale x 8 x i16> %3
171}
172
173define <vscale x 4 x i32> @add_stepvector_nxv4i32_1(i32 %data) {
174; CHECK-LABEL: add_stepvector_nxv4i32_1:
175; CHECK:       // %bb.0: // %entry
176; CHECK-NEXT:    index z0.s, w0, #1
177; CHECK-NEXT:    ret
178entry:
179  %0 = insertelement <vscale x 4 x i32> poison, i32 %data, i32 0
180  %1 = shufflevector <vscale x 4 x i32> %0, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer
181  %2 = call <vscale x 4 x i32> @llvm.experimental.stepvector.nxv4i32()
182  %3 = add <vscale x 4 x i32> %2, %1
183  ret <vscale x 4 x i32> %3
184}
185
186define <vscale x 4 x i32> @multiple_use_stepvector_nxv4i32_1(i32 %data) {
187; CHECK-LABEL: multiple_use_stepvector_nxv4i32_1:
188; CHECK:       // %bb.0: // %entry
189; CHECK-NEXT:    mov z0.s, w0
190; CHECK-NEXT:    index z1.s, w0, #1
191; CHECK-NEXT:    ptrue p0.s
192; CHECK-NEXT:    mul z0.s, p0/m, z0.s, z1.s
193; CHECK-NEXT:    sub z0.s, z0.s, z1.s
194; CHECK-NEXT:    ret
195entry:
196  %0 = insertelement <vscale x 4 x i32> poison, i32 %data, i32 0
197  %1 = shufflevector <vscale x 4 x i32> %0, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer
198  %2 = call <vscale x 4 x i32> @llvm.experimental.stepvector.nxv4i32()
199  %3 = add <vscale x 4 x i32> %2, %1
200  %4 = mul <vscale x 4 x i32> %1, %3
201  %5 = sub <vscale x 4 x i32> %4, %3
202  ret <vscale x 4 x i32> %5
203}
204
205define <vscale x 2 x i64> @add_stepvector_nxv2i64_1(i64 %data) {
206; CHECK-LABEL: add_stepvector_nxv2i64_1:
207; CHECK:       // %bb.0: // %entry
208; CHECK-NEXT:    index z0.d, x0, #1
209; CHECK-NEXT:    ret
210entry:
211  %0 = insertelement <vscale x 2 x i64> poison, i64 %data, i32 0
212  %1 = shufflevector <vscale x 2 x i64> %0, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
213  %2 = call <vscale x 2 x i64> @llvm.experimental.stepvector.nxv2i64()
214  %3 = add <vscale x 2 x i64> %1, %2
215  ret <vscale x 2 x i64> %3
216}
217
218define <vscale x 2 x i64> @multiple_use_stepvector_nxv2i64_1(i64 %data) {
219; CHECK-LABEL: multiple_use_stepvector_nxv2i64_1:
220; CHECK:       // %bb.0: // %entry
221; CHECK-NEXT:    mov z0.d, x0
222; CHECK-NEXT:    index z1.d, #0, #1
223; CHECK-NEXT:    add z0.d, z0.d, z1.d
224; CHECK-NEXT:    ptrue p0.d
225; CHECK-NEXT:    mul z0.d, p0/m, z0.d, z1.d
226; CHECK-NEXT:    ret
227entry:
228  %0 = insertelement <vscale x 2 x i64> poison, i64 %data, i32 0
229  %1 = shufflevector <vscale x 2 x i64> %0, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
230  %2 = call <vscale x 2 x i64> @llvm.experimental.stepvector.nxv2i64()
231  %3 = add <vscale x 2 x i64> %1, %2
232  %4 = mul <vscale x 2 x i64> %3, %2
233  ret <vscale x 2 x i64> %4
234}
235
236define <vscale x 8 x i8> @mul_stepvector_nxv8i8() {
237; CHECK-LABEL: mul_stepvector_nxv8i8:
238; CHECK:       // %bb.0: // %entry
239; CHECK-NEXT:    index z0.h, #0, #2
240; CHECK-NEXT:    ret
241entry:
242  %0 = insertelement <vscale x 8 x i8> poison, i8 2, i32 0
243  %1 = shufflevector <vscale x 8 x i8> %0, <vscale x 8 x i8> poison, <vscale x 8 x i32> zeroinitializer
244  %2 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
245  %3 = mul <vscale x 8 x i8> %2, %1
246  ret <vscale x 8 x i8> %3
247}
248
249define <vscale x 8 x i8> @shl_stepvector_nxv8i8() {
250; CHECK-LABEL: shl_stepvector_nxv8i8:
251; CHECK:       // %bb.0: // %entry
252; CHECK-NEXT:    index z0.h, #0, #4
253; CHECK-NEXT:    ret
254entry:
255  %0 = insertelement <vscale x 8 x i8> poison, i8 2, i32 0
256  %1 = shufflevector <vscale x 8 x i8> %0, <vscale x 8 x i8> poison, <vscale x 8 x i32> zeroinitializer
257  %2 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
258  %3 = shl <vscale x 8 x i8> %2, %1
259  ret <vscale x 8 x i8> %3
260}
261
262define <vscale x 8 x i16> @sub_multiple_use_stepvector_nxv8i16() {
263; CHECK-LABEL: sub_multiple_use_stepvector_nxv8i16:
264; CHECK:       // %bb.0: // %entry
265; CHECK-NEXT:    index z0.h, #0, #1
266; CHECK-NEXT:    mov z1.d, z0.d
267; CHECK-NEXT:    subr z1.h, z1.h, #2 // =0x2
268; CHECK-NEXT:    ptrue p0.h
269; CHECK-NEXT:    lsl z0.h, p0/m, z0.h, z1.h
270; CHECK-NEXT:    ret
271entry:
272  %0 = insertelement <vscale x 8 x i16> poison, i16 2, i32 0
273  %1 = shufflevector <vscale x 8 x i16> %0, <vscale x 8 x i16> poison, <vscale x 8 x i32> zeroinitializer
274  %2 = call <vscale x 8 x i16> @llvm.experimental.stepvector.nxv8i16()
275  %3 = sub <vscale x 8 x i16> %1, %2
276  %4 = shl <vscale x 8 x i16> %2, %3
277  ret <vscale x 8 x i16> %4
278}
279
280define <vscale x 8 x i16> @sub_stepvector_nxv8i16() {
281; CHECK-LABEL: sub_stepvector_nxv8i16:
282; CHECK:       // %bb.0: // %entry
283; CHECK-NEXT:    index z0.h, #2, #-1
284; CHECK-NEXT:    ret
285entry:
286  %0 = insertelement <vscale x 8 x i16> poison, i16 2, i32 0
287  %1 = shufflevector <vscale x 8 x i16> %0, <vscale x 8 x i16> poison, <vscale x 8 x i32> zeroinitializer
288  %2 = call <vscale x 8 x i16> @llvm.experimental.stepvector.nxv8i16()
289  %3 = sub <vscale x 8 x i16> %1, %2
290  ret <vscale x 8 x i16> %3
291}
292
293define <vscale x 8 x i8> @promote_sub_stepvector_nxv8i8() {
294; CHECK-LABEL: promote_sub_stepvector_nxv8i8:
295; CHECK:       // %bb.0: // %entry
296; CHECK-NEXT:    index z0.h, #2, #-1
297; CHECK-NEXT:    ret
298entry:
299  %0 = insertelement <vscale x 8 x i8> poison, i8 2, i32 0
300  %1 = shufflevector <vscale x 8 x i8> %0, <vscale x 8 x i8> poison, <vscale x 8 x i32> zeroinitializer
301  %2 = call <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
302  %3 = sub <vscale x 8 x i8> %1, %2
303  ret <vscale x 8 x i8> %3
304}
305
306define <vscale x 16 x i32> @split_sub_stepvector_nxv16i32() {
307; CHECK-LABEL: split_sub_stepvector_nxv16i32:
308; CHECK:       // %bb.0: // %entry
309; CHECK-NEXT:    cntw x9
310; CHECK-NEXT:    cnth x8
311; CHECK-NEXT:    neg x9, x9
312; CHECK-NEXT:    index z0.s, #0, #-1
313; CHECK-NEXT:    neg x8, x8
314; CHECK-NEXT:    mov z1.s, w9
315; CHECK-NEXT:    mov z3.s, w8
316; CHECK-NEXT:    add z1.s, z0.s, z1.s
317; CHECK-NEXT:    add z2.s, z0.s, z3.s
318; CHECK-NEXT:    add z3.s, z1.s, z3.s
319; CHECK-NEXT:    ret
320entry:
321  %0 = call <vscale x 16 x i32> @llvm.experimental.stepvector.nxv16i32()
322  %1 = sub <vscale x 16 x i32> zeroinitializer, %0
323  ret <vscale x 16 x i32> %1
324}
325
326declare <vscale x 2 x i64> @llvm.experimental.stepvector.nxv2i64()
327declare <vscale x 4 x i32> @llvm.experimental.stepvector.nxv4i32()
328declare <vscale x 8 x i16> @llvm.experimental.stepvector.nxv8i16()
329declare <vscale x 16 x i8> @llvm.experimental.stepvector.nxv16i8()
330
331declare <vscale x 4 x i64> @llvm.experimental.stepvector.nxv4i64()
332declare <vscale x 16 x i32> @llvm.experimental.stepvector.nxv16i32()
333declare <vscale x 2 x i32> @llvm.experimental.stepvector.nxv2i32()
334declare <vscale x 8 x i8> @llvm.experimental.stepvector.nxv8i8()
335declare <vscale x 4 x i16> @llvm.experimental.stepvector.nxv4i16()
336