[ARM] Cortex-M4 schedule additions
[llvm-complete.git] / test / CodeGen / ARM / smul.ll
blob7091f8d191483e5ca546c153ef63b01c57ebae7f
1 ; RUN: llc -mtriple=arm-eabi -mcpu=generic %s -o - | FileCheck %s --check-prefix=DISABLED
2 ; RUN: llc -mtriple=arm-eabi -mcpu=cortex-a8 %s -o - | FileCheck %s
3 ; RUN: llc -mtriple=thumb--none-eabi -mcpu=cortex-a8 %s -o - | FileCheck %s
4 ; RUN: llc -mtriple=thumbv6t2-none-eabi %s -o - | FileCheck %s
5 ; RUN: llc -mtriple=thumbv6-none-eabi %s -o - | FileCheck %s -check-prefix=DISABLED
7 define i32 @f1(i16 %x, i32 %y) {
8 ; CHECK-LABEL: f1:
9 ; CHECK-NOT: sxth
10 ; CHECK: {{smulbt r0, r0, r1|smultb r0, r1, r0}}
11 ; DISABLED-NOT: {{smulbt|smultb}}
12         %tmp1 = sext i16 %x to i32
13         %tmp2 = ashr i32 %y, 16
14         %tmp3 = mul i32 %tmp2, %tmp1
15         ret i32 %tmp3
18 define i32 @f2(i32 %x, i32 %y) {
19 ; CHECK-LABEL: f2:
20 ; CHECK: smultt
21 ; DISABLED-NOT: smultt
22         %tmp1 = ashr i32 %x, 16
23         %tmp3 = ashr i32 %y, 16
24         %tmp4 = mul i32 %tmp3, %tmp1
25         ret i32 %tmp4
28 define i32 @f3(i32 %a, i16 %x, i32 %y) {
29 ; CHECK-LABEL: f3:
30 ; CHECK-NOT: sxth
31 ; CHECK: {{smlabt r0, r1, r2, r0|smlatb r0, r2, r1, r0}}
32 ; DISABLED-NOT: {{smlabt|smlatb}}
33         %tmp = sext i16 %x to i32
34         %tmp2 = ashr i32 %y, 16
35         %tmp3 = mul i32 %tmp2, %tmp
36         %tmp5 = add i32 %tmp3, %a
37         ret i32 %tmp5
40 define i32 @f4(i32 %a, i32 %x, i32 %y) {
41 ; CHECK-LABEL: f4:
42 ; CHECK: smlatt
43 ; DISABLED-NOT: smlatt
44         %tmp1 = ashr i32 %x, 16
45         %tmp3 = ashr i32 %y, 16
46         %tmp4 = mul i32 %tmp3, %tmp1
47         %tmp5 = add i32 %tmp4, %a
48         ret i32 %tmp5
51 define i32 @f5(i32 %a, i16 %x, i16 %y) {
52 ; CHECK-LABEL: f5:
53 ; CHECK-NOT: sxth
54 ; CHECK: smlabb
55 ; DISABLED-NOT: smlabb
56         %tmp1 = sext i16 %x to i32
57         %tmp3 = sext i16 %y to i32
58         %tmp4 = mul i32 %tmp3, %tmp1
59         %tmp5 = add i32 %tmp4, %a
60         ret i32 %tmp5
63 define i32 @f6(i32 %a, i32 %x, i16 %y) {
64 ; CHECK-LABEL: f6:
65 ; CHECK-NOT: sxth
66 ; CHECK: {{smlatb r0, r1, r2, r0|smlabt r0, r2, r1, r0}}
67 ; DISABLED-NOT: {{smlatb|smlabt}}
68         %tmp1 = sext i16 %y to i32
69         %tmp2 = ashr i32 %x, 16
70         %tmp3 = mul i32 %tmp2, %tmp1
71         %tmp5 = add i32 %tmp3, %a
72         ret i32 %tmp5
75 define i32 @f7(i32 %a, i32 %b, i32 %c) {
76 ; CHECK-LABEL: f7:
77 ; CHECK: smlawb r0, r0, r1, r2
78 ; DISABLED-NOT: smlawb
79         %shl = shl i32 %b, 16
80         %shr = ashr exact i32 %shl, 16
81         %conv = sext i32 %a to i64
82         %conv2 = sext i32 %shr to i64
83         %mul = mul nsw i64 %conv2, %conv
84         %shr49 = lshr i64 %mul, 16
85         %conv5 = trunc i64 %shr49 to i32
86         %add = add nsw i32 %conv5, %c
87         ret i32 %add
90 define i32 @f8(i32 %a, i16 signext %b, i32 %c) {
91 ; CHECK-LABEL: f8:
92 ; CHECK-NOT: sxth
93 ; CHECK: smlawb r0, r0, r1, r2
94 ; DISABLED-NOT: smlawb
95         %conv = sext i32 %a to i64
96         %conv1 = sext i16 %b to i64
97         %mul = mul nsw i64 %conv1, %conv
98         %shr5 = lshr i64 %mul, 16
99         %conv2 = trunc i64 %shr5 to i32
100         %add = add nsw i32 %conv2, %c
101         ret i32 %add
104 define i32 @f9(i32 %a, i32 %b, i32 %c) {
105 ; CHECK-LABEL: f9:
106 ; CHECK: smlawt r0, r0, r1, r2
107 ; DISABLED-NOT: smlawt
108         %conv = sext i32 %a to i64
109         %shr = ashr i32 %b, 16
110         %conv1 = sext i32 %shr to i64
111         %mul = mul nsw i64 %conv1, %conv
112         %shr26 = lshr i64 %mul, 16
113         %conv3 = trunc i64 %shr26 to i32
114         %add = add nsw i32 %conv3, %c
115         ret i32 %add
118 define i32 @f10(i32 %a, i32 %b) {
119 ; CHECK-LABEL: f10:
120 ; CHECK: smulwb r0, r0, r1
121 ; DISABLED-NOT: smulwb
122         %shl = shl i32 %b, 16
123         %shr = ashr exact i32 %shl, 16
124         %conv = sext i32 %a to i64
125         %conv2 = sext i32 %shr to i64
126         %mul = mul nsw i64 %conv2, %conv
127         %shr37 = lshr i64 %mul, 16
128         %conv4 = trunc i64 %shr37 to i32
129         ret i32 %conv4
132 define i32 @f11(i32 %a, i16 signext %b) {
133 ; CHECK-LABEL: f11:
134 ; CHECK-NOT: sxth
135 ; CHECK: smulwb r0, r0, r1
136 ; DISABLED-NOT: smulwb
137         %conv = sext i32 %a to i64
138         %conv1 = sext i16 %b to i64
139         %mul = mul nsw i64 %conv1, %conv
140         %shr4 = lshr i64 %mul, 16
141         %conv2 = trunc i64 %shr4 to i32
142         ret i32 %conv2
145 define i32 @f12(i32 %a, i32 %b) {
146 ; CHECK-LABEL: f12:
147 ; CHECK: smulwt r0, r0, r1
148 ; DISABLED-NOT: smulwt
149         %conv = sext i32 %a to i64
150         %shr = ashr i32 %b, 16
151         %conv1 = sext i32 %shr to i64
152         %mul = mul nsw i64 %conv1, %conv
153         %shr25 = lshr i64 %mul, 16
154         %conv3 = trunc i64 %shr25 to i32
155         ret i32 %conv3
158 define i32 @f13(i32 %x, i16 %y) {
159 ; CHECK-LABEL: f13:
160 ; CHECK-NOT: sxth
161 ; CHECK: {{smultb r0, r0, r1|smulbt r0, r1, r0}}
162 ; DISABLED-NOT: {{smultb|smulbt}}
163         %tmp1 = sext i16 %y to i32
164         %tmp2 = ashr i32 %x, 16
165         %tmp3 = mul i32 %tmp2, %tmp1
166         ret i32 %tmp3
169 define i32 @f14(i32 %x, i32 %y) {
170 ; CHECK-LABEL: f14:
171 ; CHECK-NOT: sxth
172 ; CHECK: {{smultb r0, r1, r0|smulbt r0, r0, r1}}
173 ; DISABLED-NOT: {{smultb|smulbt}}
174         %tmp1 = shl i32 %x, 16
175         %tmp2 = ashr i32 %tmp1, 16
176         %tmp3 = ashr i32 %y, 16
177         %tmp4 = mul i32 %tmp3, %tmp2
178         ret i32 %tmp4
181 define i32 @f15(i32 %x, i32 %y) {
182 ; CHECK-LABEL: f15:
183 ; CHECK-NOT: sxth
184 ; CHECK: {{smulbt r0, r0, r1|smultb r0, r1, r0}}
185 ; DISABLED-NOT: {{smulbt|smultb}}
186         %tmp1 = shl i32 %x, 16
187         %tmp2 = ashr i32 %tmp1, 16
188         %tmp3 = ashr i32 %y, 16
189         %tmp4 = mul i32 %tmp2, %tmp3
190         ret i32 %tmp4
193 define i32 @f16(i16 %x, i16 %y) {
194 ; CHECK-LABEL: f16:
195 ; CHECK-NOT: sxth
196 ; CHECK: smulbb
197 ; DISABLED-NOT: smulbb
198         %tmp1 = sext i16 %x to i32
199         %tmp2 = sext i16 %x to i32
200         %tmp3 = mul i32 %tmp1, %tmp2
201         ret i32 %tmp3
204 define i32 @f17(i32 %x, i32 %y) {
205 ; CHECK-LABEL: f17:
206 ; CHECK-NOT: sxth
207 ; CHECK: smulbb
208 ; DISABLED-NOT: smulbb
209         %tmp1 = shl i32 %x, 16
210         %tmp2 = shl i32 %y, 16
211         %tmp3 = ashr i32 %tmp1, 16
212         %tmp4 = ashr i32 %tmp2, 16
213         %tmp5 = mul i32 %tmp3, %tmp4
214         ret i32 %tmp5
217 define i32 @f18(i32 %a, i32 %x, i32 %y) {
218 ; CHECK-LABEL: f18:
219 ; CHECK-NOT: sxth
220 ; CHECK: {{smlabt r0, r1, r2, r0|smlatb r0, r2, r1, r0}}
221 ; DISABLED-NOT: {{smlabt|smlatb}}
222         %tmp0 = shl i32 %x, 16
223         %tmp1 = ashr i32 %tmp0, 16
224         %tmp2 = ashr i32 %y, 16
225         %tmp3 = mul i32 %tmp2, %tmp1
226         %tmp5 = add i32 %tmp3, %a
227         ret i32 %tmp5
230 define i32 @f19(i32 %a, i32 %x, i32 %y) {
231 ; CHECK-LABEL: f19:
232 ; CHECK: {{smlatb r0, r2, r1, r0|smlabt r0, r1, r2, r0}}
233 ; DISABLED-NOT: {{smlatb|smlabt}}
234         %tmp0 = shl i32 %x, 16
235         %tmp1 = ashr i32 %tmp0, 16
236         %tmp2 = ashr i32 %y, 16
237         %tmp3 = mul i32 %tmp1, %tmp2
238         %tmp5 = add i32 %tmp3, %a
239         ret i32 %tmp5
242 define i32 @f20(i32 %a, i32 %x, i32 %y) {
243 ; CHECK-LABEL: f20:
244 ; CHECK-NOT: sxth
245 ; CHECK: smlabb
246 ; DISABLED-NOT: smlabb
247         %tmp1 = shl i32 %x, 16
248         %tmp2 = ashr i32 %tmp1, 16
249         %tmp3 = shl i32 %y, 16
250         %tmp4 = ashr i32 %tmp3, 16
251         %tmp5 = mul i32 %tmp2, %tmp4
252         %tmp6 = add i32 %tmp5, %a
253         ret i32 %tmp6
256 define i32 @f21(i32 %a, i32 %x, i16 %y) {
257 ; CHECK-LABEL: f21
258 ; CHECK-NOT: sxth
259 ; CHECK: smlabb
260 ; DISABLED-NOT: smlabb
261         %tmp1 = shl i32 %x, 16
262         %tmp2 = ashr i32 %tmp1, 16
263         %tmp3 = sext i16 %y to i32
264         %tmp4 = mul i32 %tmp2, %tmp3
265         %tmp5 = add i32 %a, %tmp4
266         ret i32 %tmp5
269 define i32 @f21_b(i32 %a, i32 %x, i16 %y) {
270 ; CHECK-LABEL: f21_b
271 ; CHECK-NOT: sxth
272 ; CHECK: smlabb
273 ; DISABLED-NOT: smlabb
274         %tmp1 = shl i32 %x, 16
275         %tmp2 = ashr i32 %tmp1, 16
276         %tmp3 = sext i16 %y to i32
277         %tmp4 = mul i32 %tmp3, %tmp2
278         %tmp5 = add i32 %a, %tmp4
279         ret i32 %tmp5
282 @global_b = external global i16, align 2
284 define i32 @f22(i32 %a) {
285 ; CHECK-LABEL: f22:
286 ; CHECK-NOT: sxth
287 ; CHECK: smulwb r0, r0, r1
288 ; DISABLED-NOT: smulwb
289         %b = load i16, i16* @global_b, align 2
290         %sext = sext i16 %b to i64
291         %conv = sext i32 %a to i64
292         %mul = mul nsw i64 %sext, %conv
293         %shr37 = lshr i64 %mul, 16
294         %conv4 = trunc i64 %shr37 to i32
295         ret i32 %conv4
298 define i32 @f23(i32 %a, i32 %c) {
299 ; CHECK-LABEL: f23:
300 ; CHECK-NOT: sxth
301 ; CHECK: smlawb r0, r0, r2, r1
302 ; DISABLED-NOT: smlawb
303         %b = load i16, i16* @global_b, align 2
304         %sext = sext i16 %b to i64
305         %conv = sext i32 %a to i64
306         %mul = mul nsw i64 %sext, %conv
307         %shr49 = lshr i64 %mul, 16
308         %conv5 = trunc i64 %shr49 to i32
309         %add = add nsw i32 %conv5, %c
310         ret i32 %add
313 ; CHECK-LABEL: f24
314 ; CHECK-NOT: sxth
315 ; CHECK: smulbb
316 define i32 @f24(i16* %a, i32* %b, i32* %c) {
317   %ld.0 = load i16, i16* %a, align 2
318   %ld.1 = load i32, i32* %b, align 4
319   %conv.0 = sext i16 %ld.0 to i32
320   %shift = shl i32 %ld.1, 16
321   %conv.1 = ashr i32 %shift, 16
322   %mul.0 = mul i32 %conv.0, %conv.1
323   store i32 %ld.1, i32* %c
324   ret i32 %mul.0
327 ; CHECK-LABEL: f25
328 ; CHECK-NOT: sxth
329 ; CHECK: smulbb
330 define i32 @f25(i16* %a, i32 %b, i32* %c) {
331   %ld.0 = load i16, i16* %a, align 2
332   %conv.0 = sext i16 %ld.0 to i32
333   %shift = shl i32 %b, 16
334   %conv.1 = ashr i32 %shift, 16
335   %mul.0 = mul i32 %conv.0, %conv.1
336   store i32 %b, i32* %c
337   ret i32 %mul.0
340 ; CHECK-LABEL: f25_b
341 ; CHECK-NOT: sxth
342 ; CHECK: smulbb
343 define i32 @f25_b(i16* %a, i32 %b, i32* %c) {
344   %ld.0 = load i16, i16* %a, align 2
345   %conv.0 = sext i16 %ld.0 to i32
346   %shift = shl i32 %b, 16
347   %conv.1 = ashr i32 %shift, 16
348   %mul.0 = mul i32 %conv.1, %conv.0
349   store i32 %b, i32* %c
350   ret i32 %mul.0
353 ; CHECK-LABEL: f26
354 ; CHECK-NOT: sxth
355 ; CHECK: {{smulbt | smultb}}
356 define i32 @f26(i16* %a, i32 %b, i32* %c) {
357   %ld.0 = load i16, i16* %a, align 2
358   %conv.0 = sext i16 %ld.0 to i32
359   %conv.1 = ashr i32 %b, 16
360   %mul.0 = mul i32 %conv.0, %conv.1
361   store i32 %b, i32* %c
362   ret i32 %mul.0
365 ; CHECK-LABEL: f26_b
366 ; CHECK-NOT: sxth
367 ; CHECK: {{smulbt | smultb}}
368 define i32 @f26_b(i16* %a, i32 %b, i32* %c) {
369   %ld.0 = load i16, i16* %a, align 2
370   %conv.0 = sext i16 %ld.0 to i32
371   %conv.1 = ashr i32 %b, 16
372   %mul.0 = mul i32 %conv.1, %conv.0
373   store i32 %b, i32* %c
374   ret i32 %mul.0
377 ; CHECK-LABEL: f27
378 ; CHECK-NOT: sxth
379 ; CHECK: smulbb
380 ; CHECK: {{smlabt | smlatb}}
381 define i32 @f27(i16* %a, i32* %b) {
382   %ld.0 = load i16, i16* %a, align 2
383   %ld.1 = load i32, i32* %b, align 4
384   %conv.0 = sext i16 %ld.0 to i32
385   %shift = shl i32 %ld.1, 16
386   %conv.1 = ashr i32 %shift, 16
387   %conv.2 = ashr i32 %ld.1, 16
388   %mul.0 = mul i32 %conv.0, %conv.1
389   %mul.1 = mul i32 %conv.0, %conv.2
390   %add = add i32 %mul.0, %mul.1
391   ret i32 %add
394 ; CHECK-LABEL: f27_b
395 ; CHECK-NOT: sxth
396 ; CHECK: smulbb
397 ; CHECK: {{smlabt | smlatb}}
398 define i32 @f27_b(i16* %a, i32* %b) {
399   %ld.0 = load i16, i16* %a, align 2
400   %ld.1 = load i32, i32* %b, align 4
401   %conv.0 = sext i16 %ld.0 to i32
402   %shift = shl i32 %ld.1, 16
403   %conv.1 = ashr i32 %shift, 16
404   %conv.2 = ashr i32 %ld.1, 16
405   %mul.0 = mul i32 %conv.0, %conv.1
406   %mul.1 = mul i32 %conv.2, %conv.0
407   %add = add i32 %mul.0, %mul.1
408   ret i32 %add