Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / X86 / imul.ll
blob9131688c4efcc1163c9a84c91ddbf67d1af25c28
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
5 ; At least one of the test cases in here crashed when linearizing the DAG.
6 ; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu -pre-RA-sched=linearize | FileCheck %s --check-prefix=X64
8 define i32 @mul4_32(i32 %A) {
9 ; X64-LABEL: mul4_32:
10 ; X64:       # %bb.0:
11 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
12 ; X64-NEXT:    leal (,%rdi,4), %eax
13 ; X64-NEXT:    retq
15 ; X86-LABEL: mul4_32:
16 ; X86:       # %bb.0:
17 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
18 ; X86-NEXT:    shll $2, %eax
19 ; X86-NEXT:    retl
20     %mul = mul i32 %A, 4
21     ret i32 %mul
24 define i64 @mul4_64(i64 %A) {
25 ; X64-LABEL: mul4_64:
26 ; X64:       # %bb.0:
27 ; X64-NEXT:    leaq (,%rdi,4), %rax
28 ; X64-NEXT:    retq
30 ; X86-LABEL: mul4_64:
31 ; X86:       # %bb.0:
32 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
33 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
34 ; X86-NEXT:    shldl $2, %eax, %edx
35 ; X86-NEXT:    shll $2, %eax
36 ; X86-NEXT:    retl
37     %mul = mul i64 %A, 4
38     ret i64 %mul
41 define i32 @mul4096_32(i32 %A) {
42 ; X64-LABEL: mul4096_32:
43 ; X64:       # %bb.0:
44 ; X64-NEXT:    movl %edi, %eax
45 ; X64-NEXT:    shll $12, %eax
46 ; X64-NEXT:    retq
48 ; X86-LABEL: mul4096_32:
49 ; X86:       # %bb.0:
50 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
51 ; X86-NEXT:    shll $12, %eax
52 ; X86-NEXT:    retl
53     %mul = mul i32 %A, 4096
54     ret i32 %mul
57 define i64 @mul4096_64(i64 %A) {
58 ; X64-LABEL: mul4096_64:
59 ; X64:       # %bb.0:
60 ; X64-NEXT:    movq %rdi, %rax
61 ; X64-NEXT:    shlq $12, %rax
62 ; X64-NEXT:    retq
64 ; X86-LABEL: mul4096_64:
65 ; X86:       # %bb.0:
66 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
67 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
68 ; X86-NEXT:    shldl $12, %eax, %edx
69 ; X86-NEXT:    shll $12, %eax
70 ; X86-NEXT:    retl
71     %mul = mul i64 %A, 4096
72     ret i64 %mul
75 define i32 @mulmin4096_32(i32 %A) {
76 ; X64-LABEL: mulmin4096_32:
77 ; X64:       # %bb.0:
78 ; X64-NEXT:    movl %edi, %eax
79 ; X64-NEXT:    shll $12, %eax
80 ; X64-NEXT:    negl %eax
81 ; X64-NEXT:    retq
83 ; X86-LABEL: mulmin4096_32:
84 ; X86:       # %bb.0:
85 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
86 ; X86-NEXT:    shll $12, %eax
87 ; X86-NEXT:    negl %eax
88 ; X86-NEXT:    retl
89     %mul = mul i32 %A, -4096
90     ret i32 %mul
93 define i64 @mulmin4096_64(i64 %A) {
94 ; X64-LABEL: mulmin4096_64:
95 ; X64:       # %bb.0:
96 ; X64-NEXT:    movq %rdi, %rax
97 ; X64-NEXT:    shlq $12, %rax
98 ; X64-NEXT:    negq %rax
99 ; X64-NEXT:    retq
101 ; X86-LABEL: mulmin4096_64:
102 ; X86:       # %bb.0:
103 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
104 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
105 ; X86-NEXT:    shldl $12, %eax, %ecx
106 ; X86-NEXT:    shll $12, %eax
107 ; X86-NEXT:    xorl %edx, %edx
108 ; X86-NEXT:    negl %eax
109 ; X86-NEXT:    sbbl %ecx, %edx
110 ; X86-NEXT:    retl
111     %mul = mul i64 %A, -4096
112     ret i64 %mul
115 define i32 @mul3_32(i32 %A) {
116 ; X64-LABEL: mul3_32:
117 ; X64:       # %bb.0:
118 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
119 ; X64-NEXT:    leal (%rdi,%rdi,2), %eax
120 ; X64-NEXT:    retq
122 ; X86-LABEL: mul3_32:
123 ; X86:       # %bb.0:
124 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
125 ; X86-NEXT:    leal (%eax,%eax,2), %eax
126 ; X86-NEXT:    retl
127 ; But why?!
128     %mul = mul i32 %A, 3
129     ret i32 %mul
132 define i64 @mul3_64(i64 %A) {
133 ; X64-LABEL: mul3_64:
134 ; X64:       # %bb.0:
135 ; X64-NEXT:    leaq (%rdi,%rdi,2), %rax
136 ; X64-NEXT:    retq
138 ; X86-LABEL: mul3_64:
139 ; X86:       # %bb.0:
140 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
141 ; X86-NEXT:    leal (%eax,%eax,2), %ecx
142 ; X86-NEXT:    movl $3, %eax
143 ; X86-NEXT:    mull {{[0-9]+}}(%esp)
144 ; X86-NEXT:    addl %ecx, %edx
145 ; X86-NEXT:    retl
146     %mul = mul i64 %A, 3
147     ret i64 %mul
150 define i32 @mul40_32(i32 %A) {
151 ; X64-LABEL: mul40_32:
152 ; X64:       # %bb.0:
153 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
154 ; X64-NEXT:    shll $3, %edi
155 ; X64-NEXT:    leal (%rdi,%rdi,4), %eax
156 ; X64-NEXT:    retq
158 ; X86-LABEL: mul40_32:
159 ; X86:       # %bb.0:
160 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
161 ; X86-NEXT:    shll $3, %eax
162 ; X86-NEXT:    leal (%eax,%eax,4), %eax
163 ; X86-NEXT:    retl
164     %mul = mul i32 %A, 40
165     ret i32 %mul
168 define i64 @mul40_64(i64 %A) {
169 ; X64-LABEL: mul40_64:
170 ; X64:       # %bb.0:
171 ; X64-NEXT:    shlq $3, %rdi
172 ; X64-NEXT:    leaq (%rdi,%rdi,4), %rax
173 ; X64-NEXT:    retq
175 ; X86-LABEL: mul40_64:
176 ; X86:       # %bb.0:
177 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
178 ; X86-NEXT:    leal (%eax,%eax,4), %ecx
179 ; X86-NEXT:    movl $40, %eax
180 ; X86-NEXT:    mull {{[0-9]+}}(%esp)
181 ; X86-NEXT:    leal (%edx,%ecx,8), %edx
182 ; X86-NEXT:    retl
183     %mul = mul i64 %A, 40
184     ret i64 %mul
187 define i32 @mul4_32_minsize(i32 %A) minsize {
188 ; X64-LABEL: mul4_32_minsize:
189 ; X64:       # %bb.0:
190 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
191 ; X64-NEXT:    leal (,%rdi,4), %eax
192 ; X64-NEXT:    retq
194 ; X86-LABEL: mul4_32_minsize:
195 ; X86:       # %bb.0:
196 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
197 ; X86-NEXT:    shll $2, %eax
198 ; X86-NEXT:    retl
199     %mul = mul i32 %A, 4
200     ret i32 %mul
203 define i32 @mul40_32_minsize(i32 %A) minsize {
204 ; X64-LABEL: mul40_32_minsize:
205 ; X64:       # %bb.0:
206 ; X64-NEXT:    imull $40, %edi, %eax
207 ; X64-NEXT:    retq
209 ; X86-LABEL: mul40_32_minsize:
210 ; X86:       # %bb.0:
211 ; X86-NEXT:    imull $40, {{[0-9]+}}(%esp), %eax
212 ; X86-NEXT:    retl
213     %mul = mul i32 %A, 40
214     ret i32 %mul
217 define i32 @mul33_32(i32 %A) {
218 ; X64-LABEL: mul33_32:
219 ; X64:       # %bb.0:
220 ; X64-NEXT:    movl %edi, %eax
221 ; X64-NEXT:    shll $5, %eax
222 ; X64-NEXT:    addl %edi, %eax
223 ; X64-NEXT:    retq
225 ; X86-LABEL: mul33_32:
226 ; X86:       # %bb.0:
227 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
228 ; X86-NEXT:    movl %ecx, %eax
229 ; X86-NEXT:    shll $5, %eax
230 ; X86-NEXT:    addl %ecx, %eax
231 ; X86-NEXT:    retl
232     %mul = mul i32 %A, 33
233     ret i32 %mul
236 define i32 @mul31_32(i32 %A) {
237 ; X64-LABEL: mul31_32:
238 ; X64:       # %bb.0:
239 ; X64-NEXT:    movl %edi, %eax
240 ; X64-NEXT:    shll $5, %eax
241 ; X64-NEXT:    subl %edi, %eax
242 ; X64-NEXT:    retq
244 ; X86-LABEL: mul31_32:
245 ; X86:       # %bb.0:
246 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
247 ; X86-NEXT:    movl %ecx, %eax
248 ; X86-NEXT:    shll $5, %eax
249 ; X86-NEXT:    subl %ecx, %eax
250 ; X86-NEXT:    retl
251     %mul = mul i32 %A, 31
252     ret i32 %mul
255 define i32 @mul0_32(i32 %A) {
256 ; X64-LABEL: mul0_32:
257 ; X64:       # %bb.0:
258 ; X64-NEXT:    xorl %eax, %eax
259 ; X64-NEXT:    retq
261 ; X86-LABEL: mul0_32:
262 ; X86:       # %bb.0:
263 ; X86-NEXT:    xorl %eax, %eax
264 ; X86-NEXT:    retl
265     %mul = mul i32 %A, 0
266     ret i32 %mul
269 define i32 @mul4294967295_32(i32 %A) {
270 ; X64-LABEL: mul4294967295_32:
271 ; X64:       # %bb.0:
272 ; X64-NEXT:    movl %edi, %eax
273 ; X64-NEXT:    negl %eax
274 ; X64-NEXT:    retq
276 ; X86-LABEL: mul4294967295_32:
277 ; X86:       # %bb.0:
278 ; X86-NEXT:    xorl %eax, %eax
279 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
280 ; X86-NEXT:    retl
281     %mul = mul i32 %A, 4294967295
282     ret i32 %mul
285 define i64 @mul18446744073709551615_64(i64 %A) {
286 ; X64-LABEL: mul18446744073709551615_64:
287 ; X64:       # %bb.0:
288 ; X64-NEXT:    movq %rdi, %rax
289 ; X64-NEXT:    negq %rax
290 ; X64-NEXT:    retq
292 ; X86-LABEL: mul18446744073709551615_64:
293 ; X86:       # %bb.0:
294 ; X86-NEXT:    xorl %edx, %edx
295 ; X86-NEXT:    xorl %eax, %eax
296 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
297 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edx
298 ; X86-NEXT:    retl
299     %mul = mul i64 %A, 18446744073709551615
300     ret i64 %mul
303 define i32 @test(i32 %a) {
304 ; X64-LABEL: test:
305 ; X64:       # %bb.0: # %entry
306 ; X64-NEXT:    movl %edi, %eax
307 ; X64-NEXT:    shll $5, %eax
308 ; X64-NEXT:    subl %edi, %eax
309 ; X64-NEXT:    retq
311 ; X86-LABEL: test:
312 ; X86:       # %bb.0: # %entry
313 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
314 ; X86-NEXT:    movl %ecx, %eax
315 ; X86-NEXT:    shll $5, %eax
316 ; X86-NEXT:    subl %ecx, %eax
317 ; X86-NEXT:    retl
318 entry:
319         %tmp3 = mul i32 %a, 31
320         ret i32 %tmp3
323 define i32 @test1(i32 %a) {
324 ; X64-LABEL: test1:
325 ; X64:       # %bb.0: # %entry
326 ; X64-NEXT:    movl %edi, %eax
327 ; X64-NEXT:    movl %edi, %ecx
328 ; X64-NEXT:    shll $5, %ecx
329 ; X64-NEXT:    subl %ecx, %eax
330 ; X64-NEXT:    retq
332 ; X86-LABEL: test1:
333 ; X86:       # %bb.0: # %entry
334 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
335 ; X86-NEXT:    movl %eax, %ecx
336 ; X86-NEXT:    shll $5, %ecx
337 ; X86-NEXT:    subl %ecx, %eax
338 ; X86-NEXT:    retl
339 entry:
340         %tmp3 = mul i32 %a, -31
341         ret i32 %tmp3
345 define i32 @test2(i32 %a) {
346 ; X64-LABEL: test2:
347 ; X64:       # %bb.0: # %entry
348 ; X64-NEXT:    movl %edi, %eax
349 ; X64-NEXT:    shll $5, %eax
350 ; X64-NEXT:    addl %edi, %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:    movl %edi, %eax
369 ; X64-NEXT:    shll $5, %eax
370 ; X64-NEXT:    addl %edi, %eax
371 ; X64-NEXT:    negl %eax
372 ; X64-NEXT:    retq
374 ; X86-LABEL: test3:
375 ; X86:       # %bb.0: # %entry
376 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
377 ; X86-NEXT:    movl %ecx, %eax
378 ; X86-NEXT:    shll $5, %eax
379 ; X86-NEXT:    addl %ecx, %eax
380 ; X86-NEXT:    negl %eax
381 ; X86-NEXT:    retl
382 entry:
383         %tmp3 = mul i32 %a, -33
384         ret i32 %tmp3
387 define i64 @test4(i64 %a) {
388 ; X64-LABEL: test4:
389 ; X64:       # %bb.0: # %entry
390 ; X64-NEXT:    movq %rdi, %rax
391 ; X64-NEXT:    shlq $5, %rax
392 ; X64-NEXT:    subq %rdi, %rax
393 ; X64-NEXT:    retq
395 ; X86-LABEL: test4:
396 ; X86:       # %bb.0: # %entry
397 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
398 ; X86-NEXT:    movl %eax, %ecx
399 ; X86-NEXT:    shll $5, %ecx
400 ; X86-NEXT:    subl %eax, %ecx
401 ; X86-NEXT:    movl $31, %eax
402 ; X86-NEXT:    mull {{[0-9]+}}(%esp)
403 ; X86-NEXT:    addl %ecx, %edx
404 ; X86-NEXT:    retl
405 entry:
406         %tmp3 = mul i64 %a, 31
407         ret i64 %tmp3
410 define i64 @test5(i64 %a) {
411 ; X64-LABEL: test5:
412 ; X64:       # %bb.0: # %entry
413 ; X64-NEXT:    movq %rdi, %rax
414 ; X64-NEXT:    movq %rdi, %rcx
415 ; X64-NEXT:    shlq $5, %rcx
416 ; X64-NEXT:    subq %rcx, %rax
417 ; X64-NEXT:    retq
419 ; X86-LABEL: test5:
420 ; X86:       # %bb.0: # %entry
421 ; X86-NEXT:    pushl %esi
422 ; X86-NEXT:    .cfi_def_cfa_offset 8
423 ; X86-NEXT:    .cfi_offset %esi, -8
424 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
425 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
426 ; X86-NEXT:    movl %esi, %eax
427 ; X86-NEXT:    shll $5, %eax
428 ; X86-NEXT:    subl %eax, %esi
429 ; X86-NEXT:    movl $-31, %edx
430 ; X86-NEXT:    movl %ecx, %eax
431 ; X86-NEXT:    mull %edx
432 ; X86-NEXT:    subl %ecx, %edx
433 ; X86-NEXT:    addl %esi, %edx
434 ; X86-NEXT:    popl %esi
435 ; X86-NEXT:    .cfi_def_cfa_offset 4
436 ; X86-NEXT:    retl
437 entry:
438         %tmp3 = mul i64 %a, -31
439         ret i64 %tmp3
443 define i64 @test6(i64 %a) {
444 ; X64-LABEL: test6:
445 ; X64:       # %bb.0: # %entry
446 ; X64-NEXT:    movq %rdi, %rax
447 ; X64-NEXT:    shlq $5, %rax
448 ; X64-NEXT:    addq %rdi, %rax
449 ; X64-NEXT:    retq
451 ; X86-LABEL: test6:
452 ; X86:       # %bb.0: # %entry
453 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
454 ; X86-NEXT:    movl %eax, %ecx
455 ; X86-NEXT:    shll $5, %ecx
456 ; X86-NEXT:    addl %eax, %ecx
457 ; X86-NEXT:    movl $33, %eax
458 ; X86-NEXT:    mull {{[0-9]+}}(%esp)
459 ; X86-NEXT:    addl %ecx, %edx
460 ; X86-NEXT:    retl
461 entry:
462         %tmp3 = mul i64 %a, 33
463         ret i64 %tmp3
466 define i64 @test7(i64 %a) {
467 ; X64-LABEL: test7:
468 ; X64:       # %bb.0: # %entry
469 ; X64-NEXT:    movq %rdi, %rax
470 ; X64-NEXT:    shlq $5, %rax
471 ; X64-NEXT:    addq %rdi, %rax
472 ; X64-NEXT:    negq %rax
473 ; X64-NEXT:    retq
475 ; X86-LABEL: test7:
476 ; X86:       # %bb.0: # %entry
477 ; X86-NEXT:    pushl %esi
478 ; X86-NEXT:    .cfi_def_cfa_offset 8
479 ; X86-NEXT:    .cfi_offset %esi, -8
480 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
481 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
482 ; X86-NEXT:    movl %eax, %esi
483 ; X86-NEXT:    shll $5, %esi
484 ; X86-NEXT:    addl %eax, %esi
485 ; X86-NEXT:    movl $-33, %edx
486 ; X86-NEXT:    movl %ecx, %eax
487 ; X86-NEXT:    mull %edx
488 ; X86-NEXT:    subl %ecx, %edx
489 ; X86-NEXT:    subl %esi, %edx
490 ; X86-NEXT:    popl %esi
491 ; X86-NEXT:    .cfi_def_cfa_offset 4
492 ; X86-NEXT:    retl
493 entry:
494         %tmp3 = mul i64 %a, -33
495         ret i64 %tmp3
498 define i64 @testOverflow(i64 %a) {
499 ; X64-LABEL: testOverflow:
500 ; X64:       # %bb.0: # %entry
501 ; X64-NEXT:    movq %rdi, %rax
502 ; X64-NEXT:    shlq $63, %rax
503 ; X64-NEXT:    subq %rdi, %rax
504 ; X64-NEXT:    retq
506 ; X86-LABEL: testOverflow:
507 ; X86:       # %bb.0: # %entry
508 ; X86-NEXT:    pushl %esi
509 ; X86-NEXT:    .cfi_def_cfa_offset 8
510 ; X86-NEXT:    .cfi_offset %esi, -8
511 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
512 ; X86-NEXT:    movl $-1, %edx
513 ; X86-NEXT:    movl %ecx, %eax
514 ; X86-NEXT:    mull %edx
515 ; X86-NEXT:    movl %ecx, %esi
516 ; X86-NEXT:    shll $31, %esi
517 ; X86-NEXT:    subl %ecx, %esi
518 ; X86-NEXT:    addl %esi, %edx
519 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %edx
520 ; X86-NEXT:    popl %esi
521 ; X86-NEXT:    .cfi_def_cfa_offset 4
522 ; X86-NEXT:    retl
523 entry:
524         %tmp3 = mul i64 %a, 9223372036854775807
525         ret i64 %tmp3
528 define i64 @testNegOverflow(i64 %a) {
529 ; X64-LABEL: testNegOverflow:
530 ; X64:       # %bb.0: # %entry
531 ; X64-NEXT:    movq %rdi, %rax
532 ; X64-NEXT:    shlq $63, %rax
533 ; X64-NEXT:    addq %rdi, %rax
534 ; X64-NEXT:    retq
536 ; X86-LABEL: testNegOverflow:
537 ; X86:       # %bb.0: # %entry
538 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
539 ; X86-NEXT:    movl %eax, %edx
540 ; X86-NEXT:    shll $31, %edx
541 ; X86-NEXT:    addl {{[0-9]+}}(%esp), %edx
542 ; X86-NEXT:    retl
543 entry:
544         %tmp3 = mul i64 %a, -9223372036854775807
545         ret i64 %tmp3