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
6
7define 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
16}
17
18define 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
26}
27
28define 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
38}
39
40define 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
49}
50
51define 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
61}
62
63define 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
73}
74
75define 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
88}
89
90define 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
102}
103
104define 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
116}
117
118define 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
130}
131
132define 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
143}
144
145define 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
156}
157
158define 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
167}
168
169define 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
179}
180
181define 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
191}
192
193define 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
202}
203
204define 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
215}
216
217define 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
228}
229
230define 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
240}
241
242define 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
254}
255
256define 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
267}
268
269define 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
280}
281
282@global_b = external global i16, align 2
283
284define 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
296}
297
298define 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
311}
312
313; CHECK-LABEL: f24
314; CHECK-NOT: sxth
315; CHECK: smulbb
316define 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
325}
326
327; CHECK-LABEL: f25
328; CHECK-NOT: sxth
329; CHECK: smulbb
330define 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
338}
339
340; CHECK-LABEL: f25_b
341; CHECK-NOT: sxth
342; CHECK: smulbb
343define 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
351}
352
353; CHECK-LABEL: f26
354; CHECK-NOT: sxth
355; CHECK: {{smulbt | smultb}}
356define 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
363}
364
365; CHECK-LABEL: f26_b
366; CHECK-NOT: sxth
367; CHECK: {{smulbt | smultb}}
368define 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
375}
376
377; CHECK-LABEL: f27
378; CHECK-NOT: sxth
379; CHECK: smulbb
380; CHECK: {{smlabt | smlatb}}
381define 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
392}
393
394; CHECK-LABEL: f27_b
395; CHECK-NOT: sxth
396; CHECK: smulbb
397; CHECK: {{smlabt | smlatb}}
398define 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
409}
410
411