1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -disable-peephole -mtriple=x86_64-linux-unknown < %s | FileCheck %s --check-prefixes=CHECK,LINUX,SDAG
3 ; RUN: llc -disable-peephole -mtriple=x86_64-linux-unknown -fast-isel -fast-isel-abort=1 < %s | FileCheck %s --check-prefixes=CHECK,LINUX,FAST
4 ; RUN: llc -disable-peephole -mtriple=x86_64-linux-unknown -mcpu=knl < %s | FileCheck %s --check-prefixes=CHECK,LINUX,SDAG
5 ; RUN: llc -disable-peephole -mtriple=x86_64-pc-win32 < %s | FileCheck %s --check-prefixes=CHECK,WIN64
6 ; RUN: llc -disable-peephole -mtriple=i386-pc-win32 < %s | FileCheck %s --check-prefix=WIN32
8 define {i64, i1} @t1() nounwind {
11 ; CHECK-NEXT: movl $72, %eax
12 ; CHECK-NEXT: xorl %edx, %edx
17 ; WIN32-NEXT: movl $72, %eax
18 ; WIN32-NEXT: xorl %edx, %edx
19 ; WIN32-NEXT: xorl %ecx, %ecx
21 %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 8)
25 define {i64, i1} @t2() nounwind {
28 ; CHECK-NEXT: xorl %eax, %eax
29 ; CHECK-NEXT: xorl %edx, %edx
34 ; WIN32-NEXT: xorl %eax, %eax
35 ; WIN32-NEXT: xorl %edx, %edx
36 ; WIN32-NEXT: xorl %ecx, %ecx
38 %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 0)
42 define {i64, i1} @t3() nounwind {
45 ; CHECK-NEXT: movq $-9, %rax
46 ; CHECK-NEXT: movb $1, %dl
51 ; WIN32-NEXT: movl $-9, %eax
52 ; WIN32-NEXT: movl $-1, %edx
53 ; WIN32-NEXT: movb $1, %cl
55 %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 -1)
60 define zeroext i1 @smuloi8(i8 %v1, i8 %v2, ptr %res) {
61 ; SDAG-LABEL: smuloi8:
63 ; SDAG-NEXT: movl %edi, %eax
64 ; SDAG-NEXT: # kill: def $al killed $al killed $eax
65 ; SDAG-NEXT: imulb %sil
67 ; SDAG-NEXT: movb %al, (%rdx)
68 ; SDAG-NEXT: movl %ecx, %eax
71 ; FAST-LABEL: smuloi8:
73 ; FAST-NEXT: movl %edi, %eax
74 ; FAST-NEXT: # kill: def $al killed $al killed $eax
75 ; FAST-NEXT: imulb %sil
77 ; FAST-NEXT: movb %al, (%rdx)
78 ; FAST-NEXT: andb $1, %cl
79 ; FAST-NEXT: movl %ecx, %eax
82 ; WIN64-LABEL: smuloi8:
84 ; WIN64-NEXT: movl %ecx, %eax
85 ; WIN64-NEXT: imulb %dl
86 ; WIN64-NEXT: seto %cl
87 ; WIN64-NEXT: movb %al, (%r8)
88 ; WIN64-NEXT: movl %ecx, %eax
91 ; WIN32-LABEL: smuloi8:
93 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
94 ; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax
95 ; WIN32-NEXT: imulb {{[0-9]+}}(%esp)
96 ; WIN32-NEXT: seto %cl
97 ; WIN32-NEXT: movb %al, (%edx)
98 ; WIN32-NEXT: movl %ecx, %eax
100 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
101 %val = extractvalue {i8, i1} %t, 0
102 %obit = extractvalue {i8, i1} %t, 1
103 store i8 %val, ptr %res
107 define zeroext i1 @smuloi16(i16 %v1, i16 %v2, ptr %res) {
108 ; SDAG-LABEL: smuloi16:
110 ; SDAG-NEXT: imulw %si, %di
111 ; SDAG-NEXT: seto %al
112 ; SDAG-NEXT: movw %di, (%rdx)
115 ; FAST-LABEL: smuloi16:
117 ; FAST-NEXT: imulw %si, %di
118 ; FAST-NEXT: seto %al
119 ; FAST-NEXT: movw %di, (%rdx)
120 ; FAST-NEXT: andb $1, %al
123 ; WIN64-LABEL: smuloi16:
125 ; WIN64-NEXT: imulw %dx, %cx
126 ; WIN64-NEXT: seto %al
127 ; WIN64-NEXT: movw %cx, (%r8)
130 ; WIN32-LABEL: smuloi16:
132 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
133 ; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %edx
134 ; WIN32-NEXT: imulw {{[0-9]+}}(%esp), %dx
135 ; WIN32-NEXT: seto %al
136 ; WIN32-NEXT: movw %dx, (%ecx)
138 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
139 %val = extractvalue {i16, i1} %t, 0
140 %obit = extractvalue {i16, i1} %t, 1
141 store i16 %val, ptr %res
145 define zeroext i1 @smuloi32(i32 %v1, i32 %v2, ptr %res) {
146 ; SDAG-LABEL: smuloi32:
148 ; SDAG-NEXT: imull %esi, %edi
149 ; SDAG-NEXT: seto %al
150 ; SDAG-NEXT: movl %edi, (%rdx)
153 ; FAST-LABEL: smuloi32:
155 ; FAST-NEXT: imull %esi, %edi
156 ; FAST-NEXT: seto %al
157 ; FAST-NEXT: movl %edi, (%rdx)
158 ; FAST-NEXT: andb $1, %al
161 ; WIN64-LABEL: smuloi32:
163 ; WIN64-NEXT: imull %edx, %ecx
164 ; WIN64-NEXT: seto %al
165 ; WIN64-NEXT: movl %ecx, (%r8)
168 ; WIN32-LABEL: smuloi32:
170 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
171 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
172 ; WIN32-NEXT: imull {{[0-9]+}}(%esp), %edx
173 ; WIN32-NEXT: seto %al
174 ; WIN32-NEXT: movl %edx, (%ecx)
176 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
177 %val = extractvalue {i32, i1} %t, 0
178 %obit = extractvalue {i32, i1} %t, 1
179 store i32 %val, ptr %res
183 define zeroext i1 @smuloi64(i64 %v1, i64 %v2, ptr %res) {
184 ; SDAG-LABEL: smuloi64:
186 ; SDAG-NEXT: imulq %rsi, %rdi
187 ; SDAG-NEXT: seto %al
188 ; SDAG-NEXT: movq %rdi, (%rdx)
191 ; FAST-LABEL: smuloi64:
193 ; FAST-NEXT: imulq %rsi, %rdi
194 ; FAST-NEXT: seto %al
195 ; FAST-NEXT: movq %rdi, (%rdx)
196 ; FAST-NEXT: andb $1, %al
199 ; WIN64-LABEL: smuloi64:
201 ; WIN64-NEXT: imulq %rdx, %rcx
202 ; WIN64-NEXT: seto %al
203 ; WIN64-NEXT: movq %rcx, (%r8)
206 ; WIN32-LABEL: smuloi64:
208 ; WIN32-NEXT: pushl %ebp
209 ; WIN32-NEXT: pushl %ebx
210 ; WIN32-NEXT: pushl %edi
211 ; WIN32-NEXT: pushl %esi
212 ; WIN32-NEXT: subl $8, %esp
213 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
214 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edi
215 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
216 ; WIN32-NEXT: movl %edx, %ecx
217 ; WIN32-NEXT: movl %edx, %ebx
218 ; WIN32-NEXT: sarl $31, %ecx
219 ; WIN32-NEXT: movl %edi, %esi
220 ; WIN32-NEXT: imull %ecx, %esi
221 ; WIN32-NEXT: mull %ecx
222 ; WIN32-NEXT: movl %edx, %ecx
223 ; WIN32-NEXT: movl %eax, %ebp
224 ; WIN32-NEXT: addl %eax, %ecx
225 ; WIN32-NEXT: addl %esi, %ecx
226 ; WIN32-NEXT: movl %edi, %eax
227 ; WIN32-NEXT: sarl $31, %eax
228 ; WIN32-NEXT: movl %eax, %edi
229 ; WIN32-NEXT: imull %ebx, %edi
230 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebx
231 ; WIN32-NEXT: mull %ebx
232 ; WIN32-NEXT: movl %edx, %esi
233 ; WIN32-NEXT: addl %edi, %esi
234 ; WIN32-NEXT: addl %eax, %esi
235 ; WIN32-NEXT: addl %ebp, %eax
236 ; WIN32-NEXT: movl %eax, (%esp) # 4-byte Spill
237 ; WIN32-NEXT: adcl %ecx, %esi
238 ; WIN32-NEXT: movl %ebx, %eax
239 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
240 ; WIN32-NEXT: mull %ecx
241 ; WIN32-NEXT: movl %edx, %ebp
242 ; WIN32-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
243 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
244 ; WIN32-NEXT: mull %ecx
245 ; WIN32-NEXT: movl %edx, %edi
246 ; WIN32-NEXT: movl %eax, %ecx
247 ; WIN32-NEXT: addl %ebp, %ecx
248 ; WIN32-NEXT: adcl $0, %edi
249 ; WIN32-NEXT: movl %ebx, %eax
250 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
251 ; WIN32-NEXT: movl %edx, %ebx
252 ; WIN32-NEXT: movl %eax, %ebp
253 ; WIN32-NEXT: addl %ecx, %ebp
254 ; WIN32-NEXT: adcl %edi, %ebx
255 ; WIN32-NEXT: setb %cl
256 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
257 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
258 ; WIN32-NEXT: addl %ebx, %eax
259 ; WIN32-NEXT: movzbl %cl, %ecx
260 ; WIN32-NEXT: adcl %ecx, %edx
261 ; WIN32-NEXT: addl (%esp), %eax # 4-byte Folded Reload
262 ; WIN32-NEXT: adcl %esi, %edx
263 ; WIN32-NEXT: movl %ebp, %ecx
264 ; WIN32-NEXT: sarl $31, %ecx
265 ; WIN32-NEXT: xorl %ecx, %edx
266 ; WIN32-NEXT: xorl %eax, %ecx
267 ; WIN32-NEXT: orl %edx, %ecx
268 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
269 ; WIN32-NEXT: movl %ebp, 4(%eax)
270 ; WIN32-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
271 ; WIN32-NEXT: movl %ecx, (%eax)
272 ; WIN32-NEXT: setne %al
273 ; WIN32-NEXT: addl $8, %esp
274 ; WIN32-NEXT: popl %esi
275 ; WIN32-NEXT: popl %edi
276 ; WIN32-NEXT: popl %ebx
277 ; WIN32-NEXT: popl %ebp
279 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
280 %val = extractvalue {i64, i1} %t, 0
281 %obit = extractvalue {i64, i1} %t, 1
282 store i64 %val, ptr %res
287 define zeroext i1 @umuloi8(i8 %v1, i8 %v2, ptr %res) {
288 ; SDAG-LABEL: umuloi8:
290 ; SDAG-NEXT: movl %edi, %eax
291 ; SDAG-NEXT: # kill: def $al killed $al killed $eax
292 ; SDAG-NEXT: mulb %sil
293 ; SDAG-NEXT: seto %cl
294 ; SDAG-NEXT: movb %al, (%rdx)
295 ; SDAG-NEXT: movl %ecx, %eax
298 ; FAST-LABEL: umuloi8:
300 ; FAST-NEXT: movl %edi, %eax
301 ; FAST-NEXT: # kill: def $al killed $al killed $eax
302 ; FAST-NEXT: mulb %sil
303 ; FAST-NEXT: seto %cl
304 ; FAST-NEXT: movb %al, (%rdx)
305 ; FAST-NEXT: andb $1, %cl
306 ; FAST-NEXT: movl %ecx, %eax
309 ; WIN64-LABEL: umuloi8:
311 ; WIN64-NEXT: movl %ecx, %eax
312 ; WIN64-NEXT: mulb %dl
313 ; WIN64-NEXT: seto %cl
314 ; WIN64-NEXT: movb %al, (%r8)
315 ; WIN64-NEXT: movl %ecx, %eax
318 ; WIN32-LABEL: umuloi8:
320 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
321 ; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax
322 ; WIN32-NEXT: mulb {{[0-9]+}}(%esp)
323 ; WIN32-NEXT: seto %cl
324 ; WIN32-NEXT: movb %al, (%edx)
325 ; WIN32-NEXT: movl %ecx, %eax
327 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
328 %val = extractvalue {i8, i1} %t, 0
329 %obit = extractvalue {i8, i1} %t, 1
330 store i8 %val, ptr %res
334 define zeroext i1 @umuloi16(i16 %v1, i16 %v2, ptr %res) {
335 ; SDAG-LABEL: umuloi16:
337 ; SDAG-NEXT: movq %rdx, %rcx
338 ; SDAG-NEXT: movl %edi, %eax
339 ; SDAG-NEXT: # kill: def $ax killed $ax killed $eax
340 ; SDAG-NEXT: mulw %si
341 ; SDAG-NEXT: seto %dl
342 ; SDAG-NEXT: movw %ax, (%rcx)
343 ; SDAG-NEXT: movl %edx, %eax
346 ; FAST-LABEL: umuloi16:
348 ; FAST-NEXT: movq %rdx, %rcx
349 ; FAST-NEXT: movl %edi, %eax
350 ; FAST-NEXT: # kill: def $ax killed $ax killed $eax
351 ; FAST-NEXT: mulw %si
352 ; FAST-NEXT: seto %dl
353 ; FAST-NEXT: movw %ax, (%rcx)
354 ; FAST-NEXT: andb $1, %dl
355 ; FAST-NEXT: movl %edx, %eax
358 ; WIN64-LABEL: umuloi16:
360 ; WIN64-NEXT: movl %ecx, %eax
361 ; WIN64-NEXT: mulw %dx
362 ; WIN64-NEXT: seto %cl
363 ; WIN64-NEXT: movw %ax, (%r8)
364 ; WIN64-NEXT: movl %ecx, %eax
367 ; WIN32-LABEL: umuloi16:
369 ; WIN32-NEXT: pushl %esi
370 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
371 ; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax
372 ; WIN32-NEXT: mulw {{[0-9]+}}(%esp)
373 ; WIN32-NEXT: seto %cl
374 ; WIN32-NEXT: movw %ax, (%esi)
375 ; WIN32-NEXT: movl %ecx, %eax
376 ; WIN32-NEXT: popl %esi
378 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
379 %val = extractvalue {i16, i1} %t, 0
380 %obit = extractvalue {i16, i1} %t, 1
381 store i16 %val, ptr %res
385 define zeroext i1 @umuloi32(i32 %v1, i32 %v2, ptr %res) {
386 ; SDAG-LABEL: umuloi32:
388 ; SDAG-NEXT: movq %rdx, %rcx
389 ; SDAG-NEXT: movl %edi, %eax
390 ; SDAG-NEXT: mull %esi
391 ; SDAG-NEXT: seto %dl
392 ; SDAG-NEXT: movl %eax, (%rcx)
393 ; SDAG-NEXT: movl %edx, %eax
396 ; FAST-LABEL: umuloi32:
398 ; FAST-NEXT: movq %rdx, %rcx
399 ; FAST-NEXT: movl %edi, %eax
400 ; FAST-NEXT: mull %esi
401 ; FAST-NEXT: seto %dl
402 ; FAST-NEXT: movl %eax, (%rcx)
403 ; FAST-NEXT: andb $1, %dl
404 ; FAST-NEXT: movl %edx, %eax
407 ; WIN64-LABEL: umuloi32:
409 ; WIN64-NEXT: movl %ecx, %eax
410 ; WIN64-NEXT: mull %edx
411 ; WIN64-NEXT: seto %cl
412 ; WIN64-NEXT: movl %eax, (%r8)
413 ; WIN64-NEXT: movl %ecx, %eax
416 ; WIN32-LABEL: umuloi32:
418 ; WIN32-NEXT: pushl %esi
419 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
420 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
421 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
422 ; WIN32-NEXT: seto %cl
423 ; WIN32-NEXT: movl %eax, (%esi)
424 ; WIN32-NEXT: movl %ecx, %eax
425 ; WIN32-NEXT: popl %esi
427 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
428 %val = extractvalue {i32, i1} %t, 0
429 %obit = extractvalue {i32, i1} %t, 1
430 store i32 %val, ptr %res
434 define zeroext i1 @umuloi64(i64 %v1, i64 %v2, ptr %res) {
435 ; SDAG-LABEL: umuloi64:
437 ; SDAG-NEXT: movq %rdx, %rcx
438 ; SDAG-NEXT: movq %rdi, %rax
439 ; SDAG-NEXT: mulq %rsi
440 ; SDAG-NEXT: seto %dl
441 ; SDAG-NEXT: movq %rax, (%rcx)
442 ; SDAG-NEXT: movl %edx, %eax
445 ; FAST-LABEL: umuloi64:
447 ; FAST-NEXT: movq %rdx, %rcx
448 ; FAST-NEXT: movq %rdi, %rax
449 ; FAST-NEXT: mulq %rsi
450 ; FAST-NEXT: seto %dl
451 ; FAST-NEXT: movq %rax, (%rcx)
452 ; FAST-NEXT: andb $1, %dl
453 ; FAST-NEXT: movl %edx, %eax
456 ; WIN64-LABEL: umuloi64:
458 ; WIN64-NEXT: movq %rcx, %rax
459 ; WIN64-NEXT: mulq %rdx
460 ; WIN64-NEXT: seto %cl
461 ; WIN64-NEXT: movq %rax, (%r8)
462 ; WIN64-NEXT: movl %ecx, %eax
465 ; WIN32-LABEL: umuloi64:
467 ; WIN32-NEXT: pushl %ebp
468 ; WIN32-NEXT: pushl %ebx
469 ; WIN32-NEXT: pushl %edi
470 ; WIN32-NEXT: pushl %esi
471 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebp
472 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
473 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
474 ; WIN32-NEXT: testl %esi, %esi
475 ; WIN32-NEXT: setne %dl
476 ; WIN32-NEXT: testl %eax, %eax
477 ; WIN32-NEXT: setne %cl
478 ; WIN32-NEXT: andb %dl, %cl
479 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
480 ; WIN32-NEXT: movl %eax, %edi
481 ; WIN32-NEXT: seto %bl
482 ; WIN32-NEXT: movl %esi, %eax
483 ; WIN32-NEXT: mull %ebp
484 ; WIN32-NEXT: seto %ch
485 ; WIN32-NEXT: orb %bl, %ch
486 ; WIN32-NEXT: orb %cl, %ch
487 ; WIN32-NEXT: leal (%edi,%eax), %esi
488 ; WIN32-NEXT: movl %ebp, %eax
489 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
490 ; WIN32-NEXT: addl %esi, %edx
491 ; WIN32-NEXT: setb %cl
492 ; WIN32-NEXT: orb %ch, %cl
493 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
494 ; WIN32-NEXT: movl %eax, (%esi)
495 ; WIN32-NEXT: movl %edx, 4(%esi)
496 ; WIN32-NEXT: movl %ecx, %eax
497 ; WIN32-NEXT: popl %esi
498 ; WIN32-NEXT: popl %edi
499 ; WIN32-NEXT: popl %ebx
500 ; WIN32-NEXT: popl %ebp
502 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
503 %val = extractvalue {i64, i1} %t, 0
504 %obit = extractvalue {i64, i1} %t, 1
505 store i64 %val, ptr %res
510 ; Check the use of the overflow bit in combination with a select instruction.
512 define i32 @smuloselecti32(i32 %v1, i32 %v2) {
513 ; LINUX-LABEL: smuloselecti32:
515 ; LINUX-NEXT: movl %esi, %eax
516 ; LINUX-NEXT: movl %edi, %ecx
517 ; LINUX-NEXT: imull %esi, %ecx
518 ; LINUX-NEXT: cmovol %edi, %eax
521 ; WIN64-LABEL: smuloselecti32:
523 ; WIN64-NEXT: movl %edx, %eax
524 ; WIN64-NEXT: movl %ecx, %edx
525 ; WIN64-NEXT: imull %eax, %edx
526 ; WIN64-NEXT: cmovol %ecx, %eax
529 ; WIN32-LABEL: smuloselecti32:
531 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
532 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
533 ; WIN32-NEXT: movl %eax, %edx
534 ; WIN32-NEXT: imull %ecx, %edx
535 ; WIN32-NEXT: jo LBB11_2
536 ; WIN32-NEXT: # %bb.1:
537 ; WIN32-NEXT: movl %ecx, %eax
538 ; WIN32-NEXT: LBB11_2:
540 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
541 %obit = extractvalue {i32, i1} %t, 1
542 %ret = select i1 %obit, i32 %v1, i32 %v2
546 define i64 @smuloselecti64(i64 %v1, i64 %v2) {
547 ; LINUX-LABEL: smuloselecti64:
549 ; LINUX-NEXT: movq %rsi, %rax
550 ; LINUX-NEXT: movq %rdi, %rcx
551 ; LINUX-NEXT: imulq %rsi, %rcx
552 ; LINUX-NEXT: cmovoq %rdi, %rax
555 ; WIN64-LABEL: smuloselecti64:
557 ; WIN64-NEXT: movq %rdx, %rax
558 ; WIN64-NEXT: movq %rcx, %rdx
559 ; WIN64-NEXT: imulq %rax, %rdx
560 ; WIN64-NEXT: cmovoq %rcx, %rax
563 ; WIN32-LABEL: smuloselecti64:
565 ; WIN32-NEXT: pushl %ebp
566 ; WIN32-NEXT: pushl %ebx
567 ; WIN32-NEXT: pushl %edi
568 ; WIN32-NEXT: pushl %esi
569 ; WIN32-NEXT: pushl %eax
570 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebp
571 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
572 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
573 ; WIN32-NEXT: sarl $31, %ecx
574 ; WIN32-NEXT: movl %eax, %edi
575 ; WIN32-NEXT: movl %eax, %ebx
576 ; WIN32-NEXT: imull %ecx, %edi
577 ; WIN32-NEXT: movl %ebp, %eax
578 ; WIN32-NEXT: mull %ecx
579 ; WIN32-NEXT: movl %edx, %esi
580 ; WIN32-NEXT: movl %eax, %ecx
581 ; WIN32-NEXT: addl %eax, %esi
582 ; WIN32-NEXT: addl %edi, %esi
583 ; WIN32-NEXT: movl %ebx, %eax
584 ; WIN32-NEXT: sarl $31, %eax
585 ; WIN32-NEXT: movl %eax, %edi
586 ; WIN32-NEXT: imull {{[0-9]+}}(%esp), %edi
587 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
588 ; WIN32-NEXT: movl %edx, %ebx
589 ; WIN32-NEXT: addl %edi, %ebx
590 ; WIN32-NEXT: addl %eax, %ebx
591 ; WIN32-NEXT: addl %ecx, %eax
592 ; WIN32-NEXT: movl %eax, (%esp) # 4-byte Spill
593 ; WIN32-NEXT: adcl %esi, %ebx
594 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edi
595 ; WIN32-NEXT: movl %edi, %eax
596 ; WIN32-NEXT: mull %ebp
597 ; WIN32-NEXT: movl %edx, %esi
598 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
599 ; WIN32-NEXT: mull %ebp
600 ; WIN32-NEXT: movl %edx, %ebp
601 ; WIN32-NEXT: movl %eax, %ecx
602 ; WIN32-NEXT: addl %esi, %ecx
603 ; WIN32-NEXT: adcl $0, %ebp
604 ; WIN32-NEXT: movl %edi, %eax
605 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
606 ; WIN32-NEXT: movl %edx, %edi
607 ; WIN32-NEXT: movl %eax, %esi
608 ; WIN32-NEXT: addl %ecx, %esi
609 ; WIN32-NEXT: adcl %ebp, %edi
610 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebp
611 ; WIN32-NEXT: setb %cl
612 ; WIN32-NEXT: movl %ebp, %eax
613 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
614 ; WIN32-NEXT: addl %edi, %eax
615 ; WIN32-NEXT: movzbl %cl, %ecx
616 ; WIN32-NEXT: adcl %ecx, %edx
617 ; WIN32-NEXT: addl (%esp), %eax # 4-byte Folded Reload
618 ; WIN32-NEXT: adcl %ebx, %edx
619 ; WIN32-NEXT: sarl $31, %esi
620 ; WIN32-NEXT: xorl %esi, %edx
621 ; WIN32-NEXT: xorl %eax, %esi
622 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
623 ; WIN32-NEXT: orl %edx, %esi
624 ; WIN32-NEXT: jne LBB12_2
625 ; WIN32-NEXT: # %bb.1:
626 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
627 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebp
628 ; WIN32-NEXT: LBB12_2:
629 ; WIN32-NEXT: movl %ebp, %edx
630 ; WIN32-NEXT: addl $4, %esp
631 ; WIN32-NEXT: popl %esi
632 ; WIN32-NEXT: popl %edi
633 ; WIN32-NEXT: popl %ebx
634 ; WIN32-NEXT: popl %ebp
636 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
637 %obit = extractvalue {i64, i1} %t, 1
638 %ret = select i1 %obit, i64 %v1, i64 %v2
642 define i32 @umuloselecti32(i32 %v1, i32 %v2) {
643 ; LINUX-LABEL: umuloselecti32:
645 ; LINUX-NEXT: movl %edi, %eax
646 ; LINUX-NEXT: mull %esi
647 ; LINUX-NEXT: cmovol %edi, %esi
648 ; LINUX-NEXT: movl %esi, %eax
651 ; WIN64-LABEL: umuloselecti32:
653 ; WIN64-NEXT: movl %edx, %r8d
654 ; WIN64-NEXT: movl %ecx, %eax
655 ; WIN64-NEXT: mull %edx
656 ; WIN64-NEXT: cmovol %ecx, %r8d
657 ; WIN64-NEXT: movl %r8d, %eax
660 ; WIN32-LABEL: umuloselecti32:
662 ; WIN32-NEXT: pushl %esi
663 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
664 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
665 ; WIN32-NEXT: movl %ecx, %eax
666 ; WIN32-NEXT: mull %esi
667 ; WIN32-NEXT: jo LBB13_2
668 ; WIN32-NEXT: # %bb.1:
669 ; WIN32-NEXT: movl %esi, %ecx
670 ; WIN32-NEXT: LBB13_2:
671 ; WIN32-NEXT: movl %ecx, %eax
672 ; WIN32-NEXT: popl %esi
674 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
675 %obit = extractvalue {i32, i1} %t, 1
676 %ret = select i1 %obit, i32 %v1, i32 %v2
680 define i64 @umuloselecti64(i64 %v1, i64 %v2) {
681 ; LINUX-LABEL: umuloselecti64:
683 ; LINUX-NEXT: movq %rdi, %rax
684 ; LINUX-NEXT: mulq %rsi
685 ; LINUX-NEXT: cmovoq %rdi, %rsi
686 ; LINUX-NEXT: movq %rsi, %rax
689 ; WIN64-LABEL: umuloselecti64:
691 ; WIN64-NEXT: movq %rdx, %r8
692 ; WIN64-NEXT: movq %rcx, %rax
693 ; WIN64-NEXT: mulq %rdx
694 ; WIN64-NEXT: cmovoq %rcx, %r8
695 ; WIN64-NEXT: movq %r8, %rax
698 ; WIN32-LABEL: umuloselecti64:
700 ; WIN32-NEXT: pushl %ebp
701 ; WIN32-NEXT: pushl %ebx
702 ; WIN32-NEXT: pushl %edi
703 ; WIN32-NEXT: pushl %esi
704 ; WIN32-NEXT: pushl %eax
705 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
706 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
707 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edi
708 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebp
709 ; WIN32-NEXT: testl %ebp, %ebp
710 ; WIN32-NEXT: setne %al
711 ; WIN32-NEXT: testl %esi, %esi
712 ; WIN32-NEXT: setne %bl
713 ; WIN32-NEXT: andb %al, %bl
714 ; WIN32-NEXT: movl %esi, %eax
715 ; WIN32-NEXT: mull %edi
716 ; WIN32-NEXT: movl %edi, %edx
717 ; WIN32-NEXT: movl %eax, %edi
718 ; WIN32-NEXT: seto {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Folded Spill
719 ; WIN32-NEXT: movl %ebp, %eax
720 ; WIN32-NEXT: movl %edx, %ebp
721 ; WIN32-NEXT: mull %ecx
722 ; WIN32-NEXT: seto %bh
723 ; WIN32-NEXT: orb {{[-0-9]+}}(%e{{[sb]}}p), %bh # 1-byte Folded Reload
724 ; WIN32-NEXT: orb %bl, %bh
725 ; WIN32-NEXT: addl %eax, %edi
726 ; WIN32-NEXT: movl %ecx, %eax
727 ; WIN32-NEXT: mull %ebp
728 ; WIN32-NEXT: addl %edi, %edx
729 ; WIN32-NEXT: setb %al
730 ; WIN32-NEXT: orb %bh, %al
731 ; WIN32-NEXT: testb %al, %al
732 ; WIN32-NEXT: jne LBB14_2
733 ; WIN32-NEXT: # %bb.1:
734 ; WIN32-NEXT: movl %ebp, %ecx
735 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
736 ; WIN32-NEXT: LBB14_2:
737 ; WIN32-NEXT: movl %ecx, %eax
738 ; WIN32-NEXT: movl %esi, %edx
739 ; WIN32-NEXT: addl $4, %esp
740 ; WIN32-NEXT: popl %esi
741 ; WIN32-NEXT: popl %edi
742 ; WIN32-NEXT: popl %ebx
743 ; WIN32-NEXT: popl %ebp
745 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
746 %obit = extractvalue {i64, i1} %t, 1
747 %ret = select i1 %obit, i64 %v1, i64 %v2
752 ; Check the use of the overflow bit in combination with a branch instruction.
754 define zeroext i1 @smulobri8(i8 %v1, i8 %v2) {
755 ; SDAG-LABEL: smulobri8:
757 ; SDAG-NEXT: movl %edi, %eax
758 ; SDAG-NEXT: # kill: def $al killed $al killed $eax
759 ; SDAG-NEXT: imulb %sil
760 ; SDAG-NEXT: jo .LBB15_1
761 ; SDAG-NEXT: # %bb.2: # %continue
762 ; SDAG-NEXT: movb $1, %al
764 ; SDAG-NEXT: .LBB15_1: # %overflow
765 ; SDAG-NEXT: xorl %eax, %eax
768 ; FAST-LABEL: smulobri8:
770 ; FAST-NEXT: movl %edi, %eax
771 ; FAST-NEXT: # kill: def $al killed $al killed $eax
772 ; FAST-NEXT: imulb %sil
773 ; FAST-NEXT: seto %al
774 ; FAST-NEXT: testb $1, %al
775 ; FAST-NEXT: jne .LBB15_1
776 ; FAST-NEXT: # %bb.2: # %continue
777 ; FAST-NEXT: movb $1, %al
778 ; FAST-NEXT: andb $1, %al
780 ; FAST-NEXT: .LBB15_1: # %overflow
781 ; FAST-NEXT: xorl %eax, %eax
782 ; FAST-NEXT: andb $1, %al
783 ; FAST-NEXT: # kill: def $al killed $al killed $eax
786 ; WIN64-LABEL: smulobri8:
788 ; WIN64-NEXT: movl %ecx, %eax
789 ; WIN64-NEXT: imulb %dl
790 ; WIN64-NEXT: jo .LBB15_1
791 ; WIN64-NEXT: # %bb.2: # %continue
792 ; WIN64-NEXT: movb $1, %al
794 ; WIN64-NEXT: .LBB15_1: # %overflow
795 ; WIN64-NEXT: xorl %eax, %eax
798 ; WIN32-LABEL: smulobri8:
800 ; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax
801 ; WIN32-NEXT: imulb {{[0-9]+}}(%esp)
802 ; WIN32-NEXT: jo LBB15_1
803 ; WIN32-NEXT: # %bb.2: # %continue
804 ; WIN32-NEXT: movb $1, %al
806 ; WIN32-NEXT: LBB15_1: # %overflow
807 ; WIN32-NEXT: xorl %eax, %eax
809 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
810 %val = extractvalue {i8, i1} %t, 0
811 %obit = extractvalue {i8, i1} %t, 1
812 br i1 %obit, label %overflow, label %continue, !prof !0
821 define zeroext i1 @smulobri16(i16 %v1, i16 %v2) {
822 ; SDAG-LABEL: smulobri16:
824 ; SDAG-NEXT: imulw %si, %di
825 ; SDAG-NEXT: jo .LBB16_1
826 ; SDAG-NEXT: # %bb.2: # %continue
827 ; SDAG-NEXT: movb $1, %al
829 ; SDAG-NEXT: .LBB16_1: # %overflow
830 ; SDAG-NEXT: xorl %eax, %eax
833 ; FAST-LABEL: smulobri16:
835 ; FAST-NEXT: imulw %si, %di
836 ; FAST-NEXT: seto %al
837 ; FAST-NEXT: testb $1, %al
838 ; FAST-NEXT: jne .LBB16_1
839 ; FAST-NEXT: # %bb.2: # %continue
840 ; FAST-NEXT: movb $1, %al
841 ; FAST-NEXT: andb $1, %al
843 ; FAST-NEXT: .LBB16_1: # %overflow
844 ; FAST-NEXT: xorl %eax, %eax
845 ; FAST-NEXT: andb $1, %al
846 ; FAST-NEXT: # kill: def $al killed $al killed $eax
849 ; WIN64-LABEL: smulobri16:
851 ; WIN64-NEXT: imulw %dx, %cx
852 ; WIN64-NEXT: jo .LBB16_1
853 ; WIN64-NEXT: # %bb.2: # %continue
854 ; WIN64-NEXT: movb $1, %al
856 ; WIN64-NEXT: .LBB16_1: # %overflow
857 ; WIN64-NEXT: xorl %eax, %eax
860 ; WIN32-LABEL: smulobri16:
862 ; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax
863 ; WIN32-NEXT: imulw {{[0-9]+}}(%esp), %ax
864 ; WIN32-NEXT: jo LBB16_1
865 ; WIN32-NEXT: # %bb.2: # %continue
866 ; WIN32-NEXT: movb $1, %al
868 ; WIN32-NEXT: LBB16_1: # %overflow
869 ; WIN32-NEXT: xorl %eax, %eax
871 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
872 %val = extractvalue {i16, i1} %t, 0
873 %obit = extractvalue {i16, i1} %t, 1
874 br i1 %obit, label %overflow, label %continue, !prof !0
883 define zeroext i1 @smulobri32(i32 %v1, i32 %v2) {
884 ; SDAG-LABEL: smulobri32:
886 ; SDAG-NEXT: imull %esi, %edi
887 ; SDAG-NEXT: jo .LBB17_1
888 ; SDAG-NEXT: # %bb.2: # %continue
889 ; SDAG-NEXT: movb $1, %al
891 ; SDAG-NEXT: .LBB17_1: # %overflow
892 ; SDAG-NEXT: xorl %eax, %eax
895 ; FAST-LABEL: smulobri32:
897 ; FAST-NEXT: imull %esi, %edi
898 ; FAST-NEXT: jo .LBB17_1
899 ; FAST-NEXT: # %bb.2: # %continue
900 ; FAST-NEXT: movb $1, %al
901 ; FAST-NEXT: andb $1, %al
903 ; FAST-NEXT: .LBB17_1: # %overflow
904 ; FAST-NEXT: xorl %eax, %eax
905 ; FAST-NEXT: andb $1, %al
906 ; FAST-NEXT: # kill: def $al killed $al killed $eax
909 ; WIN64-LABEL: smulobri32:
911 ; WIN64-NEXT: imull %edx, %ecx
912 ; WIN64-NEXT: jo .LBB17_1
913 ; WIN64-NEXT: # %bb.2: # %continue
914 ; WIN64-NEXT: movb $1, %al
916 ; WIN64-NEXT: .LBB17_1: # %overflow
917 ; WIN64-NEXT: xorl %eax, %eax
920 ; WIN32-LABEL: smulobri32:
922 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
923 ; WIN32-NEXT: imull {{[0-9]+}}(%esp), %eax
924 ; WIN32-NEXT: jo LBB17_1
925 ; WIN32-NEXT: # %bb.2: # %continue
926 ; WIN32-NEXT: movb $1, %al
928 ; WIN32-NEXT: LBB17_1: # %overflow
929 ; WIN32-NEXT: xorl %eax, %eax
931 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
932 %val = extractvalue {i32, i1} %t, 0
933 %obit = extractvalue {i32, i1} %t, 1
934 br i1 %obit, label %overflow, label %continue, !prof !0
943 define zeroext i1 @smulobri64(i64 %v1, i64 %v2) {
944 ; SDAG-LABEL: smulobri64:
946 ; SDAG-NEXT: imulq %rsi, %rdi
947 ; SDAG-NEXT: jo .LBB18_1
948 ; SDAG-NEXT: # %bb.2: # %continue
949 ; SDAG-NEXT: movb $1, %al
951 ; SDAG-NEXT: .LBB18_1: # %overflow
952 ; SDAG-NEXT: xorl %eax, %eax
955 ; FAST-LABEL: smulobri64:
957 ; FAST-NEXT: imulq %rsi, %rdi
958 ; FAST-NEXT: jo .LBB18_1
959 ; FAST-NEXT: # %bb.2: # %continue
960 ; FAST-NEXT: movb $1, %al
961 ; FAST-NEXT: andb $1, %al
963 ; FAST-NEXT: .LBB18_1: # %overflow
964 ; FAST-NEXT: xorl %eax, %eax
965 ; FAST-NEXT: andb $1, %al
966 ; FAST-NEXT: # kill: def $al killed $al killed $eax
969 ; WIN64-LABEL: smulobri64:
971 ; WIN64-NEXT: imulq %rdx, %rcx
972 ; WIN64-NEXT: jo .LBB18_1
973 ; WIN64-NEXT: # %bb.2: # %continue
974 ; WIN64-NEXT: movb $1, %al
976 ; WIN64-NEXT: .LBB18_1: # %overflow
977 ; WIN64-NEXT: xorl %eax, %eax
980 ; WIN32-LABEL: smulobri64:
982 ; WIN32-NEXT: pushl %ebp
983 ; WIN32-NEXT: pushl %ebx
984 ; WIN32-NEXT: pushl %edi
985 ; WIN32-NEXT: pushl %esi
986 ; WIN32-NEXT: pushl %eax
987 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
988 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edi
989 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
990 ; WIN32-NEXT: movl %edx, %ecx
991 ; WIN32-NEXT: movl %edx, %ebp
992 ; WIN32-NEXT: sarl $31, %ecx
993 ; WIN32-NEXT: movl %edi, %esi
994 ; WIN32-NEXT: imull %ecx, %esi
995 ; WIN32-NEXT: mull %ecx
996 ; WIN32-NEXT: movl %edx, %ecx
997 ; WIN32-NEXT: movl %eax, %ebx
998 ; WIN32-NEXT: addl %eax, %ecx
999 ; WIN32-NEXT: addl %esi, %ecx
1000 ; WIN32-NEXT: movl %edi, %eax
1001 ; WIN32-NEXT: sarl $31, %eax
1002 ; WIN32-NEXT: movl %eax, %edi
1003 ; WIN32-NEXT: imull %ebp, %edi
1004 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebp
1005 ; WIN32-NEXT: mull %ebp
1006 ; WIN32-NEXT: movl %edx, %esi
1007 ; WIN32-NEXT: addl %edi, %esi
1008 ; WIN32-NEXT: addl %eax, %esi
1009 ; WIN32-NEXT: addl %ebx, %eax
1010 ; WIN32-NEXT: movl %eax, (%esp) # 4-byte Spill
1011 ; WIN32-NEXT: adcl %ecx, %esi
1012 ; WIN32-NEXT: movl %ebp, %eax
1013 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
1014 ; WIN32-NEXT: mull %ecx
1015 ; WIN32-NEXT: movl %edx, %ebx
1016 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1017 ; WIN32-NEXT: mull %ecx
1018 ; WIN32-NEXT: movl %edx, %edi
1019 ; WIN32-NEXT: movl %eax, %ecx
1020 ; WIN32-NEXT: addl %ebx, %ecx
1021 ; WIN32-NEXT: adcl $0, %edi
1022 ; WIN32-NEXT: movl %ebp, %eax
1023 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
1024 ; WIN32-NEXT: movl %edx, %ebp
1025 ; WIN32-NEXT: movl %eax, %ebx
1026 ; WIN32-NEXT: addl %ecx, %ebx
1027 ; WIN32-NEXT: adcl %edi, %ebp
1028 ; WIN32-NEXT: setb %cl
1029 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1030 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
1031 ; WIN32-NEXT: addl %ebp, %eax
1032 ; WIN32-NEXT: movzbl %cl, %ecx
1033 ; WIN32-NEXT: adcl %ecx, %edx
1034 ; WIN32-NEXT: addl (%esp), %eax # 4-byte Folded Reload
1035 ; WIN32-NEXT: adcl %esi, %edx
1036 ; WIN32-NEXT: sarl $31, %ebx
1037 ; WIN32-NEXT: xorl %ebx, %edx
1038 ; WIN32-NEXT: xorl %eax, %ebx
1039 ; WIN32-NEXT: orl %edx, %ebx
1040 ; WIN32-NEXT: jne LBB18_1
1041 ; WIN32-NEXT: # %bb.3: # %continue
1042 ; WIN32-NEXT: movb $1, %al
1043 ; WIN32-NEXT: LBB18_2: # %overflow
1044 ; WIN32-NEXT: addl $4, %esp
1045 ; WIN32-NEXT: popl %esi
1046 ; WIN32-NEXT: popl %edi
1047 ; WIN32-NEXT: popl %ebx
1048 ; WIN32-NEXT: popl %ebp
1050 ; WIN32-NEXT: LBB18_1: # %overflow
1051 ; WIN32-NEXT: xorl %eax, %eax
1052 ; WIN32-NEXT: jmp LBB18_2
1053 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
1054 %val = extractvalue {i64, i1} %t, 0
1055 %obit = extractvalue {i64, i1} %t, 1
1056 br i1 %obit, label %overflow, label %continue, !prof !0
1065 define zeroext i1 @umulobri8(i8 %v1, i8 %v2) {
1066 ; SDAG-LABEL: umulobri8:
1068 ; SDAG-NEXT: movl %edi, %eax
1069 ; SDAG-NEXT: # kill: def $al killed $al killed $eax
1070 ; SDAG-NEXT: mulb %sil
1071 ; SDAG-NEXT: jo .LBB19_1
1072 ; SDAG-NEXT: # %bb.2: # %continue
1073 ; SDAG-NEXT: movb $1, %al
1075 ; SDAG-NEXT: .LBB19_1: # %overflow
1076 ; SDAG-NEXT: xorl %eax, %eax
1079 ; FAST-LABEL: umulobri8:
1081 ; FAST-NEXT: movl %edi, %eax
1082 ; FAST-NEXT: # kill: def $al killed $al killed $eax
1083 ; FAST-NEXT: mulb %sil
1084 ; FAST-NEXT: seto %al
1085 ; FAST-NEXT: testb $1, %al
1086 ; FAST-NEXT: jne .LBB19_1
1087 ; FAST-NEXT: # %bb.2: # %continue
1088 ; FAST-NEXT: movb $1, %al
1089 ; FAST-NEXT: andb $1, %al
1091 ; FAST-NEXT: .LBB19_1: # %overflow
1092 ; FAST-NEXT: xorl %eax, %eax
1093 ; FAST-NEXT: andb $1, %al
1094 ; FAST-NEXT: # kill: def $al killed $al killed $eax
1097 ; WIN64-LABEL: umulobri8:
1099 ; WIN64-NEXT: movl %ecx, %eax
1100 ; WIN64-NEXT: mulb %dl
1101 ; WIN64-NEXT: jo .LBB19_1
1102 ; WIN64-NEXT: # %bb.2: # %continue
1103 ; WIN64-NEXT: movb $1, %al
1105 ; WIN64-NEXT: .LBB19_1: # %overflow
1106 ; WIN64-NEXT: xorl %eax, %eax
1109 ; WIN32-LABEL: umulobri8:
1111 ; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax
1112 ; WIN32-NEXT: mulb {{[0-9]+}}(%esp)
1113 ; WIN32-NEXT: jo LBB19_1
1114 ; WIN32-NEXT: # %bb.2: # %continue
1115 ; WIN32-NEXT: movb $1, %al
1117 ; WIN32-NEXT: LBB19_1: # %overflow
1118 ; WIN32-NEXT: xorl %eax, %eax
1120 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
1121 %val = extractvalue {i8, i1} %t, 0
1122 %obit = extractvalue {i8, i1} %t, 1
1123 br i1 %obit, label %overflow, label %continue, !prof !0
1132 define zeroext i1 @umulobri16(i16 %v1, i16 %v2) {
1133 ; SDAG-LABEL: umulobri16:
1135 ; SDAG-NEXT: movl %edi, %eax
1136 ; SDAG-NEXT: # kill: def $ax killed $ax killed $eax
1137 ; SDAG-NEXT: mulw %si
1138 ; SDAG-NEXT: jo .LBB20_1
1139 ; SDAG-NEXT: # %bb.2: # %continue
1140 ; SDAG-NEXT: movb $1, %al
1142 ; SDAG-NEXT: .LBB20_1: # %overflow
1143 ; SDAG-NEXT: xorl %eax, %eax
1146 ; FAST-LABEL: umulobri16:
1148 ; FAST-NEXT: movl %edi, %eax
1149 ; FAST-NEXT: # kill: def $ax killed $ax killed $eax
1150 ; FAST-NEXT: mulw %si
1151 ; FAST-NEXT: seto %al
1152 ; FAST-NEXT: testb $1, %al
1153 ; FAST-NEXT: jne .LBB20_1
1154 ; FAST-NEXT: # %bb.2: # %continue
1155 ; FAST-NEXT: movb $1, %al
1156 ; FAST-NEXT: andb $1, %al
1158 ; FAST-NEXT: .LBB20_1: # %overflow
1159 ; FAST-NEXT: xorl %eax, %eax
1160 ; FAST-NEXT: andb $1, %al
1161 ; FAST-NEXT: # kill: def $al killed $al killed $eax
1164 ; WIN64-LABEL: umulobri16:
1166 ; WIN64-NEXT: movl %ecx, %eax
1167 ; WIN64-NEXT: mulw %dx
1168 ; WIN64-NEXT: jo .LBB20_1
1169 ; WIN64-NEXT: # %bb.2: # %continue
1170 ; WIN64-NEXT: movb $1, %al
1172 ; WIN64-NEXT: .LBB20_1: # %overflow
1173 ; WIN64-NEXT: xorl %eax, %eax
1176 ; WIN32-LABEL: umulobri16:
1178 ; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax
1179 ; WIN32-NEXT: mulw {{[0-9]+}}(%esp)
1180 ; WIN32-NEXT: jo LBB20_1
1181 ; WIN32-NEXT: # %bb.2: # %continue
1182 ; WIN32-NEXT: movb $1, %al
1184 ; WIN32-NEXT: LBB20_1: # %overflow
1185 ; WIN32-NEXT: xorl %eax, %eax
1187 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
1188 %val = extractvalue {i16, i1} %t, 0
1189 %obit = extractvalue {i16, i1} %t, 1
1190 br i1 %obit, label %overflow, label %continue, !prof !0
1199 define zeroext i1 @umulobri32(i32 %v1, i32 %v2) {
1200 ; SDAG-LABEL: umulobri32:
1202 ; SDAG-NEXT: movl %edi, %eax
1203 ; SDAG-NEXT: mull %esi
1204 ; SDAG-NEXT: jo .LBB21_1
1205 ; SDAG-NEXT: # %bb.2: # %continue
1206 ; SDAG-NEXT: movb $1, %al
1208 ; SDAG-NEXT: .LBB21_1: # %overflow
1209 ; SDAG-NEXT: xorl %eax, %eax
1212 ; FAST-LABEL: umulobri32:
1214 ; FAST-NEXT: movl %edi, %eax
1215 ; FAST-NEXT: mull %esi
1216 ; FAST-NEXT: jo .LBB21_1
1217 ; FAST-NEXT: # %bb.2: # %continue
1218 ; FAST-NEXT: movb $1, %al
1219 ; FAST-NEXT: andb $1, %al
1221 ; FAST-NEXT: .LBB21_1: # %overflow
1222 ; FAST-NEXT: xorl %eax, %eax
1223 ; FAST-NEXT: andb $1, %al
1224 ; FAST-NEXT: # kill: def $al killed $al killed $eax
1227 ; WIN64-LABEL: umulobri32:
1229 ; WIN64-NEXT: movl %ecx, %eax
1230 ; WIN64-NEXT: mull %edx
1231 ; WIN64-NEXT: jo .LBB21_1
1232 ; WIN64-NEXT: # %bb.2: # %continue
1233 ; WIN64-NEXT: movb $1, %al
1235 ; WIN64-NEXT: .LBB21_1: # %overflow
1236 ; WIN64-NEXT: xorl %eax, %eax
1239 ; WIN32-LABEL: umulobri32:
1241 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1242 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
1243 ; WIN32-NEXT: jo LBB21_1
1244 ; WIN32-NEXT: # %bb.2: # %continue
1245 ; WIN32-NEXT: movb $1, %al
1247 ; WIN32-NEXT: LBB21_1: # %overflow
1248 ; WIN32-NEXT: xorl %eax, %eax
1250 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
1251 %val = extractvalue {i32, i1} %t, 0
1252 %obit = extractvalue {i32, i1} %t, 1
1253 br i1 %obit, label %overflow, label %continue, !prof !0
1262 define zeroext i1 @umulobri64(i64 %v1, i64 %v2) {
1263 ; SDAG-LABEL: umulobri64:
1265 ; SDAG-NEXT: movq %rdi, %rax
1266 ; SDAG-NEXT: mulq %rsi
1267 ; SDAG-NEXT: jo .LBB22_1
1268 ; SDAG-NEXT: # %bb.2: # %continue
1269 ; SDAG-NEXT: movb $1, %al
1271 ; SDAG-NEXT: .LBB22_1: # %overflow
1272 ; SDAG-NEXT: xorl %eax, %eax
1275 ; FAST-LABEL: umulobri64:
1277 ; FAST-NEXT: movq %rdi, %rax
1278 ; FAST-NEXT: mulq %rsi
1279 ; FAST-NEXT: jo .LBB22_1
1280 ; FAST-NEXT: # %bb.2: # %continue
1281 ; FAST-NEXT: movb $1, %al
1282 ; FAST-NEXT: andb $1, %al
1284 ; FAST-NEXT: .LBB22_1: # %overflow
1285 ; FAST-NEXT: xorl %eax, %eax
1286 ; FAST-NEXT: andb $1, %al
1287 ; FAST-NEXT: # kill: def $al killed $al killed $eax
1290 ; WIN64-LABEL: umulobri64:
1292 ; WIN64-NEXT: movq %rcx, %rax
1293 ; WIN64-NEXT: mulq %rdx
1294 ; WIN64-NEXT: jo .LBB22_1
1295 ; WIN64-NEXT: # %bb.2: # %continue
1296 ; WIN64-NEXT: movb $1, %al
1298 ; WIN64-NEXT: .LBB22_1: # %overflow
1299 ; WIN64-NEXT: xorl %eax, %eax
1302 ; WIN32-LABEL: umulobri64:
1304 ; WIN32-NEXT: pushl %ebp
1305 ; WIN32-NEXT: pushl %ebx
1306 ; WIN32-NEXT: pushl %edi
1307 ; WIN32-NEXT: pushl %esi
1308 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebp
1309 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1310 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
1311 ; WIN32-NEXT: testl %esi, %esi
1312 ; WIN32-NEXT: setne %dl
1313 ; WIN32-NEXT: testl %eax, %eax
1314 ; WIN32-NEXT: setne %cl
1315 ; WIN32-NEXT: andb %dl, %cl
1316 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
1317 ; WIN32-NEXT: movl %eax, %edi
1318 ; WIN32-NEXT: seto %bl
1319 ; WIN32-NEXT: movl %esi, %eax
1320 ; WIN32-NEXT: mull %ebp
1321 ; WIN32-NEXT: seto %ch
1322 ; WIN32-NEXT: orb %bl, %ch
1323 ; WIN32-NEXT: orb %cl, %ch
1324 ; WIN32-NEXT: leal (%edi,%eax), %esi
1325 ; WIN32-NEXT: movl %ebp, %eax
1326 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
1327 ; WIN32-NEXT: addl %esi, %edx
1328 ; WIN32-NEXT: setb %al
1329 ; WIN32-NEXT: orb %ch, %al
1330 ; WIN32-NEXT: subb $1, %al
1331 ; WIN32-NEXT: je LBB22_1
1332 ; WIN32-NEXT: # %bb.3: # %continue
1333 ; WIN32-NEXT: movb $1, %al
1334 ; WIN32-NEXT: LBB22_2: # %overflow
1335 ; WIN32-NEXT: popl %esi
1336 ; WIN32-NEXT: popl %edi
1337 ; WIN32-NEXT: popl %ebx
1338 ; WIN32-NEXT: popl %ebp
1340 ; WIN32-NEXT: LBB22_1: # %overflow
1341 ; WIN32-NEXT: xorl %eax, %eax
1342 ; WIN32-NEXT: jmp LBB22_2
1343 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
1344 %val = extractvalue {i64, i1} %t, 0
1345 %obit = extractvalue {i64, i1} %t, 1
1346 br i1 %obit, label %overflow, label %continue, !prof !0
1355 define i1 @bug27873(i64 %c1, i1 %c2) {
1356 ; LINUX-LABEL: bug27873:
1358 ; LINUX-NEXT: movq %rdi, %rax
1359 ; LINUX-NEXT: movl $160, %ecx
1360 ; LINUX-NEXT: mulq %rcx
1361 ; LINUX-NEXT: seto %al
1362 ; LINUX-NEXT: orb %sil, %al
1365 ; WIN64-LABEL: bug27873:
1367 ; WIN64-NEXT: movl %edx, %r8d
1368 ; WIN64-NEXT: movq %rcx, %rax
1369 ; WIN64-NEXT: movl $160, %ecx
1370 ; WIN64-NEXT: mulq %rcx
1371 ; WIN64-NEXT: seto %al
1372 ; WIN64-NEXT: orb %r8b, %al
1375 ; WIN32-LABEL: bug27873:
1377 ; WIN32-NEXT: pushl %ebx
1378 ; WIN32-NEXT: movl $160, %eax
1379 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
1380 ; WIN32-NEXT: movl %eax, %ecx
1381 ; WIN32-NEXT: seto %bl
1382 ; WIN32-NEXT: movl $160, %eax
1383 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
1384 ; WIN32-NEXT: addl %ecx, %edx
1385 ; WIN32-NEXT: setb %al
1386 ; WIN32-NEXT: orb %bl, %al
1387 ; WIN32-NEXT: orb {{[0-9]+}}(%esp), %al
1388 ; WIN32-NEXT: popl %ebx
1390 %mul = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %c1, i64 160)
1391 %mul.overflow = extractvalue { i64, i1 } %mul, 1
1392 %x1 = or i1 %c2, %mul.overflow
1396 define zeroext i1 @smuloi8_load(ptr %ptr1, i8 %v2, ptr %res) {
1397 ; SDAG-LABEL: smuloi8_load:
1399 ; SDAG-NEXT: movl %esi, %eax
1400 ; SDAG-NEXT: # kill: def $al killed $al killed $eax
1401 ; SDAG-NEXT: imulb (%rdi)
1402 ; SDAG-NEXT: seto %cl
1403 ; SDAG-NEXT: movb %al, (%rdx)
1404 ; SDAG-NEXT: movl %ecx, %eax
1407 ; FAST-LABEL: smuloi8_load:
1409 ; FAST-NEXT: movzbl (%rdi), %eax
1410 ; FAST-NEXT: imulb %sil
1411 ; FAST-NEXT: seto %cl
1412 ; FAST-NEXT: movb %al, (%rdx)
1413 ; FAST-NEXT: andb $1, %cl
1414 ; FAST-NEXT: movl %ecx, %eax
1417 ; WIN64-LABEL: smuloi8_load:
1419 ; WIN64-NEXT: movl %edx, %eax
1420 ; WIN64-NEXT: imulb (%rcx)
1421 ; WIN64-NEXT: seto %cl
1422 ; WIN64-NEXT: movb %al, (%r8)
1423 ; WIN64-NEXT: movl %ecx, %eax
1426 ; WIN32-LABEL: smuloi8_load:
1428 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
1429 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1430 ; WIN32-NEXT: movzbl (%eax), %eax
1431 ; WIN32-NEXT: imulb {{[0-9]+}}(%esp)
1432 ; WIN32-NEXT: seto %cl
1433 ; WIN32-NEXT: movb %al, (%edx)
1434 ; WIN32-NEXT: movl %ecx, %eax
1436 %v1 = load i8, ptr %ptr1
1437 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
1438 %val = extractvalue {i8, i1} %t, 0
1439 %obit = extractvalue {i8, i1} %t, 1
1440 store i8 %val, ptr %res
1444 define zeroext i1 @smuloi8_load2(i8 %v1, ptr %ptr2, ptr %res) {
1445 ; SDAG-LABEL: smuloi8_load2:
1447 ; SDAG-NEXT: movl %edi, %eax
1448 ; SDAG-NEXT: # kill: def $al killed $al killed $eax
1449 ; SDAG-NEXT: imulb (%rsi)
1450 ; SDAG-NEXT: seto %cl
1451 ; SDAG-NEXT: movb %al, (%rdx)
1452 ; SDAG-NEXT: movl %ecx, %eax
1455 ; FAST-LABEL: smuloi8_load2:
1457 ; FAST-NEXT: movl %edi, %eax
1458 ; FAST-NEXT: # kill: def $al killed $al killed $eax
1459 ; FAST-NEXT: imulb (%rsi)
1460 ; FAST-NEXT: seto %cl
1461 ; FAST-NEXT: movb %al, (%rdx)
1462 ; FAST-NEXT: andb $1, %cl
1463 ; FAST-NEXT: movl %ecx, %eax
1466 ; WIN64-LABEL: smuloi8_load2:
1468 ; WIN64-NEXT: movl %ecx, %eax
1469 ; WIN64-NEXT: imulb (%rdx)
1470 ; WIN64-NEXT: seto %cl
1471 ; WIN64-NEXT: movb %al, (%r8)
1472 ; WIN64-NEXT: movl %ecx, %eax
1475 ; WIN32-LABEL: smuloi8_load2:
1477 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
1478 ; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax
1479 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
1480 ; WIN32-NEXT: imulb (%ecx)
1481 ; WIN32-NEXT: seto %cl
1482 ; WIN32-NEXT: movb %al, (%edx)
1483 ; WIN32-NEXT: movl %ecx, %eax
1485 %v2 = load i8, ptr %ptr2
1486 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
1487 %val = extractvalue {i8, i1} %t, 0
1488 %obit = extractvalue {i8, i1} %t, 1
1489 store i8 %val, ptr %res
1493 define zeroext i1 @smuloi16_load(ptr %ptr1, i16 %v2, ptr %res) {
1494 ; SDAG-LABEL: smuloi16_load:
1496 ; SDAG-NEXT: imulw (%rdi), %si
1497 ; SDAG-NEXT: seto %al
1498 ; SDAG-NEXT: movw %si, (%rdx)
1501 ; FAST-LABEL: smuloi16_load:
1503 ; FAST-NEXT: imulw (%rdi), %si
1504 ; FAST-NEXT: seto %al
1505 ; FAST-NEXT: movw %si, (%rdx)
1506 ; FAST-NEXT: andb $1, %al
1509 ; WIN64-LABEL: smuloi16_load:
1511 ; WIN64-NEXT: imulw (%rcx), %dx
1512 ; WIN64-NEXT: seto %al
1513 ; WIN64-NEXT: movw %dx, (%r8)
1516 ; WIN32-LABEL: smuloi16_load:
1518 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
1519 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1520 ; WIN32-NEXT: movzwl (%eax), %edx
1521 ; WIN32-NEXT: imulw {{[0-9]+}}(%esp), %dx
1522 ; WIN32-NEXT: seto %al
1523 ; WIN32-NEXT: movw %dx, (%ecx)
1525 %v1 = load i16, ptr %ptr1
1526 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
1527 %val = extractvalue {i16, i1} %t, 0
1528 %obit = extractvalue {i16, i1} %t, 1
1529 store i16 %val, ptr %res
1533 define zeroext i1 @smuloi16_load2(i16 %v1, ptr %ptr2, ptr %res) {
1534 ; SDAG-LABEL: smuloi16_load2:
1536 ; SDAG-NEXT: imulw (%rsi), %di
1537 ; SDAG-NEXT: seto %al
1538 ; SDAG-NEXT: movw %di, (%rdx)
1541 ; FAST-LABEL: smuloi16_load2:
1543 ; FAST-NEXT: imulw (%rsi), %di
1544 ; FAST-NEXT: seto %al
1545 ; FAST-NEXT: movw %di, (%rdx)
1546 ; FAST-NEXT: andb $1, %al
1549 ; WIN64-LABEL: smuloi16_load2:
1551 ; WIN64-NEXT: imulw (%rdx), %cx
1552 ; WIN64-NEXT: seto %al
1553 ; WIN64-NEXT: movw %cx, (%r8)
1556 ; WIN32-LABEL: smuloi16_load2:
1558 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
1559 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1560 ; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %edx
1561 ; WIN32-NEXT: imulw (%eax), %dx
1562 ; WIN32-NEXT: seto %al
1563 ; WIN32-NEXT: movw %dx, (%ecx)
1565 %v2 = load i16, ptr %ptr2
1566 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
1567 %val = extractvalue {i16, i1} %t, 0
1568 %obit = extractvalue {i16, i1} %t, 1
1569 store i16 %val, ptr %res
1573 define zeroext i1 @smuloi32_load(ptr %ptr1, i32 %v2, ptr %res) {
1574 ; SDAG-LABEL: smuloi32_load:
1576 ; SDAG-NEXT: imull (%rdi), %esi
1577 ; SDAG-NEXT: seto %al
1578 ; SDAG-NEXT: movl %esi, (%rdx)
1581 ; FAST-LABEL: smuloi32_load:
1583 ; FAST-NEXT: imull (%rdi), %esi
1584 ; FAST-NEXT: seto %al
1585 ; FAST-NEXT: movl %esi, (%rdx)
1586 ; FAST-NEXT: andb $1, %al
1589 ; WIN64-LABEL: smuloi32_load:
1591 ; WIN64-NEXT: imull (%rcx), %edx
1592 ; WIN64-NEXT: seto %al
1593 ; WIN64-NEXT: movl %edx, (%r8)
1596 ; WIN32-LABEL: smuloi32_load:
1598 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
1599 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1600 ; WIN32-NEXT: movl (%eax), %edx
1601 ; WIN32-NEXT: imull {{[0-9]+}}(%esp), %edx
1602 ; WIN32-NEXT: seto %al
1603 ; WIN32-NEXT: movl %edx, (%ecx)
1605 %v1 = load i32, ptr %ptr1
1606 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
1607 %val = extractvalue {i32, i1} %t, 0
1608 %obit = extractvalue {i32, i1} %t, 1
1609 store i32 %val, ptr %res
1613 define zeroext i1 @smuloi32_load2(i32 %v1, ptr %ptr2, ptr %res) {
1614 ; SDAG-LABEL: smuloi32_load2:
1616 ; SDAG-NEXT: imull (%rsi), %edi
1617 ; SDAG-NEXT: seto %al
1618 ; SDAG-NEXT: movl %edi, (%rdx)
1621 ; FAST-LABEL: smuloi32_load2:
1623 ; FAST-NEXT: imull (%rsi), %edi
1624 ; FAST-NEXT: seto %al
1625 ; FAST-NEXT: movl %edi, (%rdx)
1626 ; FAST-NEXT: andb $1, %al
1629 ; WIN64-LABEL: smuloi32_load2:
1631 ; WIN64-NEXT: imull (%rdx), %ecx
1632 ; WIN64-NEXT: seto %al
1633 ; WIN64-NEXT: movl %ecx, (%r8)
1636 ; WIN32-LABEL: smuloi32_load2:
1638 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
1639 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1640 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
1641 ; WIN32-NEXT: imull (%eax), %edx
1642 ; WIN32-NEXT: seto %al
1643 ; WIN32-NEXT: movl %edx, (%ecx)
1645 %v2 = load i32, ptr %ptr2
1646 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
1647 %val = extractvalue {i32, i1} %t, 0
1648 %obit = extractvalue {i32, i1} %t, 1
1649 store i32 %val, ptr %res
1653 define zeroext i1 @smuloi64_load(ptr %ptr1, i64 %v2, ptr %res) {
1654 ; SDAG-LABEL: smuloi64_load:
1656 ; SDAG-NEXT: imulq (%rdi), %rsi
1657 ; SDAG-NEXT: seto %al
1658 ; SDAG-NEXT: movq %rsi, (%rdx)
1661 ; FAST-LABEL: smuloi64_load:
1663 ; FAST-NEXT: imulq (%rdi), %rsi
1664 ; FAST-NEXT: seto %al
1665 ; FAST-NEXT: movq %rsi, (%rdx)
1666 ; FAST-NEXT: andb $1, %al
1669 ; WIN64-LABEL: smuloi64_load:
1671 ; WIN64-NEXT: imulq (%rcx), %rdx
1672 ; WIN64-NEXT: seto %al
1673 ; WIN64-NEXT: movq %rdx, (%r8)
1676 ; WIN32-LABEL: smuloi64_load:
1678 ; WIN32-NEXT: pushl %ebp
1679 ; WIN32-NEXT: pushl %ebx
1680 ; WIN32-NEXT: pushl %edi
1681 ; WIN32-NEXT: pushl %esi
1682 ; WIN32-NEXT: subl $20, %esp
1683 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
1684 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1685 ; WIN32-NEXT: movl (%eax), %ebx
1686 ; WIN32-NEXT: movl %ebx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
1687 ; WIN32-NEXT: movl 4(%eax), %ebp
1688 ; WIN32-NEXT: movl %ecx, %eax
1689 ; WIN32-NEXT: movl %ecx, %edi
1690 ; WIN32-NEXT: sarl $31, %eax
1691 ; WIN32-NEXT: movl %eax, %ecx
1692 ; WIN32-NEXT: imull %ebp, %ecx
1693 ; WIN32-NEXT: mull %ebx
1694 ; WIN32-NEXT: movl %eax, (%esp) # 4-byte Spill
1695 ; WIN32-NEXT: movl %edx, %ebx
1696 ; WIN32-NEXT: addl %ecx, %ebx
1697 ; WIN32-NEXT: movl %ebp, %ecx
1698 ; WIN32-NEXT: movl %ebp, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
1699 ; WIN32-NEXT: sarl $31, %ecx
1700 ; WIN32-NEXT: movl %edi, %esi
1701 ; WIN32-NEXT: imull %ecx, %esi
1702 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1703 ; WIN32-NEXT: mull %ecx
1704 ; WIN32-NEXT: movl %edx, %edi
1705 ; WIN32-NEXT: addl %eax, %edi
1706 ; WIN32-NEXT: addl %esi, %edi
1707 ; WIN32-NEXT: movl (%esp), %ecx # 4-byte Reload
1708 ; WIN32-NEXT: addl %ecx, %ebx
1709 ; WIN32-NEXT: addl %eax, %ecx
1710 ; WIN32-NEXT: movl %ecx, (%esp) # 4-byte Spill
1711 ; WIN32-NEXT: adcl %ebx, %edi
1712 ; WIN32-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
1713 ; WIN32-NEXT: movl %ecx, %eax
1714 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
1715 ; WIN32-NEXT: mull %esi
1716 ; WIN32-NEXT: movl %edx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
1717 ; WIN32-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
1718 ; WIN32-NEXT: movl %ebp, %eax
1719 ; WIN32-NEXT: mull %esi
1720 ; WIN32-NEXT: movl %edx, %ebx
1721 ; WIN32-NEXT: movl %eax, %esi
1722 ; WIN32-NEXT: addl {{[-0-9]+}}(%e{{[sb]}}p), %esi # 4-byte Folded Reload
1723 ; WIN32-NEXT: adcl $0, %ebx
1724 ; WIN32-NEXT: movl %ecx, %eax
1725 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
1726 ; WIN32-NEXT: movl %edx, %ecx
1727 ; WIN32-NEXT: movl %eax, %ebp
1728 ; WIN32-NEXT: addl %esi, %ebp
1729 ; WIN32-NEXT: adcl %ebx, %ecx
1730 ; WIN32-NEXT: setb %bl
1731 ; WIN32-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Reload
1732 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
1733 ; WIN32-NEXT: addl %ecx, %eax
1734 ; WIN32-NEXT: movzbl %bl, %ecx
1735 ; WIN32-NEXT: adcl %ecx, %edx
1736 ; WIN32-NEXT: addl (%esp), %eax # 4-byte Folded Reload
1737 ; WIN32-NEXT: adcl %edi, %edx
1738 ; WIN32-NEXT: movl %ebp, %ecx
1739 ; WIN32-NEXT: sarl $31, %ecx
1740 ; WIN32-NEXT: xorl %ecx, %edx
1741 ; WIN32-NEXT: xorl %eax, %ecx
1742 ; WIN32-NEXT: orl %edx, %ecx
1743 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1744 ; WIN32-NEXT: movl %ebp, 4(%eax)
1745 ; WIN32-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
1746 ; WIN32-NEXT: movl %ecx, (%eax)
1747 ; WIN32-NEXT: setne %al
1748 ; WIN32-NEXT: addl $20, %esp
1749 ; WIN32-NEXT: popl %esi
1750 ; WIN32-NEXT: popl %edi
1751 ; WIN32-NEXT: popl %ebx
1752 ; WIN32-NEXT: popl %ebp
1754 %v1 = load i64, ptr %ptr1
1755 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
1756 %val = extractvalue {i64, i1} %t, 0
1757 %obit = extractvalue {i64, i1} %t, 1
1758 store i64 %val, ptr %res
1762 define zeroext i1 @smuloi64_load2(i64 %v1, ptr %ptr2, ptr %res) {
1763 ; SDAG-LABEL: smuloi64_load2:
1765 ; SDAG-NEXT: imulq (%rsi), %rdi
1766 ; SDAG-NEXT: seto %al
1767 ; SDAG-NEXT: movq %rdi, (%rdx)
1770 ; FAST-LABEL: smuloi64_load2:
1772 ; FAST-NEXT: imulq (%rsi), %rdi
1773 ; FAST-NEXT: seto %al
1774 ; FAST-NEXT: movq %rdi, (%rdx)
1775 ; FAST-NEXT: andb $1, %al
1778 ; WIN64-LABEL: smuloi64_load2:
1780 ; WIN64-NEXT: imulq (%rdx), %rcx
1781 ; WIN64-NEXT: seto %al
1782 ; WIN64-NEXT: movq %rcx, (%r8)
1785 ; WIN32-LABEL: smuloi64_load2:
1787 ; WIN32-NEXT: pushl %ebp
1788 ; WIN32-NEXT: pushl %ebx
1789 ; WIN32-NEXT: pushl %edi
1790 ; WIN32-NEXT: pushl %esi
1791 ; WIN32-NEXT: subl $12, %esp
1792 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
1793 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1794 ; WIN32-NEXT: movl (%eax), %ebp
1795 ; WIN32-NEXT: movl 4(%eax), %eax
1796 ; WIN32-NEXT: sarl $31, %ecx
1797 ; WIN32-NEXT: movl %eax, %esi
1798 ; WIN32-NEXT: movl %eax, %edi
1799 ; WIN32-NEXT: movl %eax, (%esp) # 4-byte Spill
1800 ; WIN32-NEXT: imull %ecx, %esi
1801 ; WIN32-NEXT: movl %ebp, %eax
1802 ; WIN32-NEXT: mull %ecx
1803 ; WIN32-NEXT: movl %edx, %ecx
1804 ; WIN32-NEXT: movl %eax, %ebx
1805 ; WIN32-NEXT: addl %eax, %ecx
1806 ; WIN32-NEXT: addl %esi, %ecx
1807 ; WIN32-NEXT: movl %edi, %eax
1808 ; WIN32-NEXT: sarl $31, %eax
1809 ; WIN32-NEXT: movl %eax, %edi
1810 ; WIN32-NEXT: imull {{[0-9]+}}(%esp), %edi
1811 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
1812 ; WIN32-NEXT: movl %edx, %esi
1813 ; WIN32-NEXT: addl %edi, %esi
1814 ; WIN32-NEXT: addl %eax, %esi
1815 ; WIN32-NEXT: addl %ebx, %eax
1816 ; WIN32-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
1817 ; WIN32-NEXT: adcl %ecx, %esi
1818 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1819 ; WIN32-NEXT: mull %ebp
1820 ; WIN32-NEXT: movl %edx, %ebx
1821 ; WIN32-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
1822 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1823 ; WIN32-NEXT: mull %ebp
1824 ; WIN32-NEXT: movl %edx, %edi
1825 ; WIN32-NEXT: movl %eax, %ecx
1826 ; WIN32-NEXT: addl %ebx, %ecx
1827 ; WIN32-NEXT: adcl $0, %edi
1828 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1829 ; WIN32-NEXT: mull (%esp) # 4-byte Folded Reload
1830 ; WIN32-NEXT: movl %edx, %ebx
1831 ; WIN32-NEXT: movl %eax, %ebp
1832 ; WIN32-NEXT: addl %ecx, %ebp
1833 ; WIN32-NEXT: adcl %edi, %ebx
1834 ; WIN32-NEXT: setb %cl
1835 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1836 ; WIN32-NEXT: mull (%esp) # 4-byte Folded Reload
1837 ; WIN32-NEXT: addl %ebx, %eax
1838 ; WIN32-NEXT: movzbl %cl, %ecx
1839 ; WIN32-NEXT: adcl %ecx, %edx
1840 ; WIN32-NEXT: addl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Folded Reload
1841 ; WIN32-NEXT: adcl %esi, %edx
1842 ; WIN32-NEXT: movl %ebp, %ecx
1843 ; WIN32-NEXT: sarl $31, %ecx
1844 ; WIN32-NEXT: xorl %ecx, %edx
1845 ; WIN32-NEXT: xorl %eax, %ecx
1846 ; WIN32-NEXT: orl %edx, %ecx
1847 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1848 ; WIN32-NEXT: movl %ebp, 4(%eax)
1849 ; WIN32-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
1850 ; WIN32-NEXT: movl %ecx, (%eax)
1851 ; WIN32-NEXT: setne %al
1852 ; WIN32-NEXT: addl $12, %esp
1853 ; WIN32-NEXT: popl %esi
1854 ; WIN32-NEXT: popl %edi
1855 ; WIN32-NEXT: popl %ebx
1856 ; WIN32-NEXT: popl %ebp
1858 %v2 = load i64, ptr %ptr2
1859 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
1860 %val = extractvalue {i64, i1} %t, 0
1861 %obit = extractvalue {i64, i1} %t, 1
1862 store i64 %val, ptr %res
1866 define zeroext i1 @umuloi8_load(ptr %ptr1, i8 %v2, ptr %res) {
1867 ; SDAG-LABEL: umuloi8_load:
1869 ; SDAG-NEXT: movl %esi, %eax
1870 ; SDAG-NEXT: # kill: def $al killed $al killed $eax
1871 ; SDAG-NEXT: mulb (%rdi)
1872 ; SDAG-NEXT: seto %cl
1873 ; SDAG-NEXT: movb %al, (%rdx)
1874 ; SDAG-NEXT: movl %ecx, %eax
1877 ; FAST-LABEL: umuloi8_load:
1879 ; FAST-NEXT: movzbl (%rdi), %eax
1880 ; FAST-NEXT: mulb %sil
1881 ; FAST-NEXT: seto %cl
1882 ; FAST-NEXT: movb %al, (%rdx)
1883 ; FAST-NEXT: andb $1, %cl
1884 ; FAST-NEXT: movl %ecx, %eax
1887 ; WIN64-LABEL: umuloi8_load:
1889 ; WIN64-NEXT: movl %edx, %eax
1890 ; WIN64-NEXT: mulb (%rcx)
1891 ; WIN64-NEXT: seto %cl
1892 ; WIN64-NEXT: movb %al, (%r8)
1893 ; WIN64-NEXT: movl %ecx, %eax
1896 ; WIN32-LABEL: umuloi8_load:
1898 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
1899 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1900 ; WIN32-NEXT: movzbl (%eax), %eax
1901 ; WIN32-NEXT: mulb {{[0-9]+}}(%esp)
1902 ; WIN32-NEXT: seto %cl
1903 ; WIN32-NEXT: movb %al, (%edx)
1904 ; WIN32-NEXT: movl %ecx, %eax
1906 %v1 = load i8, ptr %ptr1
1907 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
1908 %val = extractvalue {i8, i1} %t, 0
1909 %obit = extractvalue {i8, i1} %t, 1
1910 store i8 %val, ptr %res
1914 define zeroext i1 @umuloi8_load2(i8 %v1, ptr %ptr2, ptr %res) {
1915 ; SDAG-LABEL: umuloi8_load2:
1917 ; SDAG-NEXT: movl %edi, %eax
1918 ; SDAG-NEXT: # kill: def $al killed $al killed $eax
1919 ; SDAG-NEXT: mulb (%rsi)
1920 ; SDAG-NEXT: seto %cl
1921 ; SDAG-NEXT: movb %al, (%rdx)
1922 ; SDAG-NEXT: movl %ecx, %eax
1925 ; FAST-LABEL: umuloi8_load2:
1927 ; FAST-NEXT: movl %edi, %eax
1928 ; FAST-NEXT: # kill: def $al killed $al killed $eax
1929 ; FAST-NEXT: mulb (%rsi)
1930 ; FAST-NEXT: seto %cl
1931 ; FAST-NEXT: movb %al, (%rdx)
1932 ; FAST-NEXT: andb $1, %cl
1933 ; FAST-NEXT: movl %ecx, %eax
1936 ; WIN64-LABEL: umuloi8_load2:
1938 ; WIN64-NEXT: movl %ecx, %eax
1939 ; WIN64-NEXT: mulb (%rdx)
1940 ; WIN64-NEXT: seto %cl
1941 ; WIN64-NEXT: movb %al, (%r8)
1942 ; WIN64-NEXT: movl %ecx, %eax
1945 ; WIN32-LABEL: umuloi8_load2:
1947 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
1948 ; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax
1949 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
1950 ; WIN32-NEXT: mulb (%ecx)
1951 ; WIN32-NEXT: seto %cl
1952 ; WIN32-NEXT: movb %al, (%edx)
1953 ; WIN32-NEXT: movl %ecx, %eax
1955 %v2 = load i8, ptr %ptr2
1956 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
1957 %val = extractvalue {i8, i1} %t, 0
1958 %obit = extractvalue {i8, i1} %t, 1
1959 store i8 %val, ptr %res
1963 define zeroext i1 @umuloi16_load(ptr %ptr1, i16 %v2, ptr %res) {
1964 ; SDAG-LABEL: umuloi16_load:
1966 ; SDAG-NEXT: movq %rdx, %rcx
1967 ; SDAG-NEXT: movl %esi, %eax
1968 ; SDAG-NEXT: # kill: def $ax killed $ax killed $eax
1969 ; SDAG-NEXT: mulw (%rdi)
1970 ; SDAG-NEXT: seto %dl
1971 ; SDAG-NEXT: movw %ax, (%rcx)
1972 ; SDAG-NEXT: movl %edx, %eax
1975 ; FAST-LABEL: umuloi16_load:
1977 ; FAST-NEXT: movq %rdx, %rcx
1978 ; FAST-NEXT: movzwl (%rdi), %eax
1979 ; FAST-NEXT: mulw %si
1980 ; FAST-NEXT: seto %dl
1981 ; FAST-NEXT: movw %ax, (%rcx)
1982 ; FAST-NEXT: andb $1, %dl
1983 ; FAST-NEXT: movl %edx, %eax
1986 ; WIN64-LABEL: umuloi16_load:
1988 ; WIN64-NEXT: movl %edx, %eax
1989 ; WIN64-NEXT: mulw (%rcx)
1990 ; WIN64-NEXT: seto %cl
1991 ; WIN64-NEXT: movw %ax, (%r8)
1992 ; WIN64-NEXT: movl %ecx, %eax
1995 ; WIN32-LABEL: umuloi16_load:
1997 ; WIN32-NEXT: pushl %esi
1998 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
1999 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
2000 ; WIN32-NEXT: movzwl (%eax), %eax
2001 ; WIN32-NEXT: mulw {{[0-9]+}}(%esp)
2002 ; WIN32-NEXT: seto %cl
2003 ; WIN32-NEXT: movw %ax, (%esi)
2004 ; WIN32-NEXT: movl %ecx, %eax
2005 ; WIN32-NEXT: popl %esi
2007 %v1 = load i16, ptr %ptr1
2008 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
2009 %val = extractvalue {i16, i1} %t, 0
2010 %obit = extractvalue {i16, i1} %t, 1
2011 store i16 %val, ptr %res
2015 define zeroext i1 @umuloi16_load2(i16 %v1, ptr %ptr2, ptr %res) {
2016 ; SDAG-LABEL: umuloi16_load2:
2018 ; SDAG-NEXT: movq %rdx, %rcx
2019 ; SDAG-NEXT: movl %edi, %eax
2020 ; SDAG-NEXT: # kill: def $ax killed $ax killed $eax
2021 ; SDAG-NEXT: mulw (%rsi)
2022 ; SDAG-NEXT: seto %dl
2023 ; SDAG-NEXT: movw %ax, (%rcx)
2024 ; SDAG-NEXT: movl %edx, %eax
2027 ; FAST-LABEL: umuloi16_load2:
2029 ; FAST-NEXT: movq %rdx, %rcx
2030 ; FAST-NEXT: movl %edi, %eax
2031 ; FAST-NEXT: # kill: def $ax killed $ax killed $eax
2032 ; FAST-NEXT: mulw (%rsi)
2033 ; FAST-NEXT: seto %dl
2034 ; FAST-NEXT: movw %ax, (%rcx)
2035 ; FAST-NEXT: andb $1, %dl
2036 ; FAST-NEXT: movl %edx, %eax
2039 ; WIN64-LABEL: umuloi16_load2:
2041 ; WIN64-NEXT: movl %ecx, %eax
2042 ; WIN64-NEXT: mulw (%rdx)
2043 ; WIN64-NEXT: seto %cl
2044 ; WIN64-NEXT: movw %ax, (%r8)
2045 ; WIN64-NEXT: movl %ecx, %eax
2048 ; WIN32-LABEL: umuloi16_load2:
2050 ; WIN32-NEXT: pushl %esi
2051 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
2052 ; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax
2053 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
2054 ; WIN32-NEXT: mulw (%ecx)
2055 ; WIN32-NEXT: seto %cl
2056 ; WIN32-NEXT: movw %ax, (%esi)
2057 ; WIN32-NEXT: movl %ecx, %eax
2058 ; WIN32-NEXT: popl %esi
2060 %v2 = load i16, ptr %ptr2
2061 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
2062 %val = extractvalue {i16, i1} %t, 0
2063 %obit = extractvalue {i16, i1} %t, 1
2064 store i16 %val, ptr %res
2068 define zeroext i1 @umuloi32_load(ptr %ptr1, i32 %v2, ptr %res) {
2069 ; SDAG-LABEL: umuloi32_load:
2071 ; SDAG-NEXT: movq %rdx, %rcx
2072 ; SDAG-NEXT: movl %esi, %eax
2073 ; SDAG-NEXT: mull (%rdi)
2074 ; SDAG-NEXT: seto %dl
2075 ; SDAG-NEXT: movl %eax, (%rcx)
2076 ; SDAG-NEXT: movl %edx, %eax
2079 ; FAST-LABEL: umuloi32_load:
2081 ; FAST-NEXT: movq %rdx, %rcx
2082 ; FAST-NEXT: movl (%rdi), %eax
2083 ; FAST-NEXT: mull %esi
2084 ; FAST-NEXT: seto %dl
2085 ; FAST-NEXT: movl %eax, (%rcx)
2086 ; FAST-NEXT: andb $1, %dl
2087 ; FAST-NEXT: movl %edx, %eax
2090 ; WIN64-LABEL: umuloi32_load:
2092 ; WIN64-NEXT: movl %edx, %eax
2093 ; WIN64-NEXT: mull (%rcx)
2094 ; WIN64-NEXT: seto %cl
2095 ; WIN64-NEXT: movl %eax, (%r8)
2096 ; WIN64-NEXT: movl %ecx, %eax
2099 ; WIN32-LABEL: umuloi32_load:
2101 ; WIN32-NEXT: pushl %esi
2102 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
2103 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
2104 ; WIN32-NEXT: movl (%eax), %eax
2105 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
2106 ; WIN32-NEXT: seto %cl
2107 ; WIN32-NEXT: movl %eax, (%esi)
2108 ; WIN32-NEXT: movl %ecx, %eax
2109 ; WIN32-NEXT: popl %esi
2111 %v1 = load i32, ptr %ptr1
2112 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
2113 %val = extractvalue {i32, i1} %t, 0
2114 %obit = extractvalue {i32, i1} %t, 1
2115 store i32 %val, ptr %res
2119 define zeroext i1 @umuloi32_load2(i32 %v1, ptr %ptr2, ptr %res) {
2120 ; SDAG-LABEL: umuloi32_load2:
2122 ; SDAG-NEXT: movq %rdx, %rcx
2123 ; SDAG-NEXT: movl %edi, %eax
2124 ; SDAG-NEXT: mull (%rsi)
2125 ; SDAG-NEXT: seto %dl
2126 ; SDAG-NEXT: movl %eax, (%rcx)
2127 ; SDAG-NEXT: movl %edx, %eax
2130 ; FAST-LABEL: umuloi32_load2:
2132 ; FAST-NEXT: movq %rdx, %rcx
2133 ; FAST-NEXT: movl %edi, %eax
2134 ; FAST-NEXT: mull (%rsi)
2135 ; FAST-NEXT: seto %dl
2136 ; FAST-NEXT: movl %eax, (%rcx)
2137 ; FAST-NEXT: andb $1, %dl
2138 ; FAST-NEXT: movl %edx, %eax
2141 ; WIN64-LABEL: umuloi32_load2:
2143 ; WIN64-NEXT: movl %ecx, %eax
2144 ; WIN64-NEXT: mull (%rdx)
2145 ; WIN64-NEXT: seto %cl
2146 ; WIN64-NEXT: movl %eax, (%r8)
2147 ; WIN64-NEXT: movl %ecx, %eax
2150 ; WIN32-LABEL: umuloi32_load2:
2152 ; WIN32-NEXT: pushl %esi
2153 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
2154 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
2155 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
2156 ; WIN32-NEXT: mull (%ecx)
2157 ; WIN32-NEXT: seto %cl
2158 ; WIN32-NEXT: movl %eax, (%esi)
2159 ; WIN32-NEXT: movl %ecx, %eax
2160 ; WIN32-NEXT: popl %esi
2162 %v2 = load i32, ptr %ptr2
2163 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
2164 %val = extractvalue {i32, i1} %t, 0
2165 %obit = extractvalue {i32, i1} %t, 1
2166 store i32 %val, ptr %res
2170 define zeroext i1 @umuloi64_load(ptr %ptr1, i64 %v2, ptr %res) {
2171 ; SDAG-LABEL: umuloi64_load:
2173 ; SDAG-NEXT: movq %rdx, %rcx
2174 ; SDAG-NEXT: movq %rsi, %rax
2175 ; SDAG-NEXT: mulq (%rdi)
2176 ; SDAG-NEXT: seto %dl
2177 ; SDAG-NEXT: movq %rax, (%rcx)
2178 ; SDAG-NEXT: movl %edx, %eax
2181 ; FAST-LABEL: umuloi64_load:
2183 ; FAST-NEXT: movq %rdx, %rcx
2184 ; FAST-NEXT: movq (%rdi), %rax
2185 ; FAST-NEXT: mulq %rsi
2186 ; FAST-NEXT: seto %dl
2187 ; FAST-NEXT: movq %rax, (%rcx)
2188 ; FAST-NEXT: andb $1, %dl
2189 ; FAST-NEXT: movl %edx, %eax
2192 ; WIN64-LABEL: umuloi64_load:
2194 ; WIN64-NEXT: movq %rdx, %rax
2195 ; WIN64-NEXT: mulq (%rcx)
2196 ; WIN64-NEXT: seto %cl
2197 ; WIN64-NEXT: movq %rax, (%r8)
2198 ; WIN64-NEXT: movl %ecx, %eax
2201 ; WIN32-LABEL: umuloi64_load:
2203 ; WIN32-NEXT: pushl %ebp
2204 ; WIN32-NEXT: pushl %ebx
2205 ; WIN32-NEXT: pushl %edi
2206 ; WIN32-NEXT: pushl %esi
2207 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
2208 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
2209 ; WIN32-NEXT: movl (%eax), %ebp
2210 ; WIN32-NEXT: movl 4(%eax), %eax
2211 ; WIN32-NEXT: testl %esi, %esi
2212 ; WIN32-NEXT: setne %dl
2213 ; WIN32-NEXT: testl %eax, %eax
2214 ; WIN32-NEXT: setne %cl
2215 ; WIN32-NEXT: andb %dl, %cl
2216 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
2217 ; WIN32-NEXT: movl %eax, %edi
2218 ; WIN32-NEXT: seto %bl
2219 ; WIN32-NEXT: movl %esi, %eax
2220 ; WIN32-NEXT: mull %ebp
2221 ; WIN32-NEXT: seto %ch
2222 ; WIN32-NEXT: orb %bl, %ch
2223 ; WIN32-NEXT: orb %cl, %ch
2224 ; WIN32-NEXT: leal (%edi,%eax), %esi
2225 ; WIN32-NEXT: movl %ebp, %eax
2226 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
2227 ; WIN32-NEXT: addl %esi, %edx
2228 ; WIN32-NEXT: setb %cl
2229 ; WIN32-NEXT: orb %ch, %cl
2230 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
2231 ; WIN32-NEXT: movl %eax, (%esi)
2232 ; WIN32-NEXT: movl %edx, 4(%esi)
2233 ; WIN32-NEXT: movl %ecx, %eax
2234 ; WIN32-NEXT: popl %esi
2235 ; WIN32-NEXT: popl %edi
2236 ; WIN32-NEXT: popl %ebx
2237 ; WIN32-NEXT: popl %ebp
2239 %v1 = load i64, ptr %ptr1
2240 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
2241 %val = extractvalue {i64, i1} %t, 0
2242 %obit = extractvalue {i64, i1} %t, 1
2243 store i64 %val, ptr %res
2247 define zeroext i1 @umuloi64_load2(i64 %v1, ptr %ptr2, ptr %res) {
2248 ; SDAG-LABEL: umuloi64_load2:
2250 ; SDAG-NEXT: movq %rdx, %rcx
2251 ; SDAG-NEXT: movq %rdi, %rax
2252 ; SDAG-NEXT: mulq (%rsi)
2253 ; SDAG-NEXT: seto %dl
2254 ; SDAG-NEXT: movq %rax, (%rcx)
2255 ; SDAG-NEXT: movl %edx, %eax
2258 ; FAST-LABEL: umuloi64_load2:
2260 ; FAST-NEXT: movq %rdx, %rcx
2261 ; FAST-NEXT: movq %rdi, %rax
2262 ; FAST-NEXT: mulq (%rsi)
2263 ; FAST-NEXT: seto %dl
2264 ; FAST-NEXT: movq %rax, (%rcx)
2265 ; FAST-NEXT: andb $1, %dl
2266 ; FAST-NEXT: movl %edx, %eax
2269 ; WIN64-LABEL: umuloi64_load2:
2271 ; WIN64-NEXT: movq %rcx, %rax
2272 ; WIN64-NEXT: mulq (%rdx)
2273 ; WIN64-NEXT: seto %cl
2274 ; WIN64-NEXT: movq %rax, (%r8)
2275 ; WIN64-NEXT: movl %ecx, %eax
2278 ; WIN32-LABEL: umuloi64_load2:
2280 ; WIN32-NEXT: pushl %ebp
2281 ; WIN32-NEXT: pushl %ebx
2282 ; WIN32-NEXT: pushl %edi
2283 ; WIN32-NEXT: pushl %esi
2284 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
2285 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
2286 ; WIN32-NEXT: movl (%ecx), %ebp
2287 ; WIN32-NEXT: movl 4(%ecx), %esi
2288 ; WIN32-NEXT: testl %eax, %eax
2289 ; WIN32-NEXT: setne %dl
2290 ; WIN32-NEXT: testl %esi, %esi
2291 ; WIN32-NEXT: setne %cl
2292 ; WIN32-NEXT: andb %dl, %cl
2293 ; WIN32-NEXT: mull %ebp
2294 ; WIN32-NEXT: movl %eax, %edi
2295 ; WIN32-NEXT: seto %bl
2296 ; WIN32-NEXT: movl %esi, %eax
2297 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
2298 ; WIN32-NEXT: seto %ch
2299 ; WIN32-NEXT: orb %bl, %ch
2300 ; WIN32-NEXT: orb %cl, %ch
2301 ; WIN32-NEXT: leal (%edi,%eax), %esi
2302 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
2303 ; WIN32-NEXT: mull %ebp
2304 ; WIN32-NEXT: addl %esi, %edx
2305 ; WIN32-NEXT: setb %cl
2306 ; WIN32-NEXT: orb %ch, %cl
2307 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
2308 ; WIN32-NEXT: movl %eax, (%esi)
2309 ; WIN32-NEXT: movl %edx, 4(%esi)
2310 ; WIN32-NEXT: movl %ecx, %eax
2311 ; WIN32-NEXT: popl %esi
2312 ; WIN32-NEXT: popl %edi
2313 ; WIN32-NEXT: popl %ebx
2314 ; WIN32-NEXT: popl %ebp
2316 %v2 = load i64, ptr %ptr2
2317 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
2318 %val = extractvalue {i64, i1} %t, 0
2319 %obit = extractvalue {i64, i1} %t, 1
2320 store i64 %val, ptr %res
2324 declare {i8, i1} @llvm.smul.with.overflow.i8 (i8, i8 ) nounwind readnone
2325 declare {i16, i1} @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone
2326 declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
2327 declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
2328 declare {i8, i1} @llvm.umul.with.overflow.i8 (i8, i8 ) nounwind readnone
2329 declare {i16, i1} @llvm.umul.with.overflow.i16(i16, i16) nounwind readnone
2330 declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
2331 declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone
2333 !0 = !{!"branch_weights", i32 0, i32 2147483647}