1 ; RUN: llc < %s -mtriple=aarch64-eabi | FileCheck %s
3 ; Convert mul x, pow2 to shift.
4 ; Convert mul x, pow2 +/- 1 to shift + add/sub.
5 ; Convert mul x, (pow2 + 1) * pow2 to shift + add + shift.
6 ; Lowering other positive constants are not supported yet.
8 define i32 @test2(i32 %x) {
10 ; CHECK: lsl w0, w0, #1
12 %mul = shl nsw i32 %x, 1
16 define i32 @test3(i32 %x) {
18 ; CHECK: add w0, w0, w0, lsl #1
20 %mul = mul nsw i32 %x, 3
24 define i32 @test4(i32 %x) {
26 ; CHECK: lsl w0, w0, #2
28 %mul = shl nsw i32 %x, 2
32 define i32 @test5(i32 %x) {
34 ; CHECK: add w0, w0, w0, lsl #2
37 %mul = mul nsw i32 %x, 5
41 define i32 @test6_32b(i32 %x) {
43 ; CHECK: add {{w[0-9]+}}, w0, w0, lsl #1
44 ; CHECK: lsl w0, {{w[0-9]+}}, #1
46 %mul = mul nsw i32 %x, 6
50 define i64 @test6_64b(i64 %x) {
51 ; CHECK-LABEL: test6_64b
52 ; CHECK: add {{x[0-9]+}}, x0, x0, lsl #1
53 ; CHECK: lsl x0, {{x[0-9]+}}, #1
55 %mul = mul nsw i64 %x, 6
59 ; mul that appears together with add, sub, s(z)ext is not supported to be
60 ; converted to the combination of lsl, add/sub yet.
61 define i64 @test6_umull(i32 %x) {
62 ; CHECK-LABEL: test6_umull
63 ; CHECK: umull x0, w0, {{w[0-9]+}}
65 %ext = zext i32 %x to i64
66 %mul = mul nsw i64 %ext, 6
70 define i64 @test6_smull(i32 %x) {
71 ; CHECK-LABEL: test6_smull
72 ; CHECK: smull x0, w0, {{w[0-9]+}}
74 %ext = sext i32 %x to i64
75 %mul = mul nsw i64 %ext, 6
79 define i32 @test6_madd(i32 %x, i32 %y) {
80 ; CHECK-LABEL: test6_madd
81 ; CHECK: madd w0, w0, {{w[0-9]+}}, w1
83 %mul = mul nsw i32 %x, 6
84 %add = add i32 %mul, %y
88 define i32 @test6_msub(i32 %x, i32 %y) {
89 ; CHECK-LABEL: test6_msub
90 ; CHECK: msub w0, w0, {{w[0-9]+}}, w1
92 %mul = mul nsw i32 %x, 6
93 %sub = sub i32 %y, %mul
97 define i64 @test6_umaddl(i32 %x, i64 %y) {
98 ; CHECK-LABEL: test6_umaddl
99 ; CHECK: umaddl x0, w0, {{w[0-9]+}}, x1
101 %ext = zext i32 %x to i64
102 %mul = mul nsw i64 %ext, 6
103 %add = add i64 %mul, %y
107 define i64 @test6_smaddl(i32 %x, i64 %y) {
108 ; CHECK-LABEL: test6_smaddl
109 ; CHECK: smaddl x0, w0, {{w[0-9]+}}, x1
111 %ext = sext i32 %x to i64
112 %mul = mul nsw i64 %ext, 6
113 %add = add i64 %mul, %y
117 define i64 @test6_umsubl(i32 %x, i64 %y) {
118 ; CHECK-LABEL: test6_umsubl
119 ; CHECK: umsubl x0, w0, {{w[0-9]+}}, x1
121 %ext = zext i32 %x to i64
122 %mul = mul nsw i64 %ext, 6
123 %sub = sub i64 %y, %mul
127 define i64 @test6_smsubl(i32 %x, i64 %y) {
128 ; CHECK-LABEL: test6_smsubl
129 ; CHECK: smsubl x0, w0, {{w[0-9]+}}, x1
131 %ext = sext i32 %x to i64
132 %mul = mul nsw i64 %ext, 6
133 %sub = sub i64 %y, %mul
137 define i64 @test6_umnegl(i32 %x) {
138 ; CHECK-LABEL: test6_umnegl
139 ; CHECK: umnegl x0, w0, {{w[0-9]+}}
141 %ext = zext i32 %x to i64
142 %mul = mul nsw i64 %ext, 6
143 %sub = sub i64 0, %mul
147 define i64 @test6_smnegl(i32 %x) {
148 ; CHECK-LABEL: test6_smnegl
149 ; CHECK: smnegl x0, w0, {{w[0-9]+}}
151 %ext = sext i32 %x to i64
152 %mul = mul nsw i64 %ext, 6
153 %sub = sub i64 0, %mul
157 define i32 @test7(i32 %x) {
159 ; CHECK: lsl {{w[0-9]+}}, w0, #3
160 ; CHECK: sub w0, {{w[0-9]+}}, w0
162 %mul = mul nsw i32 %x, 7
166 define i32 @test8(i32 %x) {
168 ; CHECK: lsl w0, w0, #3
170 %mul = shl nsw i32 %x, 3
174 define i32 @test9(i32 %x) {
176 ; CHECK: add w0, w0, w0, lsl #3
178 %mul = mul nsw i32 %x, 9
182 define i32 @test10(i32 %x) {
183 ; CHECK-LABEL: test10
184 ; CHECK: add {{w[0-9]+}}, w0, w0, lsl #2
185 ; CHECK: lsl w0, {{w[0-9]+}}, #1
187 %mul = mul nsw i32 %x, 10
191 define i32 @test11(i32 %x) {
192 ; CHECK-LABEL: test11
193 ; CHECK: mul w0, w0, {{w[0-9]+}}
195 %mul = mul nsw i32 %x, 11
199 define i32 @test12(i32 %x) {
200 ; CHECK-LABEL: test12
201 ; CHECK: add {{w[0-9]+}}, w0, w0, lsl #1
202 ; CHECK: lsl w0, {{w[0-9]+}}, #2
204 %mul = mul nsw i32 %x, 12
208 define i32 @test13(i32 %x) {
209 ; CHECK-LABEL: test13
210 ; CHECK: mul w0, w0, {{w[0-9]+}}
212 %mul = mul nsw i32 %x, 13
216 define i32 @test14(i32 %x) {
217 ; CHECK-LABEL: test14
218 ; CHECK: mul w0, w0, {{w[0-9]+}}
220 %mul = mul nsw i32 %x, 14
224 define i32 @test15(i32 %x) {
225 ; CHECK-LABEL: test15
226 ; CHECK: lsl {{w[0-9]+}}, w0, #4
227 ; CHECK: sub w0, {{w[0-9]+}}, w0
229 %mul = mul nsw i32 %x, 15
233 define i32 @test16(i32 %x) {
234 ; CHECK-LABEL: test16
235 ; CHECK: lsl w0, w0, #4
237 %mul = mul nsw i32 %x, 16
241 ; Convert mul x, -pow2 to shift.
242 ; Convert mul x, -(pow2 +/- 1) to shift + add/sub.
243 ; Lowering other negative constants are not supported yet.
245 define i32 @ntest2(i32 %x) {
246 ; CHECK-LABEL: ntest2
247 ; CHECK: neg w0, w0, lsl #1
249 %mul = mul nsw i32 %x, -2
253 define i32 @ntest3(i32 %x) {
254 ; CHECK-LABEL: ntest3
255 ; CHECK: sub w0, w0, w0, lsl #2
257 %mul = mul nsw i32 %x, -3
261 define i32 @ntest4(i32 %x) {
262 ; CHECK-LABEL: ntest4
263 ; CHECK:neg w0, w0, lsl #2
265 %mul = mul nsw i32 %x, -4
269 define i32 @ntest5(i32 %x) {
270 ; CHECK-LABEL: ntest5
271 ; CHECK: add {{w[0-9]+}}, w0, w0, lsl #2
272 ; CHECK: neg w0, {{w[0-9]+}}
273 %mul = mul nsw i32 %x, -5
277 define i32 @ntest6(i32 %x) {
278 ; CHECK-LABEL: ntest6
279 ; CHECK: mul w0, w0, {{w[0-9]+}}
281 %mul = mul nsw i32 %x, -6
285 define i32 @ntest7(i32 %x) {
286 ; CHECK-LABEL: ntest7
287 ; CHECK: sub w0, w0, w0, lsl #3
289 %mul = mul nsw i32 %x, -7
293 define i32 @ntest8(i32 %x) {
294 ; CHECK-LABEL: ntest8
295 ; CHECK: neg w0, w0, lsl #3
297 %mul = mul nsw i32 %x, -8
301 define i32 @ntest9(i32 %x) {
302 ; CHECK-LABEL: ntest9
303 ; CHECK: add {{w[0-9]+}}, w0, w0, lsl #3
304 ; CHECK: neg w0, {{w[0-9]+}}
306 %mul = mul nsw i32 %x, -9
310 define i32 @ntest10(i32 %x) {
311 ; CHECK-LABEL: ntest10
312 ; CHECK: mul w0, w0, {{w[0-9]+}}
314 %mul = mul nsw i32 %x, -10
318 define i32 @ntest11(i32 %x) {
319 ; CHECK-LABEL: ntest11
320 ; CHECK: mul w0, w0, {{w[0-9]+}}
322 %mul = mul nsw i32 %x, -11
326 define i32 @ntest12(i32 %x) {
327 ; CHECK-LABEL: ntest12
328 ; CHECK: mul w0, w0, {{w[0-9]+}}
330 %mul = mul nsw i32 %x, -12
334 define i32 @ntest13(i32 %x) {
335 ; CHECK-LABEL: ntest13
336 ; CHECK: mul w0, w0, {{w[0-9]+}}
337 %mul = mul nsw i32 %x, -13
341 define i32 @ntest14(i32 %x) {
342 ; CHECK-LABEL: ntest14
343 ; CHECK: mul w0, w0, {{w[0-9]+}}
345 %mul = mul nsw i32 %x, -14
349 define i32 @ntest15(i32 %x) {
350 ; CHECK-LABEL: ntest15
351 ; CHECK: sub w0, w0, w0, lsl #4
353 %mul = mul nsw i32 %x, -15
357 define i32 @ntest16(i32 %x) {
358 ; CHECK-LABEL: ntest16
359 ; CHECK: neg w0, w0, lsl #4
361 %mul = mul nsw i32 %x, -16