Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / test / CodeGen / X86 / imul.ll
blob0288e61bdf38f2dbbd8ef8561c68fda53c4c14e7
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu | FileCheck %s --check-prefix=X64
3 ; RUN: llc < %s -mtriple=x86_64-pc-linux-gnux32 | FileCheck %s --check-prefix=X64
4 ; RUN: llc < %s -mtriple=i686-pc-linux | FileCheck %s --check-prefix=X86
6 define i32 @mul4_32(i32 %A) {
7 ; X64-LABEL: mul4_32:
8 ; X64:       # %bb.0:
9 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
10 ; X64-NEXT:    leal (,%rdi,4), %eax
11 ; X64-NEXT:    retq
13 ; X86-LABEL: mul4_32:
14 ; X86:       # %bb.0:
15 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
16 ; X86-NEXT:    shll $2, %eax
17 ; X86-NEXT:    retl
18     %mul = mul i32 %A, 4
19     ret i32 %mul
22 define i64 @mul4_64(i64 %A) {
23 ; X64-LABEL: mul4_64:
24 ; X64:       # %bb.0:
25 ; X64-NEXT:    leaq (,%rdi,4), %rax
26 ; X64-NEXT:    retq
28 ; X86-LABEL: mul4_64:
29 ; X86:       # %bb.0:
30 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
31 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
32 ; X86-NEXT:    shldl $2, %eax, %edx
33 ; X86-NEXT:    shll $2, %eax
34 ; X86-NEXT:    retl
35     %mul = mul i64 %A, 4
36     ret i64 %mul
39 define i32 @mul4096_32(i32 %A) {
40 ; X64-LABEL: mul4096_32:
41 ; X64:       # %bb.0:
42 ; X64-NEXT:    movl %edi, %eax
43 ; X64-NEXT:    shll $12, %eax
44 ; X64-NEXT:    retq
46 ; X86-LABEL: mul4096_32:
47 ; X86:       # %bb.0:
48 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
49 ; X86-NEXT:    shll $12, %eax
50 ; X86-NEXT:    retl
51     %mul = mul i32 %A, 4096
52     ret i32 %mul
55 define i64 @mul4096_64(i64 %A) {
56 ; X64-LABEL: mul4096_64:
57 ; X64:       # %bb.0:
58 ; X64-NEXT:    movq %rdi, %rax
59 ; X64-NEXT:    shlq $12, %rax
60 ; X64-NEXT:    retq
62 ; X86-LABEL: mul4096_64:
63 ; X86:       # %bb.0:
64 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
65 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
66 ; X86-NEXT:    shldl $12, %eax, %edx
67 ; X86-NEXT:    shll $12, %eax
68 ; X86-NEXT:    retl
69     %mul = mul i64 %A, 4096
70     ret i64 %mul
73 define i32 @mulmin4096_32(i32 %A) {
74 ; X64-LABEL: mulmin4096_32:
75 ; X64:       # %bb.0:
76 ; X64-NEXT:    movl %edi, %eax
77 ; X64-NEXT:    shll $12, %eax
78 ; X64-NEXT:    negl %eax
79 ; X64-NEXT:    retq
81 ; X86-LABEL: mulmin4096_32:
82 ; X86:       # %bb.0:
83 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
84 ; X86-NEXT:    shll $12, %eax
85 ; X86-NEXT:    negl %eax
86 ; X86-NEXT:    retl
87     %mul = mul i32 %A, -4096
88     ret i32 %mul
91 define i64 @mulmin4096_64(i64 %A) {
92 ; X64-LABEL: mulmin4096_64:
93 ; X64:       # %bb.0:
94 ; X64-NEXT:    movq %rdi, %rax
95 ; X64-NEXT:    shlq $12, %rax
96 ; X64-NEXT:    negq %rax
97 ; X64-NEXT:    retq
99 ; X86-LABEL: mulmin4096_64:
100 ; X86:       # %bb.0:
101 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
102 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
103 ; X86-NEXT:    shldl $12, %eax, %ecx
104 ; X86-NEXT:    shll $12, %eax
105 ; X86-NEXT:    xorl %edx, %edx
106 ; X86-NEXT:    negl %eax
107 ; X86-NEXT:    sbbl %ecx, %edx
108 ; X86-NEXT:    retl
109     %mul = mul i64 %A, -4096
110     ret i64 %mul
113 define i32 @mul3_32(i32 %A) {
114 ; X64-LABEL: mul3_32:
115 ; X64:       # %bb.0:
116 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
117 ; X64-NEXT:    leal (%rdi,%rdi,2), %eax
118 ; X64-NEXT:    retq
120 ; X86-LABEL: mul3_32:
121 ; X86:       # %bb.0:
122 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
123 ; X86-NEXT:    leal (%eax,%eax,2), %eax
124 ; X86-NEXT:    retl
125 ; But why?!
126     %mul = mul i32 %A, 3
127     ret i32 %mul
130 define i64 @mul3_64(i64 %A) {
131 ; X64-LABEL: mul3_64:
132 ; X64:       # %bb.0:
133 ; X64-NEXT:    leaq (%rdi,%rdi,2), %rax
134 ; X64-NEXT:    retq
136 ; X86-LABEL: mul3_64:
137 ; X86:       # %bb.0:
138 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
139 ; X86-NEXT:    leal (%eax,%eax,2), %ecx
140 ; X86-NEXT:    movl $3, %eax
141 ; X86-NEXT:    mull {{[0-9]+}}(%esp)
142 ; X86-NEXT:    addl %ecx, %edx
143 ; X86-NEXT:    retl
144     %mul = mul i64 %A, 3
145     ret i64 %mul
148 define i32 @mul40_32(i32 %A) {
149 ; X64-LABEL: mul40_32:
150 ; X64:       # %bb.0:
151 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
152 ; X64-NEXT:    shll $3, %edi
153 ; X64-NEXT:    leal (%rdi,%rdi,4), %eax
154 ; X64-NEXT:    retq
156 ; X86-LABEL: mul40_32:
157 ; X86:       # %bb.0:
158 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
159 ; X86-NEXT:    shll $3, %eax
160 ; X86-NEXT:    leal (%eax,%eax,4), %eax
161 ; X86-NEXT:    retl
162     %mul = mul i32 %A, 40
163     ret i32 %mul
166 define i64 @mul40_64(i64 %A) {
167 ; X64-LABEL: mul40_64:
168 ; X64:       # %bb.0:
169 ; X64-NEXT:    shlq $3, %rdi
170 ; X64-NEXT:    leaq (%rdi,%rdi,4), %rax
171 ; X64-NEXT:    retq
173 ; X86-LABEL: mul40_64:
174 ; X86:       # %bb.0:
175 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
176 ; X86-NEXT:    leal (%eax,%eax,4), %ecx
177 ; X86-NEXT:    movl $40, %eax
178 ; X86-NEXT:    mull {{[0-9]+}}(%esp)
179 ; X86-NEXT:    leal (%edx,%ecx,8), %edx
180 ; X86-NEXT:    retl
181     %mul = mul i64 %A, 40
182     ret i64 %mul
185 define i32 @mul4_32_minsize(i32 %A) minsize {
186 ; X64-LABEL: mul4_32_minsize:
187 ; X64:       # %bb.0:
188 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
189 ; X64-NEXT:    leal (,%rdi,4), %eax
190 ; X64-NEXT:    retq
192 ; X86-LABEL: mul4_32_minsize:
193 ; X86:       # %bb.0:
194 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
195 ; X86-NEXT:    shll $2, %eax
196 ; X86-NEXT:    retl
197     %mul = mul i32 %A, 4
198     ret i32 %mul
201 define i32 @mul40_32_minsize(i32 %A) minsize {
202 ; X64-LABEL: mul40_32_minsize:
203 ; X64:       # %bb.0:
204 ; X64-NEXT:    imull $40, %edi, %eax
205 ; X64-NEXT:    retq
207 ; X86-LABEL: mul40_32_minsize:
208 ; X86:       # %bb.0:
209 ; X86-NEXT:    imull $40, {{[0-9]+}}(%esp), %eax
210 ; X86-NEXT:    retl
211     %mul = mul i32 %A, 40
212     ret i32 %mul
215 define i32 @mul33_32(i32 %A) {
216 ; X64-LABEL: mul33_32:
217 ; X64:       # %bb.0:
218 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
219 ; X64-NEXT:    movl %edi, %eax
220 ; X64-NEXT:    shll $5, %eax
221 ; X64-NEXT:    leal (%rax,%rdi), %eax
222 ; X64-NEXT:    retq
224 ; X86-LABEL: mul33_32:
225 ; X86:       # %bb.0:
226 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
227 ; X86-NEXT:    movl %ecx, %eax
228 ; X86-NEXT:    shll $5, %eax
229 ; X86-NEXT:    addl %ecx, %eax
230 ; X86-NEXT:    retl
231     %mul = mul i32 %A, 33
232     ret i32 %mul
235 define i32 @mul31_32(i32 %A) {
236 ; X64-LABEL: mul31_32:
237 ; X64:       # %bb.0:
238 ; X64-NEXT:    movl %edi, %eax
239 ; X64-NEXT:    shll $5, %eax
240 ; X64-NEXT:    subl %edi, %eax
241 ; X64-NEXT:    retq
243 ; X86-LABEL: mul31_32:
244 ; X86:       # %bb.0:
245 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
246 ; X86-NEXT:    movl %ecx, %eax
247 ; X86-NEXT:    shll $5, %eax
248 ; X86-NEXT:    subl %ecx, %eax
249 ; X86-NEXT:    retl
250     %mul = mul i32 %A, 31
251     ret i32 %mul
254 define i32 @mul0_32(i32 %A) {
255 ; X64-LABEL: mul0_32:
256 ; X64:       # %bb.0:
257 ; X64-NEXT:    xorl %eax, %eax
258 ; X64-NEXT:    retq
260 ; X86-LABEL: mul0_32:
261 ; X86:       # %bb.0:
262 ; X86-NEXT:    xorl %eax, %eax
263 ; X86-NEXT:    retl
264     %mul = mul i32 %A, 0
265     ret i32 %mul
268 define i32 @mul4294967295_32(i32 %A) {
269 ; X64-LABEL: mul4294967295_32:
270 ; X64:       # %bb.0:
271 ; X64-NEXT:    movl %edi, %eax
272 ; X64-NEXT:    negl %eax
273 ; X64-NEXT:    retq
275 ; X86-LABEL: mul4294967295_32:
276 ; X86:       # %bb.0:
277 ; X86-NEXT:    xorl %eax, %eax
278 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
279 ; X86-NEXT:    retl
280     %mul = mul i32 %A, 4294967295
281     ret i32 %mul
284 define i64 @mul18446744073709551615_64(i64 %A) {
285 ; X64-LABEL: mul18446744073709551615_64:
286 ; X64:       # %bb.0:
287 ; X64-NEXT:    movq %rdi, %rax
288 ; X64-NEXT:    negq %rax
289 ; X64-NEXT:    retq
291 ; X86-LABEL: mul18446744073709551615_64:
292 ; X86:       # %bb.0:
293 ; X86-NEXT:    xorl %edx, %edx
294 ; X86-NEXT:    xorl %eax, %eax
295 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
296 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edx
297 ; X86-NEXT:    retl
298     %mul = mul i64 %A, 18446744073709551615
299     ret i64 %mul
302 define i32 @test(i32 %a) {
303 ; X64-LABEL: test:
304 ; X64:       # %bb.0: # %entry
305 ; X64-NEXT:    movl %edi, %eax
306 ; X64-NEXT:    shll $5, %eax
307 ; X64-NEXT:    subl %edi, %eax
308 ; X64-NEXT:    retq
310 ; X86-LABEL: test:
311 ; X86:       # %bb.0: # %entry
312 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
313 ; X86-NEXT:    movl %ecx, %eax
314 ; X86-NEXT:    shll $5, %eax
315 ; X86-NEXT:    subl %ecx, %eax
316 ; X86-NEXT:    retl
317 entry:
318         %tmp3 = mul i32 %a, 31
319         ret i32 %tmp3
322 define i32 @test1(i32 %a) {
323 ; X64-LABEL: test1:
324 ; X64:       # %bb.0: # %entry
325 ; X64-NEXT:    movl %edi, %eax
326 ; X64-NEXT:    movl %edi, %ecx
327 ; X64-NEXT:    shll $5, %ecx
328 ; X64-NEXT:    subl %ecx, %eax
329 ; X64-NEXT:    retq
331 ; X86-LABEL: test1:
332 ; X86:       # %bb.0: # %entry
333 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
334 ; X86-NEXT:    movl %eax, %ecx
335 ; X86-NEXT:    shll $5, %ecx
336 ; X86-NEXT:    subl %ecx, %eax
337 ; X86-NEXT:    retl
338 entry:
339         %tmp3 = mul i32 %a, -31
340         ret i32 %tmp3
344 define i32 @test2(i32 %a) {
345 ; X64-LABEL: test2:
346 ; X64:       # %bb.0: # %entry
347 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
348 ; X64-NEXT:    movl %edi, %eax
349 ; X64-NEXT:    shll $5, %eax
350 ; X64-NEXT:    leal (%rax,%rdi), %eax
351 ; X64-NEXT:    retq
353 ; X86-LABEL: test2:
354 ; X86:       # %bb.0: # %entry
355 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
356 ; X86-NEXT:    movl %ecx, %eax
357 ; X86-NEXT:    shll $5, %eax
358 ; X86-NEXT:    addl %ecx, %eax
359 ; X86-NEXT:    retl
360 entry:
361         %tmp3 = mul i32 %a, 33
362         ret i32 %tmp3
365 define i32 @test3(i32 %a) {
366 ; X64-LABEL: test3:
367 ; X64:       # %bb.0: # %entry
368 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
369 ; X64-NEXT:    movl %edi, %eax
370 ; X64-NEXT:    shll $5, %eax
371 ; X64-NEXT:    leal (%rax,%rdi), %eax
372 ; X64-NEXT:    negl %eax
373 ; X64-NEXT:    retq
375 ; X86-LABEL: test3:
376 ; X86:       # %bb.0: # %entry
377 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
378 ; X86-NEXT:    movl %ecx, %eax
379 ; X86-NEXT:    shll $5, %eax
380 ; X86-NEXT:    addl %ecx, %eax
381 ; X86-NEXT:    negl %eax
382 ; X86-NEXT:    retl
383 entry:
384         %tmp3 = mul i32 %a, -33
385         ret i32 %tmp3
388 define i64 @test4(i64 %a) {
389 ; X64-LABEL: test4:
390 ; X64:       # %bb.0: # %entry
391 ; X64-NEXT:    movq %rdi, %rax
392 ; X64-NEXT:    shlq $5, %rax
393 ; X64-NEXT:    subq %rdi, %rax
394 ; X64-NEXT:    retq
396 ; X86-LABEL: test4:
397 ; X86:       # %bb.0: # %entry
398 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
399 ; X86-NEXT:    movl %eax, %ecx
400 ; X86-NEXT:    shll $5, %ecx
401 ; X86-NEXT:    subl %eax, %ecx
402 ; X86-NEXT:    movl $31, %eax
403 ; X86-NEXT:    mull {{[0-9]+}}(%esp)
404 ; X86-NEXT:    addl %ecx, %edx
405 ; X86-NEXT:    retl
406 entry:
407         %tmp3 = mul i64 %a, 31
408         ret i64 %tmp3
411 define i64 @test5(i64 %a) {
412 ; X64-LABEL: test5:
413 ; X64:       # %bb.0: # %entry
414 ; X64-NEXT:    movq %rdi, %rax
415 ; X64-NEXT:    movq %rdi, %rcx
416 ; X64-NEXT:    shlq $5, %rcx
417 ; X64-NEXT:    subq %rcx, %rax
418 ; X64-NEXT:    retq
420 ; X86-LABEL: test5:
421 ; X86:       # %bb.0: # %entry
422 ; X86-NEXT:    pushl %esi
423 ; X86-NEXT:    .cfi_def_cfa_offset 8
424 ; X86-NEXT:    .cfi_offset %esi, -8
425 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
426 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
427 ; X86-NEXT:    movl %esi, %eax
428 ; X86-NEXT:    shll $5, %eax
429 ; X86-NEXT:    subl %eax, %esi
430 ; X86-NEXT:    movl $-31, %edx
431 ; X86-NEXT:    movl %ecx, %eax
432 ; X86-NEXT:    mull %edx
433 ; X86-NEXT:    subl %ecx, %edx
434 ; X86-NEXT:    addl %esi, %edx
435 ; X86-NEXT:    popl %esi
436 ; X86-NEXT:    .cfi_def_cfa_offset 4
437 ; X86-NEXT:    retl
438 entry:
439         %tmp3 = mul i64 %a, -31
440         ret i64 %tmp3
444 define i64 @test6(i64 %a) {
445 ; X64-LABEL: test6:
446 ; X64:       # %bb.0: # %entry
447 ; X64-NEXT:    movq %rdi, %rax
448 ; X64-NEXT:    shlq $5, %rax
449 ; X64-NEXT:    leaq (%rax,%rdi), %rax
450 ; X64-NEXT:    retq
452 ; X86-LABEL: test6:
453 ; X86:       # %bb.0: # %entry
454 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
455 ; X86-NEXT:    movl %eax, %ecx
456 ; X86-NEXT:    shll $5, %ecx
457 ; X86-NEXT:    addl %eax, %ecx
458 ; X86-NEXT:    movl $33, %eax
459 ; X86-NEXT:    mull {{[0-9]+}}(%esp)
460 ; X86-NEXT:    addl %ecx, %edx
461 ; X86-NEXT:    retl
462 entry:
463         %tmp3 = mul i64 %a, 33
464         ret i64 %tmp3
467 define i64 @test7(i64 %a) {
468 ; X64-LABEL: test7:
469 ; X64:       # %bb.0: # %entry
470 ; X64-NEXT:    movq %rdi, %rax
471 ; X64-NEXT:    shlq $5, %rax
472 ; X64-NEXT:    leaq (%rax,%rdi), %rax
473 ; X64-NEXT:    negq %rax
474 ; X64-NEXT:    retq
476 ; X86-LABEL: test7:
477 ; X86:       # %bb.0: # %entry
478 ; X86-NEXT:    pushl %esi
479 ; X86-NEXT:    .cfi_def_cfa_offset 8
480 ; X86-NEXT:    .cfi_offset %esi, -8
481 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
482 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
483 ; X86-NEXT:    movl %eax, %esi
484 ; X86-NEXT:    shll $5, %esi
485 ; X86-NEXT:    addl %eax, %esi
486 ; X86-NEXT:    movl $-33, %edx
487 ; X86-NEXT:    movl %ecx, %eax
488 ; X86-NEXT:    mull %edx
489 ; X86-NEXT:    subl %ecx, %edx
490 ; X86-NEXT:    subl %esi, %edx
491 ; X86-NEXT:    popl %esi
492 ; X86-NEXT:    .cfi_def_cfa_offset 4
493 ; X86-NEXT:    retl
494 entry:
495         %tmp3 = mul i64 %a, -33
496         ret i64 %tmp3
499 define i64 @testOverflow(i64 %a) {
500 ; X64-LABEL: testOverflow:
501 ; X64:       # %bb.0: # %entry
502 ; X64-NEXT:    movq %rdi, %rax
503 ; X64-NEXT:    shlq $63, %rax
504 ; X64-NEXT:    subq %rdi, %rax
505 ; X64-NEXT:    retq
507 ; X86-LABEL: testOverflow:
508 ; X86:       # %bb.0: # %entry
509 ; X86-NEXT:    pushl %esi
510 ; X86-NEXT:    .cfi_def_cfa_offset 8
511 ; X86-NEXT:    .cfi_offset %esi, -8
512 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
513 ; X86-NEXT:    movl $-1, %edx
514 ; X86-NEXT:    movl %ecx, %eax
515 ; X86-NEXT:    mull %edx
516 ; X86-NEXT:    movl %ecx, %esi
517 ; X86-NEXT:    shll $31, %esi
518 ; X86-NEXT:    subl %ecx, %esi
519 ; X86-NEXT:    addl %esi, %edx
520 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %edx
521 ; X86-NEXT:    popl %esi
522 ; X86-NEXT:    .cfi_def_cfa_offset 4
523 ; X86-NEXT:    retl
524 entry:
525         %tmp3 = mul i64 %a, 9223372036854775807
526         ret i64 %tmp3
529 define i64 @testNegOverflow(i64 %a) {
530 ; X64-LABEL: testNegOverflow:
531 ; X64:       # %bb.0: # %entry
532 ; X64-NEXT:    movq %rdi, %rax
533 ; X64-NEXT:    movq %rdi, %rcx
534 ; X64-NEXT:    shlq $63, %rcx
535 ; X64-NEXT:    subq %rcx, %rax
536 ; X64-NEXT:    retq
538 ; X86-LABEL: testNegOverflow:
539 ; X86:       # %bb.0: # %entry
540 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
541 ; X86-NEXT:    movl $1, %edx
542 ; X86-NEXT:    movl %ecx, %eax
543 ; X86-NEXT:    mull %edx
544 ; X86-NEXT:    shll $31, %ecx
545 ; X86-NEXT:    addl %ecx, %edx
546 ; X86-NEXT:    addl {{[0-9]+}}(%esp), %edx
547 ; X86-NEXT:    retl
548 entry:
549         %tmp3 = mul i64 %a, -9223372036854775807
550         ret i64 %tmp3