1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2 ; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve -verify-machineinstrs < %s | FileCheck %s -check-prefix=NO_SCALAR_INC
3 ; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve -mattr=+use-scalar-inc-vl -verify-machineinstrs < %s | FileCheck %s
4 ; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve2 -verify-machineinstrs < %s | FileCheck %s
6 define <vscale x 8 x i16> @inch_vec(<vscale x 8 x i16> %a) {
7 ; NO_SCALAR_INC-LABEL: inch_vec:
8 ; NO_SCALAR_INC: // %bb.0:
9 ; NO_SCALAR_INC-NEXT: inch z0.h
10 ; NO_SCALAR_INC-NEXT: ret
12 ; CHECK-LABEL: inch_vec:
14 ; CHECK-NEXT: inch z0.h
16 %vscale = call i16 @llvm.vscale.i16()
17 %mul = mul i16 %vscale, 8
18 %vl = insertelement <vscale x 8 x i16> undef, i16 %mul, i32 0
19 %vl.splat = shufflevector <vscale x 8 x i16> %vl, <vscale x 8 x i16> undef, <vscale x 8 x i32> zeroinitializer
20 %res = add <vscale x 8 x i16> %a, %vl.splat
21 ret <vscale x 8 x i16> %res
24 define <vscale x 4 x i32> @incw_vec(<vscale x 4 x i32> %a) {
25 ; NO_SCALAR_INC-LABEL: incw_vec:
26 ; NO_SCALAR_INC: // %bb.0:
27 ; NO_SCALAR_INC-NEXT: incw z0.s
28 ; NO_SCALAR_INC-NEXT: ret
30 ; CHECK-LABEL: incw_vec:
32 ; CHECK-NEXT: incw z0.s
34 %vscale = call i32 @llvm.vscale.i32()
35 %mul = mul i32 %vscale, 4
36 %vl = insertelement <vscale x 4 x i32> undef, i32 %mul, i32 0
37 %vl.splat = shufflevector <vscale x 4 x i32> %vl, <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer
38 %res = add <vscale x 4 x i32> %a, %vl.splat
39 ret <vscale x 4 x i32> %res
42 define <vscale x 2 x i64> @incd_vec(<vscale x 2 x i64> %a) {
43 ; NO_SCALAR_INC-LABEL: incd_vec:
44 ; NO_SCALAR_INC: // %bb.0:
45 ; NO_SCALAR_INC-NEXT: incd z0.d
46 ; NO_SCALAR_INC-NEXT: ret
48 ; CHECK-LABEL: incd_vec:
50 ; CHECK-NEXT: incd z0.d
52 %vscale = call i64 @llvm.vscale.i64()
53 %mul = mul i64 %vscale, 2
54 %vl = insertelement <vscale x 2 x i64> undef, i64 %mul, i32 0
55 %vl.splat = shufflevector <vscale x 2 x i64> %vl, <vscale x 2 x i64> undef, <vscale x 2 x i32> zeroinitializer
56 %res = add <vscale x 2 x i64> %a, %vl.splat
57 ret <vscale x 2 x i64> %res
60 define <vscale x 8 x i16> @dech_vec(<vscale x 8 x i16> %a) {
61 ; NO_SCALAR_INC-LABEL: dech_vec:
62 ; NO_SCALAR_INC: // %bb.0:
63 ; NO_SCALAR_INC-NEXT: dech z0.h, all, mul #2
64 ; NO_SCALAR_INC-NEXT: ret
66 ; CHECK-LABEL: dech_vec:
68 ; CHECK-NEXT: dech z0.h, all, mul #2
70 %vscale = call i16 @llvm.vscale.i16()
71 %mul = mul i16 %vscale, 16
72 %vl = insertelement <vscale x 8 x i16> undef, i16 %mul, i32 0
73 %vl.splat = shufflevector <vscale x 8 x i16> %vl, <vscale x 8 x i16> undef, <vscale x 8 x i32> zeroinitializer
74 %res = sub <vscale x 8 x i16> %a, %vl.splat
75 ret <vscale x 8 x i16> %res
78 define <vscale x 4 x i32> @decw_vec(<vscale x 4 x i32> %a) {
79 ; NO_SCALAR_INC-LABEL: decw_vec:
80 ; NO_SCALAR_INC: // %bb.0:
81 ; NO_SCALAR_INC-NEXT: decw z0.s, all, mul #4
82 ; NO_SCALAR_INC-NEXT: ret
84 ; CHECK-LABEL: decw_vec:
86 ; CHECK-NEXT: decw z0.s, all, mul #4
88 %vscale = call i32 @llvm.vscale.i32()
89 %mul = mul i32 %vscale, 16
90 %vl = insertelement <vscale x 4 x i32> undef, i32 %mul, i32 0
91 %vl.splat = shufflevector <vscale x 4 x i32> %vl, <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer
92 %res = sub <vscale x 4 x i32> %a, %vl.splat
93 ret <vscale x 4 x i32> %res
96 define <vscale x 2 x i64> @decd_vec(<vscale x 2 x i64> %a) {
97 ; NO_SCALAR_INC-LABEL: decd_vec:
98 ; NO_SCALAR_INC: // %bb.0:
99 ; NO_SCALAR_INC-NEXT: decd z0.d, all, mul #8
100 ; NO_SCALAR_INC-NEXT: ret
102 ; CHECK-LABEL: decd_vec:
104 ; CHECK-NEXT: decd z0.d, all, mul #8
106 %vscale = call i64 @llvm.vscale.i64()
107 %mul = mul i64 %vscale, 16
108 %vl = insertelement <vscale x 2 x i64> undef, i64 %mul, i32 0
109 %vl.splat = shufflevector <vscale x 2 x i64> %vl, <vscale x 2 x i64> undef, <vscale x 2 x i32> zeroinitializer
110 %res = sub <vscale x 2 x i64> %a, %vl.splat
111 ret <vscale x 2 x i64> %res
114 ; NOTE: As there is no need for the predicate pattern we
115 ; fall back to using ADDVL with its larger immediate range.
116 define i64 @incb_scalar_i64(i64 %a) {
117 ; NO_SCALAR_INC-LABEL: incb_scalar_i64:
118 ; NO_SCALAR_INC: // %bb.0:
119 ; NO_SCALAR_INC-NEXT: rdvl x8, #1
120 ; NO_SCALAR_INC-NEXT: add x0, x0, x8
121 ; NO_SCALAR_INC-NEXT: ret
123 ; CHECK-LABEL: incb_scalar_i64:
125 ; CHECK-NEXT: addvl x0, x0, #1
127 %vscale = call i64 @llvm.vscale.i64()
128 %mul = mul i64 %vscale, 16
129 %add = add i64 %a, %mul
133 define i64 @inch_scalar_i64(i64 %a) {
134 ; NO_SCALAR_INC-LABEL: inch_scalar_i64:
135 ; NO_SCALAR_INC: // %bb.0:
136 ; NO_SCALAR_INC-NEXT: cnth x8
137 ; NO_SCALAR_INC-NEXT: add x0, x0, x8
138 ; NO_SCALAR_INC-NEXT: ret
140 ; CHECK-LABEL: inch_scalar_i64:
142 ; CHECK-NEXT: inch x0
144 %vscale = call i64 @llvm.vscale.i64()
145 %mul = mul i64 %vscale, 8
146 %add = add i64 %a, %mul
150 define i64 @incw_scalar_i64(i64 %a) {
151 ; NO_SCALAR_INC-LABEL: incw_scalar_i64:
152 ; NO_SCALAR_INC: // %bb.0:
153 ; NO_SCALAR_INC-NEXT: cntw x8
154 ; NO_SCALAR_INC-NEXT: add x0, x0, x8
155 ; NO_SCALAR_INC-NEXT: ret
157 ; CHECK-LABEL: incw_scalar_i64:
159 ; CHECK-NEXT: incw x0
161 %vscale = call i64 @llvm.vscale.i64()
162 %mul = mul i64 %vscale, 4
163 %add = add i64 %a, %mul
167 define i64 @incd_scalar_i64(i64 %a) {
168 ; NO_SCALAR_INC-LABEL: incd_scalar_i64:
169 ; NO_SCALAR_INC: // %bb.0:
170 ; NO_SCALAR_INC-NEXT: cntd x8
171 ; NO_SCALAR_INC-NEXT: add x0, x0, x8
172 ; NO_SCALAR_INC-NEXT: ret
174 ; CHECK-LABEL: incd_scalar_i64:
176 ; CHECK-NEXT: incd x0
178 %vscale = call i64 @llvm.vscale.i64()
179 %mul = mul i64 %vscale, 2
180 %add = add i64 %a, %mul
184 ; NOTE: As there is no need for the predicate pattern we
185 ; fall back to using ADDVL with its larger immediate range.
186 define i64 @decb_scalar_i64(i64 %a) {
187 ; NO_SCALAR_INC-LABEL: decb_scalar_i64:
188 ; NO_SCALAR_INC: // %bb.0:
189 ; NO_SCALAR_INC-NEXT: cnth x8, all, mul #4
190 ; NO_SCALAR_INC-NEXT: sub x0, x0, x8
191 ; NO_SCALAR_INC-NEXT: ret
193 ; CHECK-LABEL: decb_scalar_i64:
195 ; CHECK-NEXT: addvl x0, x0, #-2
197 %vscale = call i64 @llvm.vscale.i64()
198 %mul = mul i64 %vscale, 32
199 %sub = sub i64 %a, %mul
203 define i64 @dech_scalar_i64(i64 %a) {
204 ; NO_SCALAR_INC-LABEL: dech_scalar_i64:
205 ; NO_SCALAR_INC: // %bb.0:
206 ; NO_SCALAR_INC-NEXT: cnth x8, all, mul #3
207 ; NO_SCALAR_INC-NEXT: sub x0, x0, x8
208 ; NO_SCALAR_INC-NEXT: ret
210 ; CHECK-LABEL: dech_scalar_i64:
212 ; CHECK-NEXT: dech x0, all, mul #3
214 %vscale = call i64 @llvm.vscale.i64()
215 %mul = mul i64 %vscale, 24
216 %sub = sub i64 %a, %mul
220 define i64 @decw_scalar_i64(i64 %a) {
221 ; NO_SCALAR_INC-LABEL: decw_scalar_i64:
222 ; NO_SCALAR_INC: // %bb.0:
223 ; NO_SCALAR_INC-NEXT: cntw x8, all, mul #3
224 ; NO_SCALAR_INC-NEXT: sub x0, x0, x8
225 ; NO_SCALAR_INC-NEXT: ret
227 ; CHECK-LABEL: decw_scalar_i64:
229 ; CHECK-NEXT: decw x0, all, mul #3
231 %vscale = call i64 @llvm.vscale.i64()
232 %mul = mul i64 %vscale, 12
233 %sub = sub i64 %a, %mul
237 define i64 @decd_scalar_i64(i64 %a) {
238 ; NO_SCALAR_INC-LABEL: decd_scalar_i64:
239 ; NO_SCALAR_INC: // %bb.0:
240 ; NO_SCALAR_INC-NEXT: cntd x8, all, mul #3
241 ; NO_SCALAR_INC-NEXT: sub x0, x0, x8
242 ; NO_SCALAR_INC-NEXT: ret
244 ; CHECK-LABEL: decd_scalar_i64:
246 ; CHECK-NEXT: decd x0, all, mul #3
248 %vscale = call i64 @llvm.vscale.i64()
249 %mul = mul i64 %vscale, 6
250 %sub = sub i64 %a, %mul
254 ; NOTE: As there is no need for the predicate pattern we
255 ; fall back to using ADDVL with its larger immediate range.
256 define i32 @incb_scalar_i32(i32 %a) {
257 ; NO_SCALAR_INC-LABEL: incb_scalar_i32:
258 ; NO_SCALAR_INC: // %bb.0:
259 ; NO_SCALAR_INC-NEXT: rdvl x8, #3
260 ; NO_SCALAR_INC-NEXT: add w0, w0, w8
261 ; NO_SCALAR_INC-NEXT: ret
263 ; CHECK-LABEL: incb_scalar_i32:
265 ; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
266 ; CHECK-NEXT: addvl x0, x0, #3
267 ; CHECK-NEXT: // kill: def $w0 killed $w0 killed $x0
270 %vscale = call i64 @llvm.vscale.i64()
271 %mul = mul i64 %vscale, 48
272 %vl = trunc i64 %mul to i32
273 %add = add i32 %a, %vl
277 define i32 @inch_scalar_i32(i32 %a) {
278 ; NO_SCALAR_INC-LABEL: inch_scalar_i32:
279 ; NO_SCALAR_INC: // %bb.0:
280 ; NO_SCALAR_INC-NEXT: cnth x8, all, mul #7
281 ; NO_SCALAR_INC-NEXT: add w0, w0, w8
282 ; NO_SCALAR_INC-NEXT: ret
284 ; CHECK-LABEL: inch_scalar_i32:
286 ; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
287 ; CHECK-NEXT: inch x0, all, mul #7
288 ; CHECK-NEXT: // kill: def $w0 killed $w0 killed $x0
291 %vscale = call i64 @llvm.vscale.i64()
292 %mul = mul i64 %vscale, 56
293 %vl = trunc i64 %mul to i32
294 %add = add i32 %a, %vl
298 define i32 @incw_scalar_i32(i32 %a) {
299 ; NO_SCALAR_INC-LABEL: incw_scalar_i32:
300 ; NO_SCALAR_INC: // %bb.0:
301 ; NO_SCALAR_INC-NEXT: cntw x8, all, mul #7
302 ; NO_SCALAR_INC-NEXT: add w0, w0, w8
303 ; NO_SCALAR_INC-NEXT: ret
305 ; CHECK-LABEL: incw_scalar_i32:
307 ; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
308 ; CHECK-NEXT: incw x0, all, mul #7
309 ; CHECK-NEXT: // kill: def $w0 killed $w0 killed $x0
312 %vscale = call i64 @llvm.vscale.i64()
313 %mul = mul i64 %vscale, 28
314 %vl = trunc i64 %mul to i32
315 %add = add i32 %a, %vl
319 define i32 @incd_scalar_i32(i32 %a) {
320 ; NO_SCALAR_INC-LABEL: incd_scalar_i32:
321 ; NO_SCALAR_INC: // %bb.0:
322 ; NO_SCALAR_INC-NEXT: cntd x8, all, mul #7
323 ; NO_SCALAR_INC-NEXT: add w0, w0, w8
324 ; NO_SCALAR_INC-NEXT: ret
326 ; CHECK-LABEL: incd_scalar_i32:
328 ; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
329 ; CHECK-NEXT: incd x0, all, mul #7
330 ; CHECK-NEXT: // kill: def $w0 killed $w0 killed $x0
333 %vscale = call i64 @llvm.vscale.i64()
334 %mul = mul i64 %vscale, 14
335 %vl = trunc i64 %mul to i32
336 %add = add i32 %a, %vl
340 ; NOTE: As there is no need for the predicate pattern we
341 ; fall back to using ADDVL with its larger immediate range.
342 define i32 @decb_scalar_i32(i32 %a) {
343 ; NO_SCALAR_INC-LABEL: decb_scalar_i32:
344 ; NO_SCALAR_INC: // %bb.0:
345 ; NO_SCALAR_INC-NEXT: cnth x8, all, mul #8
346 ; NO_SCALAR_INC-NEXT: sub w0, w0, w8
347 ; NO_SCALAR_INC-NEXT: ret
349 ; CHECK-LABEL: decb_scalar_i32:
351 ; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
352 ; CHECK-NEXT: addvl x0, x0, #-4
353 ; CHECK-NEXT: // kill: def $w0 killed $w0 killed $x0
356 %vscale = call i64 @llvm.vscale.i64()
357 %mul = mul i64 %vscale, 64
358 %vl = trunc i64 %mul to i32
359 %sub = sub i32 %a, %vl
363 define i32 @dech_scalar_i32(i32 %a) {
364 ; NO_SCALAR_INC-LABEL: dech_scalar_i32:
365 ; NO_SCALAR_INC: // %bb.0:
366 ; NO_SCALAR_INC-NEXT: cnth x8
367 ; NO_SCALAR_INC-NEXT: sub w0, w0, w8
368 ; NO_SCALAR_INC-NEXT: ret
370 ; CHECK-LABEL: dech_scalar_i32:
372 ; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
373 ; CHECK-NEXT: dech x0
374 ; CHECK-NEXT: // kill: def $w0 killed $w0 killed $x0
377 %vscale = call i64 @llvm.vscale.i64()
378 %mul = mul i64 %vscale, 8
379 %vl = trunc i64 %mul to i32
380 %sub = sub i32 %a, %vl
384 define i32 @decw_scalar_i32(i32 %a) {
385 ; NO_SCALAR_INC-LABEL: decw_scalar_i32:
386 ; NO_SCALAR_INC: // %bb.0:
387 ; NO_SCALAR_INC-NEXT: cntw x8
388 ; NO_SCALAR_INC-NEXT: sub w0, w0, w8
389 ; NO_SCALAR_INC-NEXT: ret
391 ; CHECK-LABEL: decw_scalar_i32:
393 ; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
394 ; CHECK-NEXT: decw x0
395 ; CHECK-NEXT: // kill: def $w0 killed $w0 killed $x0
398 %vscale = call i64 @llvm.vscale.i64()
399 %mul = mul i64 %vscale, 4
400 %vl = trunc i64 %mul to i32
401 %sub = sub i32 %a, %vl
405 define i32 @decd_scalar_i32(i32 %a) {
406 ; NO_SCALAR_INC-LABEL: decd_scalar_i32:
407 ; NO_SCALAR_INC: // %bb.0:
408 ; NO_SCALAR_INC-NEXT: cntd x8
409 ; NO_SCALAR_INC-NEXT: sub w0, w0, w8
410 ; NO_SCALAR_INC-NEXT: ret
412 ; CHECK-LABEL: decd_scalar_i32:
414 ; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
415 ; CHECK-NEXT: decd x0
416 ; CHECK-NEXT: // kill: def $w0 killed $w0 killed $x0
418 %vscale = call i64 @llvm.vscale.i64()
419 %mul = mul i64 %vscale, 2
420 %vl = trunc i64 %mul to i32
421 %sub = sub i32 %a, %vl
425 declare i16 @llvm.vscale.i16()
426 declare i32 @llvm.vscale.i32()
427 declare i64 @llvm.vscale.i64()