1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-eabi | FileCheck %s
3 ; RUN: llc < %s -mtriple=aarch64-eabi -global-isel -global-isel-abort=1 | FileCheck %s --check-prefix=GISEL
5 ; Convert mul x, pow2 to shift.
6 ; Convert mul x, pow2 +/- 1 to shift + add/sub.
7 ; Convert mul x, (pow2 + 1) * pow2 to shift + add + shift.
8 ; Lowering other positive constants are not supported yet.
10 define i32 @test2(i32 %x) {
13 ; CHECK-NEXT: lsl w0, w0, #1
18 ; GISEL-NEXT: lsl w0, w0, #1
21 %mul = shl nsw i32 %x, 1
25 define i32 @test3(i32 %x) {
28 ; CHECK-NEXT: add w0, w0, w0, lsl #1
33 ; GISEL-NEXT: add w0, w0, w0, lsl #1
36 %mul = mul nsw i32 %x, 3
40 define i32 @test4(i32 %x) {
43 ; CHECK-NEXT: lsl w0, w0, #2
48 ; GISEL-NEXT: lsl w0, w0, #2
51 %mul = shl nsw i32 %x, 2
55 define i32 @test5(i32 %x) {
58 ; CHECK-NEXT: add w0, w0, w0, lsl #2
63 ; GISEL-NEXT: add w0, w0, w0, lsl #2
67 %mul = mul nsw i32 %x, 5
71 define i32 @test6_32b(i32 %x) {
72 ; CHECK-LABEL: test6_32b:
74 ; CHECK-NEXT: add w8, w0, w0, lsl #1
75 ; CHECK-NEXT: lsl w0, w8, #1
78 ; GISEL-LABEL: test6_32b:
80 ; GISEL-NEXT: add w8, w0, w0, lsl #1
81 ; GISEL-NEXT: lsl w0, w8, #1
84 %mul = mul nsw i32 %x, 6
88 define i64 @test6_64b(i64 %x) {
89 ; CHECK-LABEL: test6_64b:
91 ; CHECK-NEXT: add x8, x0, x0, lsl #1
92 ; CHECK-NEXT: lsl x0, x8, #1
95 ; GISEL-LABEL: test6_64b:
97 ; GISEL-NEXT: add x8, x0, x0, lsl #1
98 ; GISEL-NEXT: lsl x0, x8, #1
101 %mul = mul nsw i64 %x, 6
105 ; mul that appears together with add, sub, s(z)ext is not supported to be
106 ; converted to the combination of lsl, add/sub yet.
107 define i64 @test6_umull(i32 %x) {
108 ; CHECK-LABEL: test6_umull:
110 ; CHECK-NEXT: mov w8, #6
111 ; CHECK-NEXT: umull x0, w0, w8
114 ; GISEL-LABEL: test6_umull:
116 ; GISEL-NEXT: mov w8, #6
117 ; GISEL-NEXT: umull x0, w0, w8
120 %ext = zext i32 %x to i64
121 %mul = mul nsw i64 %ext, 6
125 define i64 @test6_smull(i32 %x) {
126 ; CHECK-LABEL: test6_smull:
128 ; CHECK-NEXT: mov w8, #6
129 ; CHECK-NEXT: smull x0, w0, w8
132 ; GISEL-LABEL: test6_smull:
134 ; GISEL-NEXT: mov w8, #6
135 ; GISEL-NEXT: smull x0, w0, w8
138 %ext = sext i32 %x to i64
139 %mul = mul nsw i64 %ext, 6
143 define i32 @test6_madd(i32 %x, i32 %y) {
144 ; CHECK-LABEL: test6_madd:
146 ; CHECK-NEXT: mov w8, #6
147 ; CHECK-NEXT: madd w0, w0, w8, w1
150 ; GISEL-LABEL: test6_madd:
152 ; GISEL-NEXT: mov w8, #6
153 ; GISEL-NEXT: madd w0, w0, w8, w1
156 %mul = mul nsw i32 %x, 6
157 %add = add i32 %mul, %y
161 define i32 @test6_msub(i32 %x, i32 %y) {
162 ; CHECK-LABEL: test6_msub:
164 ; CHECK-NEXT: mov w8, #6
165 ; CHECK-NEXT: msub w0, w0, w8, w1
168 ; GISEL-LABEL: test6_msub:
170 ; GISEL-NEXT: mov w8, #6
171 ; GISEL-NEXT: msub w0, w0, w8, w1
174 %mul = mul nsw i32 %x, 6
175 %sub = sub i32 %y, %mul
179 define i64 @test6_umaddl(i32 %x, i64 %y) {
180 ; CHECK-LABEL: test6_umaddl:
182 ; CHECK-NEXT: mov w8, #6
183 ; CHECK-NEXT: umaddl x0, w0, w8, x1
186 ; GISEL-LABEL: test6_umaddl:
188 ; GISEL-NEXT: mov w8, #6
189 ; GISEL-NEXT: umaddl x0, w0, w8, x1
192 %ext = zext i32 %x to i64
193 %mul = mul nsw i64 %ext, 6
194 %add = add i64 %mul, %y
198 define i64 @test6_smaddl(i32 %x, i64 %y) {
199 ; CHECK-LABEL: test6_smaddl:
201 ; CHECK-NEXT: mov w8, #6
202 ; CHECK-NEXT: smaddl x0, w0, w8, x1
205 ; GISEL-LABEL: test6_smaddl:
207 ; GISEL-NEXT: mov w8, #6
208 ; GISEL-NEXT: smaddl x0, w0, w8, x1
211 %ext = sext i32 %x to i64
212 %mul = mul nsw i64 %ext, 6
213 %add = add i64 %mul, %y
217 define i64 @test6_umsubl(i32 %x, i64 %y) {
218 ; CHECK-LABEL: test6_umsubl:
220 ; CHECK-NEXT: mov w8, #6
221 ; CHECK-NEXT: umsubl x0, w0, w8, x1
224 ; GISEL-LABEL: test6_umsubl:
226 ; GISEL-NEXT: mov w8, #6
227 ; GISEL-NEXT: umsubl x0, w0, w8, x1
230 %ext = zext i32 %x to i64
231 %mul = mul nsw i64 %ext, 6
232 %sub = sub i64 %y, %mul
236 define i64 @test6_smsubl(i32 %x, i64 %y) {
237 ; CHECK-LABEL: test6_smsubl:
239 ; CHECK-NEXT: mov w8, #6
240 ; CHECK-NEXT: smsubl x0, w0, w8, x1
243 ; GISEL-LABEL: test6_smsubl:
245 ; GISEL-NEXT: mov w8, #6
246 ; GISEL-NEXT: smsubl x0, w0, w8, x1
249 %ext = sext i32 %x to i64
250 %mul = mul nsw i64 %ext, 6
251 %sub = sub i64 %y, %mul
255 define i64 @test6_umnegl(i32 %x) {
256 ; CHECK-LABEL: test6_umnegl:
258 ; CHECK-NEXT: mov w8, #6
259 ; CHECK-NEXT: umnegl x0, w0, w8
262 ; GISEL-LABEL: test6_umnegl:
264 ; GISEL-NEXT: mov w8, #6
265 ; GISEL-NEXT: umnegl x0, w0, w8
268 %ext = zext i32 %x to i64
269 %mul = mul nsw i64 %ext, 6
270 %sub = sub i64 0, %mul
274 define i64 @test6_smnegl(i32 %x) {
275 ; CHECK-LABEL: test6_smnegl:
277 ; CHECK-NEXT: mov w8, #6
278 ; CHECK-NEXT: smnegl x0, w0, w8
281 ; GISEL-LABEL: test6_smnegl:
283 ; GISEL-NEXT: mov w8, #6
284 ; GISEL-NEXT: smnegl x0, w0, w8
287 %ext = sext i32 %x to i64
288 %mul = mul nsw i64 %ext, 6
289 %sub = sub i64 0, %mul
293 define i32 @test7(i32 %x) {
294 ; CHECK-LABEL: test7:
296 ; CHECK-NEXT: lsl w8, w0, #3
297 ; CHECK-NEXT: sub w0, w8, w0
300 ; GISEL-LABEL: test7:
302 ; GISEL-NEXT: lsl w8, w0, #3
303 ; GISEL-NEXT: sub w0, w8, w0
306 %mul = mul nsw i32 %x, 7
310 define i32 @test8(i32 %x) {
311 ; CHECK-LABEL: test8:
313 ; CHECK-NEXT: lsl w0, w0, #3
316 ; GISEL-LABEL: test8:
318 ; GISEL-NEXT: lsl w0, w0, #3
321 %mul = shl nsw i32 %x, 3
325 define i32 @test9(i32 %x) {
326 ; CHECK-LABEL: test9:
328 ; CHECK-NEXT: add w0, w0, w0, lsl #3
331 ; GISEL-LABEL: test9:
333 ; GISEL-NEXT: add w0, w0, w0, lsl #3
336 %mul = mul nsw i32 %x, 9
340 define i32 @test10(i32 %x) {
341 ; CHECK-LABEL: test10:
343 ; CHECK-NEXT: add w8, w0, w0, lsl #2
344 ; CHECK-NEXT: lsl w0, w8, #1
347 ; GISEL-LABEL: test10:
349 ; GISEL-NEXT: add w8, w0, w0, lsl #2
350 ; GISEL-NEXT: lsl w0, w8, #1
353 %mul = mul nsw i32 %x, 10
357 define i32 @test11(i32 %x) {
358 ; CHECK-LABEL: test11:
360 ; CHECK-NEXT: mov w8, #11
361 ; CHECK-NEXT: mul w0, w0, w8
364 ; GISEL-LABEL: test11:
366 ; GISEL-NEXT: mov w8, #11
367 ; GISEL-NEXT: mul w0, w0, w8
370 %mul = mul nsw i32 %x, 11
374 define i32 @test12(i32 %x) {
375 ; CHECK-LABEL: test12:
377 ; CHECK-NEXT: add w8, w0, w0, lsl #1
378 ; CHECK-NEXT: lsl w0, w8, #2
381 ; GISEL-LABEL: test12:
383 ; GISEL-NEXT: add w8, w0, w0, lsl #1
384 ; GISEL-NEXT: lsl w0, w8, #2
387 %mul = mul nsw i32 %x, 12
391 define i32 @test13(i32 %x) {
392 ; CHECK-LABEL: test13:
394 ; CHECK-NEXT: mov w8, #13
395 ; CHECK-NEXT: mul w0, w0, w8
398 ; GISEL-LABEL: test13:
400 ; GISEL-NEXT: mov w8, #13
401 ; GISEL-NEXT: mul w0, w0, w8
404 %mul = mul nsw i32 %x, 13
408 define i32 @test14(i32 %x) {
409 ; CHECK-LABEL: test14:
411 ; CHECK-NEXT: mov w8, #14
412 ; CHECK-NEXT: mul w0, w0, w8
415 ; GISEL-LABEL: test14:
417 ; GISEL-NEXT: mov w8, #14
418 ; GISEL-NEXT: mul w0, w0, w8
421 %mul = mul nsw i32 %x, 14
425 define i32 @test15(i32 %x) {
426 ; CHECK-LABEL: test15:
428 ; CHECK-NEXT: lsl w8, w0, #4
429 ; CHECK-NEXT: sub w0, w8, w0
432 ; GISEL-LABEL: test15:
434 ; GISEL-NEXT: lsl w8, w0, #4
435 ; GISEL-NEXT: sub w0, w8, w0
438 %mul = mul nsw i32 %x, 15
442 define i32 @test16(i32 %x) {
443 ; CHECK-LABEL: test16:
445 ; CHECK-NEXT: lsl w0, w0, #4
448 ; GISEL-LABEL: test16:
450 ; GISEL-NEXT: lsl w0, w0, #4
453 %mul = mul nsw i32 %x, 16
457 ; Convert mul x, -pow2 to shift.
458 ; Convert mul x, -(pow2 +/- 1) to shift + add/sub.
459 ; Lowering other negative constants are not supported yet.
461 define i32 @ntest2(i32 %x) {
462 ; CHECK-LABEL: ntest2:
464 ; CHECK-NEXT: neg w0, w0, lsl #1
467 ; GISEL-LABEL: ntest2:
469 ; GISEL-NEXT: mov w8, #-2
470 ; GISEL-NEXT: mul w0, w0, w8
473 %mul = mul nsw i32 %x, -2
477 define i32 @ntest3(i32 %x) {
478 ; CHECK-LABEL: ntest3:
480 ; CHECK-NEXT: sub w0, w0, w0, lsl #2
483 ; GISEL-LABEL: ntest3:
485 ; GISEL-NEXT: sub w0, w0, w0, lsl #2
488 %mul = mul nsw i32 %x, -3
492 define i32 @ntest4(i32 %x) {
493 ; CHECK-LABEL: ntest4:
495 ; CHECK-NEXT: neg w0, w0, lsl #2
498 ; GISEL-LABEL: ntest4:
500 ; GISEL-NEXT: mov w8, #-4
501 ; GISEL-NEXT: mul w0, w0, w8
504 %mul = mul nsw i32 %x, -4
508 define i32 @ntest5(i32 %x) {
509 ; CHECK-LABEL: ntest5:
511 ; CHECK-NEXT: add w8, w0, w0, lsl #2
512 ; CHECK-NEXT: neg w0, w8
515 ; GISEL-LABEL: ntest5:
517 ; GISEL-NEXT: add w8, w0, w0, lsl #2
518 ; GISEL-NEXT: neg w0, w8
520 %mul = mul nsw i32 %x, -5
524 define i32 @ntest6(i32 %x) {
525 ; CHECK-LABEL: ntest6:
527 ; CHECK-NEXT: mov w8, #-6
528 ; CHECK-NEXT: mul w0, w0, w8
531 ; GISEL-LABEL: ntest6:
533 ; GISEL-NEXT: mov w8, #-6
534 ; GISEL-NEXT: mul w0, w0, w8
537 %mul = mul nsw i32 %x, -6
541 define i32 @ntest7(i32 %x) {
542 ; CHECK-LABEL: ntest7:
544 ; CHECK-NEXT: sub w0, w0, w0, lsl #3
547 ; GISEL-LABEL: ntest7:
549 ; GISEL-NEXT: sub w0, w0, w0, lsl #3
552 %mul = mul nsw i32 %x, -7
556 define i32 @ntest8(i32 %x) {
557 ; CHECK-LABEL: ntest8:
559 ; CHECK-NEXT: neg w0, w0, lsl #3
562 ; GISEL-LABEL: ntest8:
564 ; GISEL-NEXT: mov w8, #-8
565 ; GISEL-NEXT: mul w0, w0, w8
568 %mul = mul nsw i32 %x, -8
572 define i32 @ntest9(i32 %x) {
573 ; CHECK-LABEL: ntest9:
575 ; CHECK-NEXT: add w8, w0, w0, lsl #3
576 ; CHECK-NEXT: neg w0, w8
579 ; GISEL-LABEL: ntest9:
581 ; GISEL-NEXT: add w8, w0, w0, lsl #3
582 ; GISEL-NEXT: neg w0, w8
585 %mul = mul nsw i32 %x, -9
589 define i32 @ntest10(i32 %x) {
590 ; CHECK-LABEL: ntest10:
592 ; CHECK-NEXT: mov w8, #-10
593 ; CHECK-NEXT: mul w0, w0, w8
596 ; GISEL-LABEL: ntest10:
598 ; GISEL-NEXT: mov w8, #-10
599 ; GISEL-NEXT: mul w0, w0, w8
602 %mul = mul nsw i32 %x, -10
606 define i32 @ntest11(i32 %x) {
607 ; CHECK-LABEL: ntest11:
609 ; CHECK-NEXT: mov w8, #-11
610 ; CHECK-NEXT: mul w0, w0, w8
613 ; GISEL-LABEL: ntest11:
615 ; GISEL-NEXT: mov w8, #-11
616 ; GISEL-NEXT: mul w0, w0, w8
619 %mul = mul nsw i32 %x, -11
623 define i32 @ntest12(i32 %x) {
624 ; CHECK-LABEL: ntest12:
626 ; CHECK-NEXT: mov w8, #-12
627 ; CHECK-NEXT: mul w0, w0, w8
630 ; GISEL-LABEL: ntest12:
632 ; GISEL-NEXT: mov w8, #-12
633 ; GISEL-NEXT: mul w0, w0, w8
636 %mul = mul nsw i32 %x, -12
640 define i32 @ntest13(i32 %x) {
641 ; CHECK-LABEL: ntest13:
643 ; CHECK-NEXT: mov w8, #-13
644 ; CHECK-NEXT: mul w0, w0, w8
647 ; GISEL-LABEL: ntest13:
649 ; GISEL-NEXT: mov w8, #-13
650 ; GISEL-NEXT: mul w0, w0, w8
652 %mul = mul nsw i32 %x, -13
656 define i32 @ntest14(i32 %x) {
657 ; CHECK-LABEL: ntest14:
659 ; CHECK-NEXT: mov w8, #-14
660 ; CHECK-NEXT: mul w0, w0, w8
663 ; GISEL-LABEL: ntest14:
665 ; GISEL-NEXT: mov w8, #-14
666 ; GISEL-NEXT: mul w0, w0, w8
669 %mul = mul nsw i32 %x, -14
673 define i32 @ntest15(i32 %x) {
674 ; CHECK-LABEL: ntest15:
676 ; CHECK-NEXT: sub w0, w0, w0, lsl #4
679 ; GISEL-LABEL: ntest15:
681 ; GISEL-NEXT: sub w0, w0, w0, lsl #4
684 %mul = mul nsw i32 %x, -15
688 define i32 @ntest16(i32 %x) {
689 ; CHECK-LABEL: ntest16:
691 ; CHECK-NEXT: neg w0, w0, lsl #4
694 ; GISEL-LABEL: ntest16:
696 ; GISEL-NEXT: mov w8, #-16
697 ; GISEL-NEXT: mul w0, w0, w8
700 %mul = mul nsw i32 %x, -16