blob: 80a7b72008065b43eb24e5a1e14158dc2e93f9e7 [file] [log] [blame]
Simon Pilgrimfc4d4b22016-07-19 13:35:11 +00001; RUN: llc < %s -mtriple=aarch64-eabi | FileCheck %s
Chad Rosiere6b87612014-06-30 14:51:14 +00002
3; Convert mul x, pow2 to shift.
4; Convert mul x, pow2 +/- 1 to shift + add/sub.
Haicheng Wufaee2b72016-11-15 20:16:48 +00005; Convert mul x, (pow2 + 1) * pow2 to shift + add + shift.
6; Lowering other positive constants are not supported yet.
Chad Rosiere6b87612014-06-30 14:51:14 +00007
8define i32 @test2(i32 %x) {
9; CHECK-LABEL: test2
10; CHECK: lsl w0, w0, #1
11
12 %mul = shl nsw i32 %x, 1
13 ret i32 %mul
14}
15
16define i32 @test3(i32 %x) {
17; CHECK-LABEL: test3
18; CHECK: add w0, w0, w0, lsl #1
19
20 %mul = mul nsw i32 %x, 3
21 ret i32 %mul
22}
23
24define i32 @test4(i32 %x) {
25; CHECK-LABEL: test4
26; CHECK: lsl w0, w0, #2
27
28 %mul = shl nsw i32 %x, 2
29 ret i32 %mul
30}
31
32define i32 @test5(i32 %x) {
33; CHECK-LABEL: test5
34; CHECK: add w0, w0, w0, lsl #2
35
36
37 %mul = mul nsw i32 %x, 5
38 ret i32 %mul
39}
40
Haicheng Wufaee2b72016-11-15 20:16:48 +000041define i32 @test6_32b(i32 %x) {
42; CHECK-LABEL: test6
43; CHECK: add {{w[0-9]+}}, w0, w0, lsl #1
44; CHECK: lsl w0, {{w[0-9]+}}, #1
45
46 %mul = mul nsw i32 %x, 6
47 ret i32 %mul
48}
49
50define 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
54
55 %mul = mul nsw i64 %x, 6
56 ret i64 %mul
57}
58
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.
61define i64 @test6_umull(i32 %x) {
62; CHECK-LABEL: test6_umull
63; CHECK: umull x0, w0, {{w[0-9]+}}
64
65 %ext = zext i32 %x to i64
66 %mul = mul nsw i64 %ext, 6
67 ret i64 %mul
68}
69
70define i64 @test6_smull(i32 %x) {
71; CHECK-LABEL: test6_smull
72; CHECK: smull x0, w0, {{w[0-9]+}}
73
74 %ext = sext i32 %x to i64
75 %mul = mul nsw i64 %ext, 6
76 ret i64 %mul
77}
78
79define i32 @test6_madd(i32 %x, i32 %y) {
80; CHECK-LABEL: test6_madd
81; CHECK: madd w0, w0, {{w[0-9]+}}, w1
82
83 %mul = mul nsw i32 %x, 6
84 %add = add i32 %mul, %y
85 ret i32 %add
86}
87
88define i32 @test6_msub(i32 %x, i32 %y) {
89; CHECK-LABEL: test6_msub
90; CHECK: msub w0, w0, {{w[0-9]+}}, w1
91
92 %mul = mul nsw i32 %x, 6
93 %sub = sub i32 %y, %mul
94 ret i32 %sub
95}
96
97define i64 @test6_umaddl(i32 %x, i64 %y) {
98; CHECK-LABEL: test6_umaddl
99; CHECK: umaddl x0, w0, {{w[0-9]+}}, x1
100
101 %ext = zext i32 %x to i64
102 %mul = mul nsw i64 %ext, 6
103 %add = add i64 %mul, %y
104 ret i64 %add
105}
106
107define i64 @test6_smaddl(i32 %x, i64 %y) {
108; CHECK-LABEL: test6_smaddl
109; CHECK: smaddl x0, w0, {{w[0-9]+}}, x1
110
111 %ext = sext i32 %x to i64
112 %mul = mul nsw i64 %ext, 6
113 %add = add i64 %mul, %y
114 ret i64 %add
115}
116
117define i64 @test6_umsubl(i32 %x, i64 %y) {
118; CHECK-LABEL: test6_umsubl
119; CHECK: umsubl x0, w0, {{w[0-9]+}}, x1
120
121 %ext = zext i32 %x to i64
122 %mul = mul nsw i64 %ext, 6
123 %sub = sub i64 %y, %mul
124 ret i64 %sub
125}
126
127define i64 @test6_smsubl(i32 %x, i64 %y) {
128; CHECK-LABEL: test6_smsubl
129; CHECK: smsubl x0, w0, {{w[0-9]+}}, x1
130
131 %ext = sext i32 %x to i64
132 %mul = mul nsw i64 %ext, 6
133 %sub = sub i64 %y, %mul
134 ret i64 %sub
135}
136
137define i64 @test6_umnegl(i32 %x) {
138; CHECK-LABEL: test6_umnegl
139; CHECK: umnegl x0, w0, {{w[0-9]+}}
140
141 %ext = zext i32 %x to i64
142 %mul = mul nsw i64 %ext, 6
143 %sub = sub i64 0, %mul
144 ret i64 %sub
145}
146
147define i64 @test6_smnegl(i32 %x) {
148; CHECK-LABEL: test6_smnegl
149; CHECK: smnegl x0, w0, {{w[0-9]+}}
150
151 %ext = sext i32 %x to i64
152 %mul = mul nsw i64 %ext, 6
153 %sub = sub i64 0, %mul
154 ret i64 %sub
155}
156
Chad Rosiere6b87612014-06-30 14:51:14 +0000157define i32 @test7(i32 %x) {
158; CHECK-LABEL: test7
159; CHECK: lsl {{w[0-9]+}}, w0, #3
160; CHECK: sub w0, {{w[0-9]+}}, w0
161
162 %mul = mul nsw i32 %x, 7
163 ret i32 %mul
164}
165
166define i32 @test8(i32 %x) {
167; CHECK-LABEL: test8
168; CHECK: lsl w0, w0, #3
169
170 %mul = shl nsw i32 %x, 3
171 ret i32 %mul
172}
173
174define i32 @test9(i32 %x) {
175; CHECK-LABEL: test9
176; CHECK: add w0, w0, w0, lsl #3
177
Haicheng Wufaee2b72016-11-15 20:16:48 +0000178 %mul = mul nsw i32 %x, 9
179 ret i32 %mul
180}
181
182define 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
186
187 %mul = mul nsw i32 %x, 10
188 ret i32 %mul
189}
190
191define i32 @test11(i32 %x) {
192; CHECK-LABEL: test11
193; CHECK: mul w0, w0, {{w[0-9]+}}
194
195 %mul = mul nsw i32 %x, 11
196 ret i32 %mul
197}
198
199define 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
203
204 %mul = mul nsw i32 %x, 12
205 ret i32 %mul
206}
207
208define i32 @test13(i32 %x) {
209; CHECK-LABEL: test13
210; CHECK: mul w0, w0, {{w[0-9]+}}
211
212 %mul = mul nsw i32 %x, 13
213 ret i32 %mul
214}
215
216define i32 @test14(i32 %x) {
217; CHECK-LABEL: test14
218; CHECK: mul w0, w0, {{w[0-9]+}}
219
220 %mul = mul nsw i32 %x, 14
221 ret i32 %mul
222}
223
224define i32 @test15(i32 %x) {
225; CHECK-LABEL: test15
226; CHECK: lsl {{w[0-9]+}}, w0, #4
227; CHECK: sub w0, {{w[0-9]+}}, w0
228
229 %mul = mul nsw i32 %x, 15
230 ret i32 %mul
231}
232
233define i32 @test16(i32 %x) {
234; CHECK-LABEL: test16
235; CHECK: lsl w0, w0, #4
236
237 %mul = mul nsw i32 %x, 16
Chad Rosiere6b87612014-06-30 14:51:14 +0000238 ret i32 %mul
239}
240
241; Convert mul x, -pow2 to shift.
242; Convert mul x, -(pow2 +/- 1) to shift + add/sub.
Haicheng Wufaee2b72016-11-15 20:16:48 +0000243; Lowering other negative constants are not supported yet.
Chad Rosiere6b87612014-06-30 14:51:14 +0000244
245define i32 @ntest2(i32 %x) {
246; CHECK-LABEL: ntest2
247; CHECK: neg w0, w0, lsl #1
248
249 %mul = mul nsw i32 %x, -2
250 ret i32 %mul
251}
252
253define i32 @ntest3(i32 %x) {
254; CHECK-LABEL: ntest3
Chad Rosier8e38f302015-03-03 17:31:01 +0000255; CHECK: sub w0, w0, w0, lsl #2
Chad Rosiere6b87612014-06-30 14:51:14 +0000256
257 %mul = mul nsw i32 %x, -3
258 ret i32 %mul
259}
260
261define i32 @ntest4(i32 %x) {
262; CHECK-LABEL: ntest4
263; CHECK:neg w0, w0, lsl #2
264
265 %mul = mul nsw i32 %x, -4
266 ret i32 %mul
267}
268
269define 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
274 ret i32 %mul
275}
276
Haicheng Wufaee2b72016-11-15 20:16:48 +0000277define i32 @ntest6(i32 %x) {
278; CHECK-LABEL: ntest6
279; CHECK: mul w0, w0, {{w[0-9]+}}
280
281 %mul = mul nsw i32 %x, -6
282 ret i32 %mul
283}
284
Chad Rosiere6b87612014-06-30 14:51:14 +0000285define i32 @ntest7(i32 %x) {
286; CHECK-LABEL: ntest7
287; CHECK: sub w0, w0, w0, lsl #3
288
289 %mul = mul nsw i32 %x, -7
290 ret i32 %mul
291}
292
293define i32 @ntest8(i32 %x) {
294; CHECK-LABEL: ntest8
295; CHECK: neg w0, w0, lsl #3
296
297 %mul = mul nsw i32 %x, -8
298 ret i32 %mul
299}
300
301define 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]+}}
305
306 %mul = mul nsw i32 %x, -9
307 ret i32 %mul
308}
Haicheng Wufaee2b72016-11-15 20:16:48 +0000309
310define i32 @ntest10(i32 %x) {
311; CHECK-LABEL: ntest10
312; CHECK: mul w0, w0, {{w[0-9]+}}
313
314 %mul = mul nsw i32 %x, -10
315 ret i32 %mul
316}
317
318define i32 @ntest11(i32 %x) {
319; CHECK-LABEL: ntest11
320; CHECK: mul w0, w0, {{w[0-9]+}}
321
322 %mul = mul nsw i32 %x, -11
323 ret i32 %mul
324}
325
326define i32 @ntest12(i32 %x) {
327; CHECK-LABEL: ntest12
328; CHECK: mul w0, w0, {{w[0-9]+}}
329
330 %mul = mul nsw i32 %x, -12
331 ret i32 %mul
332}
333
334define i32 @ntest13(i32 %x) {
335; CHECK-LABEL: ntest13
336; CHECK: mul w0, w0, {{w[0-9]+}}
337 %mul = mul nsw i32 %x, -13
338 ret i32 %mul
339}
340
341define i32 @ntest14(i32 %x) {
342; CHECK-LABEL: ntest14
343; CHECK: mul w0, w0, {{w[0-9]+}}
344
345 %mul = mul nsw i32 %x, -14
346 ret i32 %mul
347}
348
349define i32 @ntest15(i32 %x) {
350; CHECK-LABEL: ntest15
351; CHECK: sub w0, w0, w0, lsl #4
352
353 %mul = mul nsw i32 %x, -15
354 ret i32 %mul
355}
356
357define i32 @ntest16(i32 %x) {
358; CHECK-LABEL: ntest16
359; CHECK: neg w0, w0, lsl #4
360
361 %mul = mul nsw i32 %x, -16
362 ret i32 %mul
363}