[PowerPC] Recommit r314244 with refactoring and off by default
[llvm-core.git] / test / CodeGen / X86 / imul.ll
blob7aa698e05709749832aded252a630c781b89f204
1 ; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu | FileCheck %s --check-prefix=X64
2 ; RUN: llc < %s -mtriple=x86_64-pc-linux-gnux32 | FileCheck %s --check-prefix=X64
3 ; RUN: llc < %s -mtriple=i686-pc-linux | FileCheck %s --check-prefix=X86
5 define i32 @mul4_32(i32 %A) {
6 ; X64-LABEL: mul4_32:
7 ; X64: leal
8 ; X86-LABEL: mul4_32:
9 ; X86: shll
10     %mul = mul i32 %A, 4
11     ret i32 %mul
14 define i64 @mul4_64(i64 %A) {
15 ; X64-LABEL: mul4_64:
16 ; X64: leaq
17 ; X86-LABEL: mul4_64:
18 ; X86: shldl
19 ; X86: shll
20     %mul = mul i64 %A, 4
21     ret i64 %mul
24 define i32 @mul4096_32(i32 %A) {
25 ; X64-LABEL: mul4096_32:
26 ; X64: shll
27 ; X86-LABEL: mul4096_32:
28 ; X86: shll
29     %mul = mul i32 %A, 4096
30     ret i32 %mul
33 define i64 @mul4096_64(i64 %A) {
34 ; X64-LABEL: mul4096_64:
35 ; X64: shlq
36 ; X86-LABEL: mul4096_64:
37 ; X86: shldl
38 ; X86: shll
39     %mul = mul i64 %A, 4096
40     ret i64 %mul
43 define i32 @mulmin4096_32(i32 %A) {
44 ; X64-LABEL: mulmin4096_32:
45 ; X64: shll
46 ; X64-NEXT: negl
47 ; X86-LABEL: mulmin4096_32:
48 ; X86: shll
49 ; X86-NEXT: negl
50     %mul = mul i32 %A, -4096
51     ret i32 %mul
54 define i64 @mulmin4096_64(i64 %A) {
55 ; X64-LABEL: mulmin4096_64:
56 ; X64: shlq
57 ; X64-NEXT: negq
58 ; X86-LABEL: mulmin4096_64:
59 ; X86: shldl
60 ; X86-NEXT: shll
61 ; X86-NEXT: xorl
62 ; X86-NEXT: negl
63 ; X86-NEXT: sbbl
64     %mul = mul i64 %A, -4096
65     ret i64 %mul
68 define i32 @mul3_32(i32 %A) {
69 ; X64-LABEL: mul3_32:
70 ; X64: leal
71 ; X86-LABEL: mul3_32:
72 ; But why?!
73 ; X86: imull
74     %mul = mul i32 %A, 3
75     ret i32 %mul
78 define i64 @mul3_64(i64 %A) {
79 ; X64-LABEL: mul3_64:
80 ; X64: leaq
81 ; X86-LABEL: mul3_64:
82 ; X86: mull
83 ; X86-NEXT: imull
84     %mul = mul i64 %A, 3
85     ret i64 %mul
88 define i32 @mul40_32(i32 %A) {
89 ; X64-LABEL: mul40_32:
90 ; X64: shll
91 ; X64-NEXT: leal
92 ; X86-LABEL: mul40_32:
93 ; X86: shll
94 ; X86-NEXT: leal
95     %mul = mul i32 %A, 40
96     ret i32 %mul
99 define i64 @mul40_64(i64 %A) {
100 ; X64-LABEL: mul40_64:
101 ; X64: shlq
102 ; X64-NEXT: leaq
103 ; X86-LABEL: mul40_64:
104 ; X86: leal
105 ; X86-NEXT: movl
106 ; X86-NEXT: mull
107 ; X86-NEXT: leal
108     %mul = mul i64 %A, 40
109     ret i64 %mul
112 define i32 @mul4_32_minsize(i32 %A) minsize {
113 ; X64-LABEL: mul4_32_minsize:
114 ; X64: leal
115 ; X86-LABEL: mul4_32_minsize:
116 ; X86: shll
117     %mul = mul i32 %A, 4
118     ret i32 %mul
121 define i32 @mul40_32_minsize(i32 %A) minsize {
122 ; X64-LABEL: mul40_32_minsize:
123 ; X64: imull
124 ; X86-LABEL: mul40_32_minsize:
125 ; X86: imull
126     %mul = mul i32 %A, 40
127     ret i32 %mul
130 define i32 @mul33_32(i32 %A) {
131 ; X64-LABEL: mul33_32:
132 ; X64: shll
133 ; X64-NEXT: leal
134 ; X86-LABEL: mul33_32:
135 ; X86: shll
136 ; X86-NEXT: addl
137     %mul = mul i32 %A, 33
138     ret i32 %mul
141 define i32 @mul31_32(i32 %A) {
142 ; X64-LABEL: mul31_32:
143 ; X64: shll
144 ; X64-NEXT: subl
145 ; X86-LABEL: mul31_32:
146 ; X86: shll
147 ; X86-NEXT: subl
148     %mul = mul i32 %A, 31
149     ret i32 %mul
152 define i32 @mul0_32(i32 %A) {
153 ; X64-LABEL: mul0_32:
154 ; X64: xorl     %eax, %eax
155     %mul = mul i32 %A, 0
156     ret i32 %mul
159 define i32 @mul4294967295_32(i32 %A) {
160 ; X64-LABEL: mul4294967295_32:
161 ; X64: negl     %edi
162 ; X64-NEXT:     movl    %edi, %eax
163     %mul = mul i32 %A, 4294967295
164     ret i32 %mul
167 define i64 @mul18446744073709551615_64(i64 %A) {
168 ; X64-LABEL: mul18446744073709551615_64:
169 ; X64: negq     %rdi
170 ; X64-NEXT:     movq    %rdi, %rax
171     %mul = mul i64 %A, 18446744073709551615
172     ret i64 %mul
175 define i32 @test(i32 %a) {
176 ; X64-LABEL: test:
177 ; X64:       # BB#0: # %entry
178 ; X64-NEXT:    movl %edi, %eax
179 ; X64-NEXT:    shll $5, %eax
180 ; X64-NEXT:    subl %edi, %eax
181 ; X64-NEXT:    retq
183 ; X86-LABEL: test:
184 ; X86:       # BB#0: # %entry
185 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
186 ; X86-NEXT:    movl %ecx, %eax
187 ; X86-NEXT:    shll $5, %eax
188 ; X86-NEXT:    subl %ecx, %eax
189 ; X86-NEXT:    retl
190 entry:
191         %tmp3 = mul i32 %a, 31
192         ret i32 %tmp3
195 define i32 @test1(i32 %a) {
196 ; X64-LABEL: test1:
197 ; X64:       # BB#0: # %entry
198 ; X64-NEXT:    movl %edi, %eax
199 ; X64-NEXT:    shll $5, %eax
200 ; X64-NEXT:    subl %edi, %eax
201 ; X64-NEXT:    negl %eax
202 ; X64-NEXT:    retq
204 ; X86-LABEL: test1:
205 ; X86:       # BB#0: # %entry
206 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
207 ; X86-NEXT:    movl %ecx, %eax
208 ; X86-NEXT:    shll $5, %eax
209 ; X86-NEXT:    subl %ecx, %eax
210 ; X86-NEXT:    negl %eax
211 ; X86-NEXT:    retl
212 entry:
213         %tmp3 = mul i32 %a, -31
214         ret i32 %tmp3
218 define i32 @test2(i32 %a) {
219 ; X64-LABEL: test2:
220 ; X64:       # BB#0: # %entry
221 ; X64-NEXT:    # kill: %edi<def> %edi<kill> %rdi<def>
222 ; X64-NEXT:    movl %edi, %eax
223 ; X64-NEXT:    shll $5, %eax
224 ; X64-NEXT:    leal (%rax,%rdi), %eax
225 ; X64-NEXT:    retq
227 ; X86-LABEL: test2:
228 ; X86:       # BB#0: # %entry
229 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
230 ; X86-NEXT:    movl %ecx, %eax
231 ; X86-NEXT:    shll $5, %eax
232 ; X86-NEXT:    addl %ecx, %eax
233 ; X86-NEXT:    retl
234 entry:
235         %tmp3 = mul i32 %a, 33
236         ret i32 %tmp3
239 define i32 @test3(i32 %a) {
240 ; X64-LABEL: test3:
241 ; X64:       # BB#0: # %entry
242 ; X64-NEXT:    # kill: %edi<def> %edi<kill> %rdi<def>
243 ; X64-NEXT:    movl %edi, %eax
244 ; X64-NEXT:    shll $5, %eax
245 ; X64-NEXT:    leal (%rax,%rdi), %eax
246 ; X64-NEXT:    negl %eax
247 ; X64-NEXT:    retq
249 ; X86-LABEL: test3:
250 ; X86:       # BB#0: # %entry
251 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
252 ; X86-NEXT:    movl %ecx, %eax
253 ; X86-NEXT:    shll $5, %eax
254 ; X86-NEXT:    addl %ecx, %eax
255 ; X86-NEXT:    negl %eax
256 ; X86-NEXT:    retl
257 entry:
258         %tmp3 = mul i32 %a, -33
259         ret i32 %tmp3
262 define i64 @test4(i64 %a) {
263 ; X64-LABEL: test4:
264 ; X64:       # BB#0: # %entry
265 ; X64-NEXT:    movq %rdi, %rax
266 ; X64-NEXT:    shlq $5, %rax
267 ; X64-NEXT:    subq %rdi, %rax
268 ; X64-NEXT:    retq
270 ; X86-LABEL: test4:
271 ; X86:       # BB#0: # %entry
272 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
273 ; X86-NEXT:    movl %eax, %ecx
274 ; X86-NEXT:    shll $5, %ecx
275 ; X86-NEXT:    subl %eax, %ecx
276 ; X86-NEXT:    movl $31, %eax
277 ; X86-NEXT:    mull {{[0-9]+}}(%esp)
278 ; X86-NEXT:    addl %ecx, %edx
279 ; X86-NEXT:    retl
280 entry:
281         %tmp3 = mul i64 %a, 31
282         ret i64 %tmp3
285 define i64 @test5(i64 %a) {
286 ; X64-LABEL: test5:
287 ; X64:       # BB#0: # %entry
288 ; X64-NEXT:    movq %rdi, %rax
289 ; X64-NEXT:    shlq $5, %rax
290 ; X64-NEXT:    subq %rdi, %rax
291 ; X64-NEXT:    negq %rax
292 ; X64-NEXT:    retq
294 ; X86-LABEL: test5:
295 ; X86:       # BB#0: # %entry
296 ; X86-NEXT:    pushl %esi
297 ; X86-NEXT:    .cfi_def_cfa_offset 8
298 ; X86-NEXT:    .cfi_offset %esi, -8
299 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
300 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
301 ; X86-NEXT:    movl %eax, %esi
302 ; X86-NEXT:    shll $5, %esi
303 ; X86-NEXT:    subl %eax, %esi
304 ; X86-NEXT:    movl $-31, %edx
305 ; X86-NEXT:    movl %ecx, %eax
306 ; X86-NEXT:    mull %edx
307 ; X86-NEXT:    subl %ecx, %edx
308 ; X86-NEXT:    subl %esi, %edx
309 ; X86-NEXT:    popl %esi
310 ; X86-NEXT:    retl
311 entry:
312         %tmp3 = mul i64 %a, -31
313         ret i64 %tmp3
317 define i64 @test6(i64 %a) {
318 ; X64-LABEL: test6:
319 ; X64:       # BB#0: # %entry
320 ; X64-NEXT:    movq %rdi, %rax
321 ; X64-NEXT:    shlq $5, %rax
322 ; X64-NEXT:    leaq (%rax,%rdi), %rax
323 ; X64-NEXT:    retq
325 ; X86-LABEL: test6:
326 ; X86:       # BB#0: # %entry
327 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
328 ; X86-NEXT:    movl %eax, %ecx
329 ; X86-NEXT:    shll $5, %ecx
330 ; X86-NEXT:    addl %eax, %ecx
331 ; X86-NEXT:    movl $33, %eax
332 ; X86-NEXT:    mull {{[0-9]+}}(%esp)
333 ; X86-NEXT:    addl %ecx, %edx
334 ; X86-NEXT:    retl
335 entry:
336         %tmp3 = mul i64 %a, 33
337         ret i64 %tmp3
340 define i64 @test7(i64 %a) {
341 ; X64-LABEL: test7:
342 ; X64:       # BB#0: # %entry
343 ; X64-NEXT:    movq %rdi, %rax
344 ; X64-NEXT:    shlq $5, %rax
345 ; X64-NEXT:    leaq (%rax,%rdi), %rax
346 ; X64-NEXT:    negq %rax
347 ; X64-NEXT:    retq
349 ; X86-LABEL: test7:
350 ; X86:       # BB#0: # %entry
351 ; X86-NEXT:    pushl %esi
352 ; X86-NEXT:    .cfi_def_cfa_offset 8
353 ; X86-NEXT:    .cfi_offset %esi, -8
354 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
355 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
356 ; X86-NEXT:    movl %eax, %esi
357 ; X86-NEXT:    shll $5, %esi
358 ; X86-NEXT:    addl %eax, %esi
359 ; X86-NEXT:    movl $-33, %edx
360 ; X86-NEXT:    movl %ecx, %eax
361 ; X86-NEXT:    mull %edx
362 ; X86-NEXT:    subl %ecx, %edx
363 ; X86-NEXT:    subl %esi, %edx
364 ; X86-NEXT:    popl %esi
365 ; X86-NEXT:    retl
366 entry:
367         %tmp3 = mul i64 %a, -33
368         ret i64 %tmp3
371 define i64 @testOverflow(i64 %a) {
372 ; X64-LABEL: testOverflow:
373 ; X64:       # BB#0: # %entry
374 ; X64-NEXT:    movabsq $9223372036854775807, %rax # imm = 0x7FFFFFFFFFFFFFFF
375 ; X64-NEXT:    imulq %rdi, %rax
376 ; X64-NEXT:    retq
378 ; X86-LABEL: testOverflow:
379 ; X86:       # BB#0: # %entry
380 ; X86-NEXT:    pushl %esi
381 ; X86-NEXT:    .cfi_def_cfa_offset 8
382 ; X86-NEXT:    .cfi_offset %esi, -8
383 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
384 ; X86-NEXT:    movl $-1, %edx
385 ; X86-NEXT:    movl %ecx, %eax
386 ; X86-NEXT:    mull %edx
387 ; X86-NEXT:    movl %ecx, %esi
388 ; X86-NEXT:    shll $31, %esi
389 ; X86-NEXT:    subl %ecx, %esi
390 ; X86-NEXT:    addl %esi, %edx
391 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %edx
392 ; X86-NEXT:    popl %esi
393 ; X86-NEXT:    retl
394 entry:
395         %tmp3 = mul i64 %a, 9223372036854775807
396         ret i64 %tmp3