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: movzbl %cl, %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
121 ; FAST-NEXT: movzbl %al, %eax
124 ; WIN64-LABEL: smuloi16:
126 ; WIN64-NEXT: imulw %dx, %cx
127 ; WIN64-NEXT: seto %al
128 ; WIN64-NEXT: movw %cx, (%r8)
131 ; WIN32-LABEL: smuloi16:
133 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
134 ; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %edx
135 ; WIN32-NEXT: imulw {{[0-9]+}}(%esp), %dx
136 ; WIN32-NEXT: seto %al
137 ; WIN32-NEXT: movw %dx, (%ecx)
139 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
140 %val = extractvalue {i16, i1} %t, 0
141 %obit = extractvalue {i16, i1} %t, 1
142 store i16 %val, ptr %res
146 define zeroext i1 @smuloi32(i32 %v1, i32 %v2, ptr %res) {
147 ; SDAG-LABEL: smuloi32:
149 ; SDAG-NEXT: imull %esi, %edi
150 ; SDAG-NEXT: seto %al
151 ; SDAG-NEXT: movl %edi, (%rdx)
154 ; FAST-LABEL: smuloi32:
156 ; FAST-NEXT: imull %esi, %edi
157 ; FAST-NEXT: seto %al
158 ; FAST-NEXT: movl %edi, (%rdx)
159 ; FAST-NEXT: andb $1, %al
160 ; FAST-NEXT: movzbl %al, %eax
163 ; WIN64-LABEL: smuloi32:
165 ; WIN64-NEXT: imull %edx, %ecx
166 ; WIN64-NEXT: seto %al
167 ; WIN64-NEXT: movl %ecx, (%r8)
170 ; WIN32-LABEL: smuloi32:
172 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
173 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
174 ; WIN32-NEXT: imull {{[0-9]+}}(%esp), %edx
175 ; WIN32-NEXT: seto %al
176 ; WIN32-NEXT: movl %edx, (%ecx)
178 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
179 %val = extractvalue {i32, i1} %t, 0
180 %obit = extractvalue {i32, i1} %t, 1
181 store i32 %val, ptr %res
185 define zeroext i1 @smuloi64(i64 %v1, i64 %v2, ptr %res) {
186 ; SDAG-LABEL: smuloi64:
188 ; SDAG-NEXT: imulq %rsi, %rdi
189 ; SDAG-NEXT: seto %al
190 ; SDAG-NEXT: movq %rdi, (%rdx)
193 ; FAST-LABEL: smuloi64:
195 ; FAST-NEXT: imulq %rsi, %rdi
196 ; FAST-NEXT: seto %al
197 ; FAST-NEXT: movq %rdi, (%rdx)
198 ; FAST-NEXT: andb $1, %al
199 ; FAST-NEXT: movzbl %al, %eax
202 ; WIN64-LABEL: smuloi64:
204 ; WIN64-NEXT: imulq %rdx, %rcx
205 ; WIN64-NEXT: seto %al
206 ; WIN64-NEXT: movq %rcx, (%r8)
209 ; WIN32-LABEL: smuloi64:
211 ; WIN32-NEXT: pushl %ebp
212 ; WIN32-NEXT: pushl %ebx
213 ; WIN32-NEXT: pushl %edi
214 ; WIN32-NEXT: pushl %esi
215 ; WIN32-NEXT: subl $8, %esp
216 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
217 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edi
218 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
219 ; WIN32-NEXT: movl %edx, %ecx
220 ; WIN32-NEXT: movl %edx, %ebx
221 ; WIN32-NEXT: sarl $31, %ecx
222 ; WIN32-NEXT: movl %edi, %esi
223 ; WIN32-NEXT: imull %ecx, %esi
224 ; WIN32-NEXT: mull %ecx
225 ; WIN32-NEXT: movl %edx, %ecx
226 ; WIN32-NEXT: movl %eax, %ebp
227 ; WIN32-NEXT: addl %eax, %ecx
228 ; WIN32-NEXT: addl %esi, %ecx
229 ; WIN32-NEXT: movl %edi, %eax
230 ; WIN32-NEXT: sarl $31, %eax
231 ; WIN32-NEXT: movl %eax, %edi
232 ; WIN32-NEXT: imull %ebx, %edi
233 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebx
234 ; WIN32-NEXT: mull %ebx
235 ; WIN32-NEXT: movl %edx, %esi
236 ; WIN32-NEXT: addl %edi, %esi
237 ; WIN32-NEXT: addl %eax, %esi
238 ; WIN32-NEXT: addl %ebp, %eax
239 ; WIN32-NEXT: movl %eax, (%esp) # 4-byte Spill
240 ; WIN32-NEXT: adcl %ecx, %esi
241 ; WIN32-NEXT: movl %ebx, %eax
242 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
243 ; WIN32-NEXT: mull %ecx
244 ; WIN32-NEXT: movl %edx, %ebp
245 ; WIN32-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
246 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
247 ; WIN32-NEXT: mull %ecx
248 ; WIN32-NEXT: movl %edx, %edi
249 ; WIN32-NEXT: movl %eax, %ecx
250 ; WIN32-NEXT: addl %ebp, %ecx
251 ; WIN32-NEXT: adcl $0, %edi
252 ; WIN32-NEXT: movl %ebx, %eax
253 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
254 ; WIN32-NEXT: movl %edx, %ebx
255 ; WIN32-NEXT: movl %eax, %ebp
256 ; WIN32-NEXT: addl %ecx, %ebp
257 ; WIN32-NEXT: adcl %edi, %ebx
258 ; WIN32-NEXT: setb %cl
259 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
260 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
261 ; WIN32-NEXT: addl %ebx, %eax
262 ; WIN32-NEXT: movzbl %cl, %ecx
263 ; WIN32-NEXT: adcl %ecx, %edx
264 ; WIN32-NEXT: addl (%esp), %eax # 4-byte Folded Reload
265 ; WIN32-NEXT: adcl %esi, %edx
266 ; WIN32-NEXT: movl %ebp, %ecx
267 ; WIN32-NEXT: sarl $31, %ecx
268 ; WIN32-NEXT: xorl %ecx, %edx
269 ; WIN32-NEXT: xorl %eax, %ecx
270 ; WIN32-NEXT: orl %edx, %ecx
271 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
272 ; WIN32-NEXT: movl %ebp, 4(%eax)
273 ; WIN32-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
274 ; WIN32-NEXT: movl %ecx, (%eax)
275 ; WIN32-NEXT: setne %al
276 ; WIN32-NEXT: addl $8, %esp
277 ; WIN32-NEXT: popl %esi
278 ; WIN32-NEXT: popl %edi
279 ; WIN32-NEXT: popl %ebx
280 ; WIN32-NEXT: popl %ebp
282 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
283 %val = extractvalue {i64, i1} %t, 0
284 %obit = extractvalue {i64, i1} %t, 1
285 store i64 %val, ptr %res
290 define zeroext i1 @umuloi8(i8 %v1, i8 %v2, ptr %res) {
291 ; SDAG-LABEL: umuloi8:
293 ; SDAG-NEXT: movl %edi, %eax
294 ; SDAG-NEXT: # kill: def $al killed $al killed $eax
295 ; SDAG-NEXT: mulb %sil
296 ; SDAG-NEXT: seto %cl
297 ; SDAG-NEXT: movb %al, (%rdx)
298 ; SDAG-NEXT: movl %ecx, %eax
301 ; FAST-LABEL: umuloi8:
303 ; FAST-NEXT: movl %edi, %eax
304 ; FAST-NEXT: # kill: def $al killed $al killed $eax
305 ; FAST-NEXT: mulb %sil
306 ; FAST-NEXT: seto %cl
307 ; FAST-NEXT: movb %al, (%rdx)
308 ; FAST-NEXT: andb $1, %cl
309 ; FAST-NEXT: movzbl %cl, %eax
312 ; WIN64-LABEL: umuloi8:
314 ; WIN64-NEXT: movl %ecx, %eax
315 ; WIN64-NEXT: mulb %dl
316 ; WIN64-NEXT: seto %cl
317 ; WIN64-NEXT: movb %al, (%r8)
318 ; WIN64-NEXT: movl %ecx, %eax
321 ; WIN32-LABEL: umuloi8:
323 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
324 ; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax
325 ; WIN32-NEXT: mulb {{[0-9]+}}(%esp)
326 ; WIN32-NEXT: seto %cl
327 ; WIN32-NEXT: movb %al, (%edx)
328 ; WIN32-NEXT: movl %ecx, %eax
330 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
331 %val = extractvalue {i8, i1} %t, 0
332 %obit = extractvalue {i8, i1} %t, 1
333 store i8 %val, ptr %res
337 define zeroext i1 @umuloi16(i16 %v1, i16 %v2, ptr %res) {
338 ; SDAG-LABEL: umuloi16:
340 ; SDAG-NEXT: movq %rdx, %rcx
341 ; SDAG-NEXT: movl %edi, %eax
342 ; SDAG-NEXT: # kill: def $ax killed $ax killed $eax
343 ; SDAG-NEXT: mulw %si
344 ; SDAG-NEXT: seto %dl
345 ; SDAG-NEXT: movw %ax, (%rcx)
346 ; SDAG-NEXT: movl %edx, %eax
349 ; FAST-LABEL: umuloi16:
351 ; FAST-NEXT: movq %rdx, %rcx
352 ; FAST-NEXT: movl %edi, %eax
353 ; FAST-NEXT: # kill: def $ax killed $ax killed $eax
354 ; FAST-NEXT: mulw %si
355 ; FAST-NEXT: seto %dl
356 ; FAST-NEXT: movw %ax, (%rcx)
357 ; FAST-NEXT: andb $1, %dl
358 ; FAST-NEXT: movzbl %dl, %eax
361 ; WIN64-LABEL: umuloi16:
363 ; WIN64-NEXT: movl %ecx, %eax
364 ; WIN64-NEXT: mulw %dx
365 ; WIN64-NEXT: seto %cl
366 ; WIN64-NEXT: movw %ax, (%r8)
367 ; WIN64-NEXT: movl %ecx, %eax
370 ; WIN32-LABEL: umuloi16:
372 ; WIN32-NEXT: pushl %esi
373 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
374 ; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax
375 ; WIN32-NEXT: mulw {{[0-9]+}}(%esp)
376 ; WIN32-NEXT: seto %cl
377 ; WIN32-NEXT: movw %ax, (%esi)
378 ; WIN32-NEXT: movl %ecx, %eax
379 ; WIN32-NEXT: popl %esi
381 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
382 %val = extractvalue {i16, i1} %t, 0
383 %obit = extractvalue {i16, i1} %t, 1
384 store i16 %val, ptr %res
388 define zeroext i1 @umuloi32(i32 %v1, i32 %v2, ptr %res) {
389 ; SDAG-LABEL: umuloi32:
391 ; SDAG-NEXT: movq %rdx, %rcx
392 ; SDAG-NEXT: movl %edi, %eax
393 ; SDAG-NEXT: mull %esi
394 ; SDAG-NEXT: seto %dl
395 ; SDAG-NEXT: movl %eax, (%rcx)
396 ; SDAG-NEXT: movl %edx, %eax
399 ; FAST-LABEL: umuloi32:
401 ; FAST-NEXT: movq %rdx, %rcx
402 ; FAST-NEXT: movl %edi, %eax
403 ; FAST-NEXT: mull %esi
404 ; FAST-NEXT: seto %dl
405 ; FAST-NEXT: movl %eax, (%rcx)
406 ; FAST-NEXT: andb $1, %dl
407 ; FAST-NEXT: movzbl %dl, %eax
410 ; WIN64-LABEL: umuloi32:
412 ; WIN64-NEXT: movl %ecx, %eax
413 ; WIN64-NEXT: mull %edx
414 ; WIN64-NEXT: seto %cl
415 ; WIN64-NEXT: movl %eax, (%r8)
416 ; WIN64-NEXT: movl %ecx, %eax
419 ; WIN32-LABEL: umuloi32:
421 ; WIN32-NEXT: pushl %esi
422 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
423 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
424 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
425 ; WIN32-NEXT: seto %cl
426 ; WIN32-NEXT: movl %eax, (%esi)
427 ; WIN32-NEXT: movl %ecx, %eax
428 ; WIN32-NEXT: popl %esi
430 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
431 %val = extractvalue {i32, i1} %t, 0
432 %obit = extractvalue {i32, i1} %t, 1
433 store i32 %val, ptr %res
437 define zeroext i1 @umuloi64(i64 %v1, i64 %v2, ptr %res) {
438 ; SDAG-LABEL: umuloi64:
440 ; SDAG-NEXT: movq %rdx, %rcx
441 ; SDAG-NEXT: movq %rdi, %rax
442 ; SDAG-NEXT: mulq %rsi
443 ; SDAG-NEXT: seto %dl
444 ; SDAG-NEXT: movq %rax, (%rcx)
445 ; SDAG-NEXT: movl %edx, %eax
448 ; FAST-LABEL: umuloi64:
450 ; FAST-NEXT: movq %rdx, %rcx
451 ; FAST-NEXT: movq %rdi, %rax
452 ; FAST-NEXT: mulq %rsi
453 ; FAST-NEXT: seto %dl
454 ; FAST-NEXT: movq %rax, (%rcx)
455 ; FAST-NEXT: andb $1, %dl
456 ; FAST-NEXT: movzbl %dl, %eax
459 ; WIN64-LABEL: umuloi64:
461 ; WIN64-NEXT: movq %rcx, %rax
462 ; WIN64-NEXT: mulq %rdx
463 ; WIN64-NEXT: seto %cl
464 ; WIN64-NEXT: movq %rax, (%r8)
465 ; WIN64-NEXT: movl %ecx, %eax
468 ; WIN32-LABEL: umuloi64:
470 ; WIN32-NEXT: pushl %ebp
471 ; WIN32-NEXT: pushl %ebx
472 ; WIN32-NEXT: pushl %edi
473 ; WIN32-NEXT: pushl %esi
474 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebp
475 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
476 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
477 ; WIN32-NEXT: testl %esi, %esi
478 ; WIN32-NEXT: setne %dl
479 ; WIN32-NEXT: testl %eax, %eax
480 ; WIN32-NEXT: setne %cl
481 ; WIN32-NEXT: andb %dl, %cl
482 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
483 ; WIN32-NEXT: movl %eax, %edi
484 ; WIN32-NEXT: seto %bl
485 ; WIN32-NEXT: movl %esi, %eax
486 ; WIN32-NEXT: mull %ebp
487 ; WIN32-NEXT: seto %ch
488 ; WIN32-NEXT: orb %bl, %ch
489 ; WIN32-NEXT: orb %cl, %ch
490 ; WIN32-NEXT: leal (%edi,%eax), %esi
491 ; WIN32-NEXT: movl %ebp, %eax
492 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
493 ; WIN32-NEXT: addl %esi, %edx
494 ; WIN32-NEXT: setb %cl
495 ; WIN32-NEXT: orb %ch, %cl
496 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
497 ; WIN32-NEXT: movl %eax, (%esi)
498 ; WIN32-NEXT: movl %edx, 4(%esi)
499 ; WIN32-NEXT: movl %ecx, %eax
500 ; WIN32-NEXT: popl %esi
501 ; WIN32-NEXT: popl %edi
502 ; WIN32-NEXT: popl %ebx
503 ; WIN32-NEXT: popl %ebp
505 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
506 %val = extractvalue {i64, i1} %t, 0
507 %obit = extractvalue {i64, i1} %t, 1
508 store i64 %val, ptr %res
513 ; Check the use of the overflow bit in combination with a select instruction.
515 define i32 @smuloselecti32(i32 %v1, i32 %v2) {
516 ; LINUX-LABEL: smuloselecti32:
518 ; LINUX-NEXT: movl %esi, %eax
519 ; LINUX-NEXT: movl %edi, %ecx
520 ; LINUX-NEXT: imull %esi, %ecx
521 ; LINUX-NEXT: cmovol %edi, %eax
524 ; WIN64-LABEL: smuloselecti32:
526 ; WIN64-NEXT: movl %edx, %eax
527 ; WIN64-NEXT: movl %ecx, %edx
528 ; WIN64-NEXT: imull %eax, %edx
529 ; WIN64-NEXT: cmovol %ecx, %eax
532 ; WIN32-LABEL: smuloselecti32:
534 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
535 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
536 ; WIN32-NEXT: movl %eax, %edx
537 ; WIN32-NEXT: imull %ecx, %edx
538 ; WIN32-NEXT: jo LBB11_2
539 ; WIN32-NEXT: # %bb.1:
540 ; WIN32-NEXT: movl %ecx, %eax
541 ; WIN32-NEXT: LBB11_2:
543 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
544 %obit = extractvalue {i32, i1} %t, 1
545 %ret = select i1 %obit, i32 %v1, i32 %v2
549 define i64 @smuloselecti64(i64 %v1, i64 %v2) {
550 ; LINUX-LABEL: smuloselecti64:
552 ; LINUX-NEXT: movq %rsi, %rax
553 ; LINUX-NEXT: movq %rdi, %rcx
554 ; LINUX-NEXT: imulq %rsi, %rcx
555 ; LINUX-NEXT: cmovoq %rdi, %rax
558 ; WIN64-LABEL: smuloselecti64:
560 ; WIN64-NEXT: movq %rdx, %rax
561 ; WIN64-NEXT: movq %rcx, %rdx
562 ; WIN64-NEXT: imulq %rax, %rdx
563 ; WIN64-NEXT: cmovoq %rcx, %rax
566 ; WIN32-LABEL: smuloselecti64:
568 ; WIN32-NEXT: pushl %ebp
569 ; WIN32-NEXT: pushl %ebx
570 ; WIN32-NEXT: pushl %edi
571 ; WIN32-NEXT: pushl %esi
572 ; WIN32-NEXT: pushl %eax
573 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebp
574 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
575 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
576 ; WIN32-NEXT: sarl $31, %ecx
577 ; WIN32-NEXT: movl %eax, %edi
578 ; WIN32-NEXT: movl %eax, %ebx
579 ; WIN32-NEXT: imull %ecx, %edi
580 ; WIN32-NEXT: movl %ebp, %eax
581 ; WIN32-NEXT: mull %ecx
582 ; WIN32-NEXT: movl %edx, %esi
583 ; WIN32-NEXT: movl %eax, %ecx
584 ; WIN32-NEXT: addl %eax, %esi
585 ; WIN32-NEXT: addl %edi, %esi
586 ; WIN32-NEXT: movl %ebx, %eax
587 ; WIN32-NEXT: sarl $31, %eax
588 ; WIN32-NEXT: movl %eax, %edi
589 ; WIN32-NEXT: imull {{[0-9]+}}(%esp), %edi
590 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
591 ; WIN32-NEXT: movl %edx, %ebx
592 ; WIN32-NEXT: addl %edi, %ebx
593 ; WIN32-NEXT: addl %eax, %ebx
594 ; WIN32-NEXT: addl %ecx, %eax
595 ; WIN32-NEXT: movl %eax, (%esp) # 4-byte Spill
596 ; WIN32-NEXT: adcl %esi, %ebx
597 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edi
598 ; WIN32-NEXT: movl %edi, %eax
599 ; WIN32-NEXT: mull %ebp
600 ; WIN32-NEXT: movl %edx, %esi
601 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
602 ; WIN32-NEXT: mull %ebp
603 ; WIN32-NEXT: movl %edx, %ebp
604 ; WIN32-NEXT: movl %eax, %ecx
605 ; WIN32-NEXT: addl %esi, %ecx
606 ; WIN32-NEXT: adcl $0, %ebp
607 ; WIN32-NEXT: movl %edi, %eax
608 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
609 ; WIN32-NEXT: movl %edx, %edi
610 ; WIN32-NEXT: movl %eax, %esi
611 ; WIN32-NEXT: addl %ecx, %esi
612 ; WIN32-NEXT: adcl %ebp, %edi
613 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebp
614 ; WIN32-NEXT: setb %cl
615 ; WIN32-NEXT: movl %ebp, %eax
616 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
617 ; WIN32-NEXT: addl %edi, %eax
618 ; WIN32-NEXT: movzbl %cl, %ecx
619 ; WIN32-NEXT: adcl %ecx, %edx
620 ; WIN32-NEXT: addl (%esp), %eax # 4-byte Folded Reload
621 ; WIN32-NEXT: adcl %ebx, %edx
622 ; WIN32-NEXT: sarl $31, %esi
623 ; WIN32-NEXT: xorl %esi, %edx
624 ; WIN32-NEXT: xorl %eax, %esi
625 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
626 ; WIN32-NEXT: orl %edx, %esi
627 ; WIN32-NEXT: jne LBB12_2
628 ; WIN32-NEXT: # %bb.1:
629 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
630 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebp
631 ; WIN32-NEXT: LBB12_2:
632 ; WIN32-NEXT: movl %ebp, %edx
633 ; WIN32-NEXT: addl $4, %esp
634 ; WIN32-NEXT: popl %esi
635 ; WIN32-NEXT: popl %edi
636 ; WIN32-NEXT: popl %ebx
637 ; WIN32-NEXT: popl %ebp
639 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
640 %obit = extractvalue {i64, i1} %t, 1
641 %ret = select i1 %obit, i64 %v1, i64 %v2
645 define i32 @umuloselecti32(i32 %v1, i32 %v2) {
646 ; LINUX-LABEL: umuloselecti32:
648 ; LINUX-NEXT: movl %edi, %eax
649 ; LINUX-NEXT: mull %esi
650 ; LINUX-NEXT: cmovol %edi, %esi
651 ; LINUX-NEXT: movl %esi, %eax
654 ; WIN64-LABEL: umuloselecti32:
656 ; WIN64-NEXT: movl %edx, %r8d
657 ; WIN64-NEXT: movl %ecx, %eax
658 ; WIN64-NEXT: mull %edx
659 ; WIN64-NEXT: cmovol %ecx, %r8d
660 ; WIN64-NEXT: movl %r8d, %eax
663 ; WIN32-LABEL: umuloselecti32:
665 ; WIN32-NEXT: pushl %esi
666 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
667 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
668 ; WIN32-NEXT: movl %ecx, %eax
669 ; WIN32-NEXT: mull %esi
670 ; WIN32-NEXT: jo LBB13_2
671 ; WIN32-NEXT: # %bb.1:
672 ; WIN32-NEXT: movl %esi, %ecx
673 ; WIN32-NEXT: LBB13_2:
674 ; WIN32-NEXT: movl %ecx, %eax
675 ; WIN32-NEXT: popl %esi
677 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
678 %obit = extractvalue {i32, i1} %t, 1
679 %ret = select i1 %obit, i32 %v1, i32 %v2
683 define i64 @umuloselecti64(i64 %v1, i64 %v2) {
684 ; LINUX-LABEL: umuloselecti64:
686 ; LINUX-NEXT: movq %rdi, %rax
687 ; LINUX-NEXT: mulq %rsi
688 ; LINUX-NEXT: cmovoq %rdi, %rsi
689 ; LINUX-NEXT: movq %rsi, %rax
692 ; WIN64-LABEL: umuloselecti64:
694 ; WIN64-NEXT: movq %rdx, %r8
695 ; WIN64-NEXT: movq %rcx, %rax
696 ; WIN64-NEXT: mulq %rdx
697 ; WIN64-NEXT: cmovoq %rcx, %r8
698 ; WIN64-NEXT: movq %r8, %rax
701 ; WIN32-LABEL: umuloselecti64:
703 ; WIN32-NEXT: pushl %ebp
704 ; WIN32-NEXT: pushl %ebx
705 ; WIN32-NEXT: pushl %edi
706 ; WIN32-NEXT: pushl %esi
707 ; WIN32-NEXT: pushl %eax
708 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
709 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
710 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edi
711 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebp
712 ; WIN32-NEXT: testl %ebp, %ebp
713 ; WIN32-NEXT: setne %al
714 ; WIN32-NEXT: testl %esi, %esi
715 ; WIN32-NEXT: setne %bl
716 ; WIN32-NEXT: andb %al, %bl
717 ; WIN32-NEXT: movl %esi, %eax
718 ; WIN32-NEXT: mull %edi
719 ; WIN32-NEXT: movl %edi, %edx
720 ; WIN32-NEXT: movl %eax, %edi
721 ; WIN32-NEXT: seto {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Folded Spill
722 ; WIN32-NEXT: movl %ebp, %eax
723 ; WIN32-NEXT: movl %edx, %ebp
724 ; WIN32-NEXT: mull %ecx
725 ; WIN32-NEXT: seto %bh
726 ; WIN32-NEXT: orb {{[-0-9]+}}(%e{{[sb]}}p), %bh # 1-byte Folded Reload
727 ; WIN32-NEXT: orb %bl, %bh
728 ; WIN32-NEXT: addl %eax, %edi
729 ; WIN32-NEXT: movl %ecx, %eax
730 ; WIN32-NEXT: mull %ebp
731 ; WIN32-NEXT: addl %edi, %edx
732 ; WIN32-NEXT: setb %al
733 ; WIN32-NEXT: orb %bh, %al
734 ; WIN32-NEXT: testb %al, %al
735 ; WIN32-NEXT: jne LBB14_2
736 ; WIN32-NEXT: # %bb.1:
737 ; WIN32-NEXT: movl %ebp, %ecx
738 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
739 ; WIN32-NEXT: LBB14_2:
740 ; WIN32-NEXT: movl %ecx, %eax
741 ; WIN32-NEXT: movl %esi, %edx
742 ; WIN32-NEXT: addl $4, %esp
743 ; WIN32-NEXT: popl %esi
744 ; WIN32-NEXT: popl %edi
745 ; WIN32-NEXT: popl %ebx
746 ; WIN32-NEXT: popl %ebp
748 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
749 %obit = extractvalue {i64, i1} %t, 1
750 %ret = select i1 %obit, i64 %v1, i64 %v2
755 ; Check the use of the overflow bit in combination with a branch instruction.
757 define zeroext i1 @smulobri8(i8 %v1, i8 %v2) {
758 ; SDAG-LABEL: smulobri8:
760 ; SDAG-NEXT: movl %edi, %eax
761 ; SDAG-NEXT: # kill: def $al killed $al killed $eax
762 ; SDAG-NEXT: imulb %sil
763 ; SDAG-NEXT: jo .LBB15_1
764 ; SDAG-NEXT: # %bb.2: # %continue
765 ; SDAG-NEXT: movb $1, %al
767 ; SDAG-NEXT: .LBB15_1: # %overflow
768 ; SDAG-NEXT: xorl %eax, %eax
771 ; FAST-LABEL: smulobri8:
773 ; FAST-NEXT: movl %edi, %eax
774 ; FAST-NEXT: # kill: def $al killed $al killed $eax
775 ; FAST-NEXT: imulb %sil
776 ; FAST-NEXT: seto %al
777 ; FAST-NEXT: testb $1, %al
778 ; FAST-NEXT: jne .LBB15_1
779 ; FAST-NEXT: # %bb.2: # %continue
780 ; FAST-NEXT: movb $1, %al
781 ; FAST-NEXT: andb $1, %al
782 ; FAST-NEXT: movzbl %al, %eax
784 ; FAST-NEXT: .LBB15_1: # %overflow
785 ; FAST-NEXT: xorl %eax, %eax
786 ; FAST-NEXT: andb $1, %al
787 ; FAST-NEXT: movzbl %al, %eax
790 ; WIN64-LABEL: smulobri8:
792 ; WIN64-NEXT: movl %ecx, %eax
793 ; WIN64-NEXT: imulb %dl
794 ; WIN64-NEXT: jo .LBB15_1
795 ; WIN64-NEXT: # %bb.2: # %continue
796 ; WIN64-NEXT: movb $1, %al
798 ; WIN64-NEXT: .LBB15_1: # %overflow
799 ; WIN64-NEXT: xorl %eax, %eax
802 ; WIN32-LABEL: smulobri8:
804 ; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax
805 ; WIN32-NEXT: imulb {{[0-9]+}}(%esp)
806 ; WIN32-NEXT: jo LBB15_1
807 ; WIN32-NEXT: # %bb.2: # %continue
808 ; WIN32-NEXT: movb $1, %al
810 ; WIN32-NEXT: LBB15_1: # %overflow
811 ; WIN32-NEXT: xorl %eax, %eax
813 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
814 %val = extractvalue {i8, i1} %t, 0
815 %obit = extractvalue {i8, i1} %t, 1
816 br i1 %obit, label %overflow, label %continue, !prof !0
825 define zeroext i1 @smulobri16(i16 %v1, i16 %v2) {
826 ; SDAG-LABEL: smulobri16:
828 ; SDAG-NEXT: imulw %si, %di
829 ; SDAG-NEXT: jo .LBB16_1
830 ; SDAG-NEXT: # %bb.2: # %continue
831 ; SDAG-NEXT: movb $1, %al
833 ; SDAG-NEXT: .LBB16_1: # %overflow
834 ; SDAG-NEXT: xorl %eax, %eax
837 ; FAST-LABEL: smulobri16:
839 ; FAST-NEXT: imulw %si, %di
840 ; FAST-NEXT: seto %al
841 ; FAST-NEXT: testb $1, %al
842 ; FAST-NEXT: jne .LBB16_1
843 ; FAST-NEXT: # %bb.2: # %continue
844 ; FAST-NEXT: movb $1, %al
845 ; FAST-NEXT: andb $1, %al
846 ; FAST-NEXT: movzbl %al, %eax
848 ; FAST-NEXT: .LBB16_1: # %overflow
849 ; FAST-NEXT: xorl %eax, %eax
850 ; FAST-NEXT: andb $1, %al
851 ; FAST-NEXT: movzbl %al, %eax
854 ; WIN64-LABEL: smulobri16:
856 ; WIN64-NEXT: imulw %dx, %cx
857 ; WIN64-NEXT: jo .LBB16_1
858 ; WIN64-NEXT: # %bb.2: # %continue
859 ; WIN64-NEXT: movb $1, %al
861 ; WIN64-NEXT: .LBB16_1: # %overflow
862 ; WIN64-NEXT: xorl %eax, %eax
865 ; WIN32-LABEL: smulobri16:
867 ; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax
868 ; WIN32-NEXT: imulw {{[0-9]+}}(%esp), %ax
869 ; WIN32-NEXT: jo LBB16_1
870 ; WIN32-NEXT: # %bb.2: # %continue
871 ; WIN32-NEXT: movb $1, %al
873 ; WIN32-NEXT: LBB16_1: # %overflow
874 ; WIN32-NEXT: xorl %eax, %eax
876 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
877 %val = extractvalue {i16, i1} %t, 0
878 %obit = extractvalue {i16, i1} %t, 1
879 br i1 %obit, label %overflow, label %continue, !prof !0
888 define zeroext i1 @smulobri32(i32 %v1, i32 %v2) {
889 ; SDAG-LABEL: smulobri32:
891 ; SDAG-NEXT: imull %esi, %edi
892 ; SDAG-NEXT: jo .LBB17_1
893 ; SDAG-NEXT: # %bb.2: # %continue
894 ; SDAG-NEXT: movb $1, %al
896 ; SDAG-NEXT: .LBB17_1: # %overflow
897 ; SDAG-NEXT: xorl %eax, %eax
900 ; FAST-LABEL: smulobri32:
902 ; FAST-NEXT: imull %esi, %edi
903 ; FAST-NEXT: jo .LBB17_1
904 ; FAST-NEXT: # %bb.2: # %continue
905 ; FAST-NEXT: movb $1, %al
906 ; FAST-NEXT: andb $1, %al
907 ; FAST-NEXT: movzbl %al, %eax
909 ; FAST-NEXT: .LBB17_1: # %overflow
910 ; FAST-NEXT: xorl %eax, %eax
911 ; FAST-NEXT: andb $1, %al
912 ; FAST-NEXT: movzbl %al, %eax
915 ; WIN64-LABEL: smulobri32:
917 ; WIN64-NEXT: imull %edx, %ecx
918 ; WIN64-NEXT: jo .LBB17_1
919 ; WIN64-NEXT: # %bb.2: # %continue
920 ; WIN64-NEXT: movb $1, %al
922 ; WIN64-NEXT: .LBB17_1: # %overflow
923 ; WIN64-NEXT: xorl %eax, %eax
926 ; WIN32-LABEL: smulobri32:
928 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
929 ; WIN32-NEXT: imull {{[0-9]+}}(%esp), %eax
930 ; WIN32-NEXT: jo LBB17_1
931 ; WIN32-NEXT: # %bb.2: # %continue
932 ; WIN32-NEXT: movb $1, %al
934 ; WIN32-NEXT: LBB17_1: # %overflow
935 ; WIN32-NEXT: xorl %eax, %eax
937 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
938 %val = extractvalue {i32, i1} %t, 0
939 %obit = extractvalue {i32, i1} %t, 1
940 br i1 %obit, label %overflow, label %continue, !prof !0
949 define zeroext i1 @smulobri64(i64 %v1, i64 %v2) {
950 ; SDAG-LABEL: smulobri64:
952 ; SDAG-NEXT: imulq %rsi, %rdi
953 ; SDAG-NEXT: jo .LBB18_1
954 ; SDAG-NEXT: # %bb.2: # %continue
955 ; SDAG-NEXT: movb $1, %al
957 ; SDAG-NEXT: .LBB18_1: # %overflow
958 ; SDAG-NEXT: xorl %eax, %eax
961 ; FAST-LABEL: smulobri64:
963 ; FAST-NEXT: imulq %rsi, %rdi
964 ; FAST-NEXT: jo .LBB18_1
965 ; FAST-NEXT: # %bb.2: # %continue
966 ; FAST-NEXT: movb $1, %al
967 ; FAST-NEXT: andb $1, %al
968 ; FAST-NEXT: movzbl %al, %eax
970 ; FAST-NEXT: .LBB18_1: # %overflow
971 ; FAST-NEXT: xorl %eax, %eax
972 ; FAST-NEXT: andb $1, %al
973 ; FAST-NEXT: movzbl %al, %eax
976 ; WIN64-LABEL: smulobri64:
978 ; WIN64-NEXT: imulq %rdx, %rcx
979 ; WIN64-NEXT: jo .LBB18_1
980 ; WIN64-NEXT: # %bb.2: # %continue
981 ; WIN64-NEXT: movb $1, %al
983 ; WIN64-NEXT: .LBB18_1: # %overflow
984 ; WIN64-NEXT: xorl %eax, %eax
987 ; WIN32-LABEL: smulobri64:
989 ; WIN32-NEXT: pushl %ebp
990 ; WIN32-NEXT: pushl %ebx
991 ; WIN32-NEXT: pushl %edi
992 ; WIN32-NEXT: pushl %esi
993 ; WIN32-NEXT: pushl %eax
994 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
995 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edi
996 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
997 ; WIN32-NEXT: movl %edx, %ecx
998 ; WIN32-NEXT: movl %edx, %ebp
999 ; WIN32-NEXT: sarl $31, %ecx
1000 ; WIN32-NEXT: movl %edi, %esi
1001 ; WIN32-NEXT: imull %ecx, %esi
1002 ; WIN32-NEXT: mull %ecx
1003 ; WIN32-NEXT: movl %edx, %ecx
1004 ; WIN32-NEXT: movl %eax, %ebx
1005 ; WIN32-NEXT: addl %eax, %ecx
1006 ; WIN32-NEXT: addl %esi, %ecx
1007 ; WIN32-NEXT: movl %edi, %eax
1008 ; WIN32-NEXT: sarl $31, %eax
1009 ; WIN32-NEXT: movl %eax, %edi
1010 ; WIN32-NEXT: imull %ebp, %edi
1011 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebp
1012 ; WIN32-NEXT: mull %ebp
1013 ; WIN32-NEXT: movl %edx, %esi
1014 ; WIN32-NEXT: addl %edi, %esi
1015 ; WIN32-NEXT: addl %eax, %esi
1016 ; WIN32-NEXT: addl %ebx, %eax
1017 ; WIN32-NEXT: movl %eax, (%esp) # 4-byte Spill
1018 ; WIN32-NEXT: adcl %ecx, %esi
1019 ; WIN32-NEXT: movl %ebp, %eax
1020 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
1021 ; WIN32-NEXT: mull %ecx
1022 ; WIN32-NEXT: movl %edx, %ebx
1023 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1024 ; WIN32-NEXT: mull %ecx
1025 ; WIN32-NEXT: movl %edx, %edi
1026 ; WIN32-NEXT: movl %eax, %ecx
1027 ; WIN32-NEXT: addl %ebx, %ecx
1028 ; WIN32-NEXT: adcl $0, %edi
1029 ; WIN32-NEXT: movl %ebp, %eax
1030 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
1031 ; WIN32-NEXT: movl %edx, %ebp
1032 ; WIN32-NEXT: movl %eax, %ebx
1033 ; WIN32-NEXT: addl %ecx, %ebx
1034 ; WIN32-NEXT: adcl %edi, %ebp
1035 ; WIN32-NEXT: setb %cl
1036 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1037 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
1038 ; WIN32-NEXT: addl %ebp, %eax
1039 ; WIN32-NEXT: movzbl %cl, %ecx
1040 ; WIN32-NEXT: adcl %ecx, %edx
1041 ; WIN32-NEXT: addl (%esp), %eax # 4-byte Folded Reload
1042 ; WIN32-NEXT: adcl %esi, %edx
1043 ; WIN32-NEXT: sarl $31, %ebx
1044 ; WIN32-NEXT: xorl %ebx, %edx
1045 ; WIN32-NEXT: xorl %eax, %ebx
1046 ; WIN32-NEXT: orl %edx, %ebx
1047 ; WIN32-NEXT: jne LBB18_1
1048 ; WIN32-NEXT: # %bb.3: # %continue
1049 ; WIN32-NEXT: movb $1, %al
1050 ; WIN32-NEXT: LBB18_2: # %overflow
1051 ; WIN32-NEXT: addl $4, %esp
1052 ; WIN32-NEXT: popl %esi
1053 ; WIN32-NEXT: popl %edi
1054 ; WIN32-NEXT: popl %ebx
1055 ; WIN32-NEXT: popl %ebp
1057 ; WIN32-NEXT: LBB18_1: # %overflow
1058 ; WIN32-NEXT: xorl %eax, %eax
1059 ; WIN32-NEXT: jmp LBB18_2
1060 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
1061 %val = extractvalue {i64, i1} %t, 0
1062 %obit = extractvalue {i64, i1} %t, 1
1063 br i1 %obit, label %overflow, label %continue, !prof !0
1072 define zeroext i1 @umulobri8(i8 %v1, i8 %v2) {
1073 ; SDAG-LABEL: umulobri8:
1075 ; SDAG-NEXT: movl %edi, %eax
1076 ; SDAG-NEXT: # kill: def $al killed $al killed $eax
1077 ; SDAG-NEXT: mulb %sil
1078 ; SDAG-NEXT: jo .LBB19_1
1079 ; SDAG-NEXT: # %bb.2: # %continue
1080 ; SDAG-NEXT: movb $1, %al
1082 ; SDAG-NEXT: .LBB19_1: # %overflow
1083 ; SDAG-NEXT: xorl %eax, %eax
1086 ; FAST-LABEL: umulobri8:
1088 ; FAST-NEXT: movl %edi, %eax
1089 ; FAST-NEXT: # kill: def $al killed $al killed $eax
1090 ; FAST-NEXT: mulb %sil
1091 ; FAST-NEXT: seto %al
1092 ; FAST-NEXT: testb $1, %al
1093 ; FAST-NEXT: jne .LBB19_1
1094 ; FAST-NEXT: # %bb.2: # %continue
1095 ; FAST-NEXT: movb $1, %al
1096 ; FAST-NEXT: andb $1, %al
1097 ; FAST-NEXT: movzbl %al, %eax
1099 ; FAST-NEXT: .LBB19_1: # %overflow
1100 ; FAST-NEXT: xorl %eax, %eax
1101 ; FAST-NEXT: andb $1, %al
1102 ; FAST-NEXT: movzbl %al, %eax
1105 ; WIN64-LABEL: umulobri8:
1107 ; WIN64-NEXT: movl %ecx, %eax
1108 ; WIN64-NEXT: mulb %dl
1109 ; WIN64-NEXT: jo .LBB19_1
1110 ; WIN64-NEXT: # %bb.2: # %continue
1111 ; WIN64-NEXT: movb $1, %al
1113 ; WIN64-NEXT: .LBB19_1: # %overflow
1114 ; WIN64-NEXT: xorl %eax, %eax
1117 ; WIN32-LABEL: umulobri8:
1119 ; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax
1120 ; WIN32-NEXT: mulb {{[0-9]+}}(%esp)
1121 ; WIN32-NEXT: jo LBB19_1
1122 ; WIN32-NEXT: # %bb.2: # %continue
1123 ; WIN32-NEXT: movb $1, %al
1125 ; WIN32-NEXT: LBB19_1: # %overflow
1126 ; WIN32-NEXT: xorl %eax, %eax
1128 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
1129 %val = extractvalue {i8, i1} %t, 0
1130 %obit = extractvalue {i8, i1} %t, 1
1131 br i1 %obit, label %overflow, label %continue, !prof !0
1140 define zeroext i1 @umulobri16(i16 %v1, i16 %v2) {
1141 ; SDAG-LABEL: umulobri16:
1143 ; SDAG-NEXT: movl %edi, %eax
1144 ; SDAG-NEXT: # kill: def $ax killed $ax killed $eax
1145 ; SDAG-NEXT: mulw %si
1146 ; SDAG-NEXT: jo .LBB20_1
1147 ; SDAG-NEXT: # %bb.2: # %continue
1148 ; SDAG-NEXT: movb $1, %al
1150 ; SDAG-NEXT: .LBB20_1: # %overflow
1151 ; SDAG-NEXT: xorl %eax, %eax
1154 ; FAST-LABEL: umulobri16:
1156 ; FAST-NEXT: movl %edi, %eax
1157 ; FAST-NEXT: # kill: def $ax killed $ax killed $eax
1158 ; FAST-NEXT: mulw %si
1159 ; FAST-NEXT: seto %al
1160 ; FAST-NEXT: testb $1, %al
1161 ; FAST-NEXT: jne .LBB20_1
1162 ; FAST-NEXT: # %bb.2: # %continue
1163 ; FAST-NEXT: movb $1, %al
1164 ; FAST-NEXT: andb $1, %al
1165 ; FAST-NEXT: movzbl %al, %eax
1167 ; FAST-NEXT: .LBB20_1: # %overflow
1168 ; FAST-NEXT: xorl %eax, %eax
1169 ; FAST-NEXT: andb $1, %al
1170 ; FAST-NEXT: movzbl %al, %eax
1173 ; WIN64-LABEL: umulobri16:
1175 ; WIN64-NEXT: movl %ecx, %eax
1176 ; WIN64-NEXT: mulw %dx
1177 ; WIN64-NEXT: jo .LBB20_1
1178 ; WIN64-NEXT: # %bb.2: # %continue
1179 ; WIN64-NEXT: movb $1, %al
1181 ; WIN64-NEXT: .LBB20_1: # %overflow
1182 ; WIN64-NEXT: xorl %eax, %eax
1185 ; WIN32-LABEL: umulobri16:
1187 ; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax
1188 ; WIN32-NEXT: mulw {{[0-9]+}}(%esp)
1189 ; WIN32-NEXT: jo LBB20_1
1190 ; WIN32-NEXT: # %bb.2: # %continue
1191 ; WIN32-NEXT: movb $1, %al
1193 ; WIN32-NEXT: LBB20_1: # %overflow
1194 ; WIN32-NEXT: xorl %eax, %eax
1196 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
1197 %val = extractvalue {i16, i1} %t, 0
1198 %obit = extractvalue {i16, i1} %t, 1
1199 br i1 %obit, label %overflow, label %continue, !prof !0
1208 define zeroext i1 @umulobri32(i32 %v1, i32 %v2) {
1209 ; SDAG-LABEL: umulobri32:
1211 ; SDAG-NEXT: movl %edi, %eax
1212 ; SDAG-NEXT: mull %esi
1213 ; SDAG-NEXT: jo .LBB21_1
1214 ; SDAG-NEXT: # %bb.2: # %continue
1215 ; SDAG-NEXT: movb $1, %al
1217 ; SDAG-NEXT: .LBB21_1: # %overflow
1218 ; SDAG-NEXT: xorl %eax, %eax
1221 ; FAST-LABEL: umulobri32:
1223 ; FAST-NEXT: movl %edi, %eax
1224 ; FAST-NEXT: mull %esi
1225 ; FAST-NEXT: jo .LBB21_1
1226 ; FAST-NEXT: # %bb.2: # %continue
1227 ; FAST-NEXT: movb $1, %al
1228 ; FAST-NEXT: andb $1, %al
1229 ; FAST-NEXT: movzbl %al, %eax
1231 ; FAST-NEXT: .LBB21_1: # %overflow
1232 ; FAST-NEXT: xorl %eax, %eax
1233 ; FAST-NEXT: andb $1, %al
1234 ; FAST-NEXT: movzbl %al, %eax
1237 ; WIN64-LABEL: umulobri32:
1239 ; WIN64-NEXT: movl %ecx, %eax
1240 ; WIN64-NEXT: mull %edx
1241 ; WIN64-NEXT: jo .LBB21_1
1242 ; WIN64-NEXT: # %bb.2: # %continue
1243 ; WIN64-NEXT: movb $1, %al
1245 ; WIN64-NEXT: .LBB21_1: # %overflow
1246 ; WIN64-NEXT: xorl %eax, %eax
1249 ; WIN32-LABEL: umulobri32:
1251 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1252 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
1253 ; WIN32-NEXT: jo LBB21_1
1254 ; WIN32-NEXT: # %bb.2: # %continue
1255 ; WIN32-NEXT: movb $1, %al
1257 ; WIN32-NEXT: LBB21_1: # %overflow
1258 ; WIN32-NEXT: xorl %eax, %eax
1260 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
1261 %val = extractvalue {i32, i1} %t, 0
1262 %obit = extractvalue {i32, i1} %t, 1
1263 br i1 %obit, label %overflow, label %continue, !prof !0
1272 define zeroext i1 @umulobri64(i64 %v1, i64 %v2) {
1273 ; SDAG-LABEL: umulobri64:
1275 ; SDAG-NEXT: movq %rdi, %rax
1276 ; SDAG-NEXT: mulq %rsi
1277 ; SDAG-NEXT: jo .LBB22_1
1278 ; SDAG-NEXT: # %bb.2: # %continue
1279 ; SDAG-NEXT: movb $1, %al
1281 ; SDAG-NEXT: .LBB22_1: # %overflow
1282 ; SDAG-NEXT: xorl %eax, %eax
1285 ; FAST-LABEL: umulobri64:
1287 ; FAST-NEXT: movq %rdi, %rax
1288 ; FAST-NEXT: mulq %rsi
1289 ; FAST-NEXT: jo .LBB22_1
1290 ; FAST-NEXT: # %bb.2: # %continue
1291 ; FAST-NEXT: movb $1, %al
1292 ; FAST-NEXT: andb $1, %al
1293 ; FAST-NEXT: movzbl %al, %eax
1295 ; FAST-NEXT: .LBB22_1: # %overflow
1296 ; FAST-NEXT: xorl %eax, %eax
1297 ; FAST-NEXT: andb $1, %al
1298 ; FAST-NEXT: movzbl %al, %eax
1301 ; WIN64-LABEL: umulobri64:
1303 ; WIN64-NEXT: movq %rcx, %rax
1304 ; WIN64-NEXT: mulq %rdx
1305 ; WIN64-NEXT: jo .LBB22_1
1306 ; WIN64-NEXT: # %bb.2: # %continue
1307 ; WIN64-NEXT: movb $1, %al
1309 ; WIN64-NEXT: .LBB22_1: # %overflow
1310 ; WIN64-NEXT: xorl %eax, %eax
1313 ; WIN32-LABEL: umulobri64:
1315 ; WIN32-NEXT: pushl %ebp
1316 ; WIN32-NEXT: pushl %ebx
1317 ; WIN32-NEXT: pushl %edi
1318 ; WIN32-NEXT: pushl %esi
1319 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebp
1320 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1321 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
1322 ; WIN32-NEXT: testl %esi, %esi
1323 ; WIN32-NEXT: setne %dl
1324 ; WIN32-NEXT: testl %eax, %eax
1325 ; WIN32-NEXT: setne %cl
1326 ; WIN32-NEXT: andb %dl, %cl
1327 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
1328 ; WIN32-NEXT: movl %eax, %edi
1329 ; WIN32-NEXT: seto %bl
1330 ; WIN32-NEXT: movl %esi, %eax
1331 ; WIN32-NEXT: mull %ebp
1332 ; WIN32-NEXT: seto %ch
1333 ; WIN32-NEXT: orb %bl, %ch
1334 ; WIN32-NEXT: orb %cl, %ch
1335 ; WIN32-NEXT: leal (%edi,%eax), %esi
1336 ; WIN32-NEXT: movl %ebp, %eax
1337 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
1338 ; WIN32-NEXT: addl %esi, %edx
1339 ; WIN32-NEXT: setb %al
1340 ; WIN32-NEXT: orb %ch, %al
1341 ; WIN32-NEXT: subb $1, %al
1342 ; WIN32-NEXT: je LBB22_1
1343 ; WIN32-NEXT: # %bb.3: # %continue
1344 ; WIN32-NEXT: movb $1, %al
1345 ; WIN32-NEXT: LBB22_2: # %overflow
1346 ; WIN32-NEXT: popl %esi
1347 ; WIN32-NEXT: popl %edi
1348 ; WIN32-NEXT: popl %ebx
1349 ; WIN32-NEXT: popl %ebp
1351 ; WIN32-NEXT: LBB22_1: # %overflow
1352 ; WIN32-NEXT: xorl %eax, %eax
1353 ; WIN32-NEXT: jmp LBB22_2
1354 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
1355 %val = extractvalue {i64, i1} %t, 0
1356 %obit = extractvalue {i64, i1} %t, 1
1357 br i1 %obit, label %overflow, label %continue, !prof !0
1366 define i1 @bug27873(i64 %c1, i1 %c2) {
1367 ; LINUX-LABEL: bug27873:
1369 ; LINUX-NEXT: movq %rdi, %rax
1370 ; LINUX-NEXT: movl $160, %ecx
1371 ; LINUX-NEXT: mulq %rcx
1372 ; LINUX-NEXT: seto %al
1373 ; LINUX-NEXT: orb %sil, %al
1376 ; WIN64-LABEL: bug27873:
1378 ; WIN64-NEXT: movl %edx, %r8d
1379 ; WIN64-NEXT: movq %rcx, %rax
1380 ; WIN64-NEXT: movl $160, %ecx
1381 ; WIN64-NEXT: mulq %rcx
1382 ; WIN64-NEXT: seto %al
1383 ; WIN64-NEXT: orb %r8b, %al
1386 ; WIN32-LABEL: bug27873:
1388 ; WIN32-NEXT: pushl %ebx
1389 ; WIN32-NEXT: movl $160, %eax
1390 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
1391 ; WIN32-NEXT: movl %eax, %ecx
1392 ; WIN32-NEXT: seto %bl
1393 ; WIN32-NEXT: movl $160, %eax
1394 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
1395 ; WIN32-NEXT: addl %ecx, %edx
1396 ; WIN32-NEXT: setb %al
1397 ; WIN32-NEXT: orb %bl, %al
1398 ; WIN32-NEXT: orb {{[0-9]+}}(%esp), %al
1399 ; WIN32-NEXT: popl %ebx
1401 %mul = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %c1, i64 160)
1402 %mul.overflow = extractvalue { i64, i1 } %mul, 1
1403 %x1 = or i1 %c2, %mul.overflow
1407 define zeroext i1 @smuloi8_load(ptr %ptr1, i8 %v2, ptr %res) {
1408 ; SDAG-LABEL: smuloi8_load:
1410 ; SDAG-NEXT: movl %esi, %eax
1411 ; SDAG-NEXT: # kill: def $al killed $al killed $eax
1412 ; SDAG-NEXT: imulb (%rdi)
1413 ; SDAG-NEXT: seto %cl
1414 ; SDAG-NEXT: movb %al, (%rdx)
1415 ; SDAG-NEXT: movl %ecx, %eax
1418 ; FAST-LABEL: smuloi8_load:
1420 ; FAST-NEXT: movzbl (%rdi), %eax
1421 ; FAST-NEXT: imulb %sil
1422 ; FAST-NEXT: seto %cl
1423 ; FAST-NEXT: movb %al, (%rdx)
1424 ; FAST-NEXT: andb $1, %cl
1425 ; FAST-NEXT: movzbl %cl, %eax
1428 ; WIN64-LABEL: smuloi8_load:
1430 ; WIN64-NEXT: movl %edx, %eax
1431 ; WIN64-NEXT: imulb (%rcx)
1432 ; WIN64-NEXT: seto %cl
1433 ; WIN64-NEXT: movb %al, (%r8)
1434 ; WIN64-NEXT: movl %ecx, %eax
1437 ; WIN32-LABEL: smuloi8_load:
1439 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
1440 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1441 ; WIN32-NEXT: movzbl (%eax), %eax
1442 ; WIN32-NEXT: imulb {{[0-9]+}}(%esp)
1443 ; WIN32-NEXT: seto %cl
1444 ; WIN32-NEXT: movb %al, (%edx)
1445 ; WIN32-NEXT: movl %ecx, %eax
1447 %v1 = load i8, ptr %ptr1
1448 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
1449 %val = extractvalue {i8, i1} %t, 0
1450 %obit = extractvalue {i8, i1} %t, 1
1451 store i8 %val, ptr %res
1455 define zeroext i1 @smuloi8_load2(i8 %v1, ptr %ptr2, ptr %res) {
1456 ; SDAG-LABEL: smuloi8_load2:
1458 ; SDAG-NEXT: movl %edi, %eax
1459 ; SDAG-NEXT: # kill: def $al killed $al killed $eax
1460 ; SDAG-NEXT: imulb (%rsi)
1461 ; SDAG-NEXT: seto %cl
1462 ; SDAG-NEXT: movb %al, (%rdx)
1463 ; SDAG-NEXT: movl %ecx, %eax
1466 ; FAST-LABEL: smuloi8_load2:
1468 ; FAST-NEXT: movl %edi, %eax
1469 ; FAST-NEXT: # kill: def $al killed $al killed $eax
1470 ; FAST-NEXT: imulb (%rsi)
1471 ; FAST-NEXT: seto %cl
1472 ; FAST-NEXT: movb %al, (%rdx)
1473 ; FAST-NEXT: andb $1, %cl
1474 ; FAST-NEXT: movzbl %cl, %eax
1477 ; WIN64-LABEL: smuloi8_load2:
1479 ; WIN64-NEXT: movl %ecx, %eax
1480 ; WIN64-NEXT: imulb (%rdx)
1481 ; WIN64-NEXT: seto %cl
1482 ; WIN64-NEXT: movb %al, (%r8)
1483 ; WIN64-NEXT: movl %ecx, %eax
1486 ; WIN32-LABEL: smuloi8_load2:
1488 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
1489 ; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax
1490 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
1491 ; WIN32-NEXT: imulb (%ecx)
1492 ; WIN32-NEXT: seto %cl
1493 ; WIN32-NEXT: movb %al, (%edx)
1494 ; WIN32-NEXT: movl %ecx, %eax
1496 %v2 = load i8, ptr %ptr2
1497 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
1498 %val = extractvalue {i8, i1} %t, 0
1499 %obit = extractvalue {i8, i1} %t, 1
1500 store i8 %val, ptr %res
1504 define zeroext i1 @smuloi16_load(ptr %ptr1, i16 %v2, ptr %res) {
1505 ; SDAG-LABEL: smuloi16_load:
1507 ; SDAG-NEXT: imulw (%rdi), %si
1508 ; SDAG-NEXT: seto %al
1509 ; SDAG-NEXT: movw %si, (%rdx)
1512 ; FAST-LABEL: smuloi16_load:
1514 ; FAST-NEXT: imulw (%rdi), %si
1515 ; FAST-NEXT: seto %al
1516 ; FAST-NEXT: movw %si, (%rdx)
1517 ; FAST-NEXT: andb $1, %al
1518 ; FAST-NEXT: movzbl %al, %eax
1521 ; WIN64-LABEL: smuloi16_load:
1523 ; WIN64-NEXT: imulw (%rcx), %dx
1524 ; WIN64-NEXT: seto %al
1525 ; WIN64-NEXT: movw %dx, (%r8)
1528 ; WIN32-LABEL: smuloi16_load:
1530 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
1531 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1532 ; WIN32-NEXT: movzwl (%eax), %edx
1533 ; WIN32-NEXT: imulw {{[0-9]+}}(%esp), %dx
1534 ; WIN32-NEXT: seto %al
1535 ; WIN32-NEXT: movw %dx, (%ecx)
1537 %v1 = load i16, ptr %ptr1
1538 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
1539 %val = extractvalue {i16, i1} %t, 0
1540 %obit = extractvalue {i16, i1} %t, 1
1541 store i16 %val, ptr %res
1545 define zeroext i1 @smuloi16_load2(i16 %v1, ptr %ptr2, ptr %res) {
1546 ; SDAG-LABEL: smuloi16_load2:
1548 ; SDAG-NEXT: imulw (%rsi), %di
1549 ; SDAG-NEXT: seto %al
1550 ; SDAG-NEXT: movw %di, (%rdx)
1553 ; FAST-LABEL: smuloi16_load2:
1555 ; FAST-NEXT: imulw (%rsi), %di
1556 ; FAST-NEXT: seto %al
1557 ; FAST-NEXT: movw %di, (%rdx)
1558 ; FAST-NEXT: andb $1, %al
1559 ; FAST-NEXT: movzbl %al, %eax
1562 ; WIN64-LABEL: smuloi16_load2:
1564 ; WIN64-NEXT: imulw (%rdx), %cx
1565 ; WIN64-NEXT: seto %al
1566 ; WIN64-NEXT: movw %cx, (%r8)
1569 ; WIN32-LABEL: smuloi16_load2:
1571 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
1572 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1573 ; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %edx
1574 ; WIN32-NEXT: imulw (%eax), %dx
1575 ; WIN32-NEXT: seto %al
1576 ; WIN32-NEXT: movw %dx, (%ecx)
1578 %v2 = load i16, ptr %ptr2
1579 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
1580 %val = extractvalue {i16, i1} %t, 0
1581 %obit = extractvalue {i16, i1} %t, 1
1582 store i16 %val, ptr %res
1586 define zeroext i1 @smuloi32_load(ptr %ptr1, i32 %v2, ptr %res) {
1587 ; SDAG-LABEL: smuloi32_load:
1589 ; SDAG-NEXT: imull (%rdi), %esi
1590 ; SDAG-NEXT: seto %al
1591 ; SDAG-NEXT: movl %esi, (%rdx)
1594 ; FAST-LABEL: smuloi32_load:
1596 ; FAST-NEXT: imull (%rdi), %esi
1597 ; FAST-NEXT: seto %al
1598 ; FAST-NEXT: movl %esi, (%rdx)
1599 ; FAST-NEXT: andb $1, %al
1600 ; FAST-NEXT: movzbl %al, %eax
1603 ; WIN64-LABEL: smuloi32_load:
1605 ; WIN64-NEXT: imull (%rcx), %edx
1606 ; WIN64-NEXT: seto %al
1607 ; WIN64-NEXT: movl %edx, (%r8)
1610 ; WIN32-LABEL: smuloi32_load:
1612 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
1613 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1614 ; WIN32-NEXT: movl (%eax), %edx
1615 ; WIN32-NEXT: imull {{[0-9]+}}(%esp), %edx
1616 ; WIN32-NEXT: seto %al
1617 ; WIN32-NEXT: movl %edx, (%ecx)
1619 %v1 = load i32, ptr %ptr1
1620 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
1621 %val = extractvalue {i32, i1} %t, 0
1622 %obit = extractvalue {i32, i1} %t, 1
1623 store i32 %val, ptr %res
1627 define zeroext i1 @smuloi32_load2(i32 %v1, ptr %ptr2, ptr %res) {
1628 ; SDAG-LABEL: smuloi32_load2:
1630 ; SDAG-NEXT: imull (%rsi), %edi
1631 ; SDAG-NEXT: seto %al
1632 ; SDAG-NEXT: movl %edi, (%rdx)
1635 ; FAST-LABEL: smuloi32_load2:
1637 ; FAST-NEXT: imull (%rsi), %edi
1638 ; FAST-NEXT: seto %al
1639 ; FAST-NEXT: movl %edi, (%rdx)
1640 ; FAST-NEXT: andb $1, %al
1641 ; FAST-NEXT: movzbl %al, %eax
1644 ; WIN64-LABEL: smuloi32_load2:
1646 ; WIN64-NEXT: imull (%rdx), %ecx
1647 ; WIN64-NEXT: seto %al
1648 ; WIN64-NEXT: movl %ecx, (%r8)
1651 ; WIN32-LABEL: smuloi32_load2:
1653 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
1654 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1655 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
1656 ; WIN32-NEXT: imull (%eax), %edx
1657 ; WIN32-NEXT: seto %al
1658 ; WIN32-NEXT: movl %edx, (%ecx)
1660 %v2 = load i32, ptr %ptr2
1661 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
1662 %val = extractvalue {i32, i1} %t, 0
1663 %obit = extractvalue {i32, i1} %t, 1
1664 store i32 %val, ptr %res
1668 define zeroext i1 @smuloi64_load(ptr %ptr1, i64 %v2, ptr %res) {
1669 ; SDAG-LABEL: smuloi64_load:
1671 ; SDAG-NEXT: imulq (%rdi), %rsi
1672 ; SDAG-NEXT: seto %al
1673 ; SDAG-NEXT: movq %rsi, (%rdx)
1676 ; FAST-LABEL: smuloi64_load:
1678 ; FAST-NEXT: imulq (%rdi), %rsi
1679 ; FAST-NEXT: seto %al
1680 ; FAST-NEXT: movq %rsi, (%rdx)
1681 ; FAST-NEXT: andb $1, %al
1682 ; FAST-NEXT: movzbl %al, %eax
1685 ; WIN64-LABEL: smuloi64_load:
1687 ; WIN64-NEXT: imulq (%rcx), %rdx
1688 ; WIN64-NEXT: seto %al
1689 ; WIN64-NEXT: movq %rdx, (%r8)
1692 ; WIN32-LABEL: smuloi64_load:
1694 ; WIN32-NEXT: pushl %ebp
1695 ; WIN32-NEXT: pushl %ebx
1696 ; WIN32-NEXT: pushl %edi
1697 ; WIN32-NEXT: pushl %esi
1698 ; WIN32-NEXT: subl $20, %esp
1699 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
1700 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1701 ; WIN32-NEXT: movl (%eax), %ebx
1702 ; WIN32-NEXT: movl %ebx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
1703 ; WIN32-NEXT: movl 4(%eax), %ebp
1704 ; WIN32-NEXT: movl %ecx, %eax
1705 ; WIN32-NEXT: movl %ecx, %edi
1706 ; WIN32-NEXT: sarl $31, %eax
1707 ; WIN32-NEXT: movl %eax, %ecx
1708 ; WIN32-NEXT: imull %ebp, %ecx
1709 ; WIN32-NEXT: mull %ebx
1710 ; WIN32-NEXT: movl %eax, (%esp) # 4-byte Spill
1711 ; WIN32-NEXT: movl %edx, %ebx
1712 ; WIN32-NEXT: addl %ecx, %ebx
1713 ; WIN32-NEXT: movl %ebp, %ecx
1714 ; WIN32-NEXT: movl %ebp, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
1715 ; WIN32-NEXT: sarl $31, %ecx
1716 ; WIN32-NEXT: movl %edi, %esi
1717 ; WIN32-NEXT: imull %ecx, %esi
1718 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1719 ; WIN32-NEXT: mull %ecx
1720 ; WIN32-NEXT: movl %edx, %edi
1721 ; WIN32-NEXT: addl %eax, %edi
1722 ; WIN32-NEXT: addl %esi, %edi
1723 ; WIN32-NEXT: movl (%esp), %ecx # 4-byte Reload
1724 ; WIN32-NEXT: addl %ecx, %ebx
1725 ; WIN32-NEXT: addl %eax, %ecx
1726 ; WIN32-NEXT: movl %ecx, (%esp) # 4-byte Spill
1727 ; WIN32-NEXT: adcl %ebx, %edi
1728 ; WIN32-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
1729 ; WIN32-NEXT: movl %ecx, %eax
1730 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
1731 ; WIN32-NEXT: mull %esi
1732 ; WIN32-NEXT: movl %edx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
1733 ; WIN32-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
1734 ; WIN32-NEXT: movl %ebp, %eax
1735 ; WIN32-NEXT: mull %esi
1736 ; WIN32-NEXT: movl %edx, %ebx
1737 ; WIN32-NEXT: movl %eax, %esi
1738 ; WIN32-NEXT: addl {{[-0-9]+}}(%e{{[sb]}}p), %esi # 4-byte Folded Reload
1739 ; WIN32-NEXT: adcl $0, %ebx
1740 ; WIN32-NEXT: movl %ecx, %eax
1741 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
1742 ; WIN32-NEXT: movl %edx, %ecx
1743 ; WIN32-NEXT: movl %eax, %ebp
1744 ; WIN32-NEXT: addl %esi, %ebp
1745 ; WIN32-NEXT: adcl %ebx, %ecx
1746 ; WIN32-NEXT: setb %bl
1747 ; WIN32-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Reload
1748 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
1749 ; WIN32-NEXT: addl %ecx, %eax
1750 ; WIN32-NEXT: movzbl %bl, %ecx
1751 ; WIN32-NEXT: adcl %ecx, %edx
1752 ; WIN32-NEXT: addl (%esp), %eax # 4-byte Folded Reload
1753 ; WIN32-NEXT: adcl %edi, %edx
1754 ; WIN32-NEXT: movl %ebp, %ecx
1755 ; WIN32-NEXT: sarl $31, %ecx
1756 ; WIN32-NEXT: xorl %ecx, %edx
1757 ; WIN32-NEXT: xorl %eax, %ecx
1758 ; WIN32-NEXT: orl %edx, %ecx
1759 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1760 ; WIN32-NEXT: movl %ebp, 4(%eax)
1761 ; WIN32-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
1762 ; WIN32-NEXT: movl %ecx, (%eax)
1763 ; WIN32-NEXT: setne %al
1764 ; WIN32-NEXT: addl $20, %esp
1765 ; WIN32-NEXT: popl %esi
1766 ; WIN32-NEXT: popl %edi
1767 ; WIN32-NEXT: popl %ebx
1768 ; WIN32-NEXT: popl %ebp
1770 %v1 = load i64, ptr %ptr1
1771 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
1772 %val = extractvalue {i64, i1} %t, 0
1773 %obit = extractvalue {i64, i1} %t, 1
1774 store i64 %val, ptr %res
1778 define zeroext i1 @smuloi64_load2(i64 %v1, ptr %ptr2, ptr %res) {
1779 ; SDAG-LABEL: smuloi64_load2:
1781 ; SDAG-NEXT: imulq (%rsi), %rdi
1782 ; SDAG-NEXT: seto %al
1783 ; SDAG-NEXT: movq %rdi, (%rdx)
1786 ; FAST-LABEL: smuloi64_load2:
1788 ; FAST-NEXT: imulq (%rsi), %rdi
1789 ; FAST-NEXT: seto %al
1790 ; FAST-NEXT: movq %rdi, (%rdx)
1791 ; FAST-NEXT: andb $1, %al
1792 ; FAST-NEXT: movzbl %al, %eax
1795 ; WIN64-LABEL: smuloi64_load2:
1797 ; WIN64-NEXT: imulq (%rdx), %rcx
1798 ; WIN64-NEXT: seto %al
1799 ; WIN64-NEXT: movq %rcx, (%r8)
1802 ; WIN32-LABEL: smuloi64_load2:
1804 ; WIN32-NEXT: pushl %ebp
1805 ; WIN32-NEXT: pushl %ebx
1806 ; WIN32-NEXT: pushl %edi
1807 ; WIN32-NEXT: pushl %esi
1808 ; WIN32-NEXT: subl $12, %esp
1809 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
1810 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1811 ; WIN32-NEXT: movl (%eax), %ebp
1812 ; WIN32-NEXT: movl 4(%eax), %eax
1813 ; WIN32-NEXT: sarl $31, %ecx
1814 ; WIN32-NEXT: movl %eax, %esi
1815 ; WIN32-NEXT: movl %eax, %edi
1816 ; WIN32-NEXT: movl %eax, (%esp) # 4-byte Spill
1817 ; WIN32-NEXT: imull %ecx, %esi
1818 ; WIN32-NEXT: movl %ebp, %eax
1819 ; WIN32-NEXT: mull %ecx
1820 ; WIN32-NEXT: movl %edx, %ecx
1821 ; WIN32-NEXT: movl %eax, %ebx
1822 ; WIN32-NEXT: addl %eax, %ecx
1823 ; WIN32-NEXT: addl %esi, %ecx
1824 ; WIN32-NEXT: movl %edi, %eax
1825 ; WIN32-NEXT: sarl $31, %eax
1826 ; WIN32-NEXT: movl %eax, %edi
1827 ; WIN32-NEXT: imull {{[0-9]+}}(%esp), %edi
1828 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
1829 ; WIN32-NEXT: movl %edx, %esi
1830 ; WIN32-NEXT: addl %edi, %esi
1831 ; WIN32-NEXT: addl %eax, %esi
1832 ; WIN32-NEXT: addl %ebx, %eax
1833 ; WIN32-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
1834 ; WIN32-NEXT: adcl %ecx, %esi
1835 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1836 ; WIN32-NEXT: mull %ebp
1837 ; WIN32-NEXT: movl %edx, %ebx
1838 ; WIN32-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
1839 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1840 ; WIN32-NEXT: mull %ebp
1841 ; WIN32-NEXT: movl %edx, %edi
1842 ; WIN32-NEXT: movl %eax, %ecx
1843 ; WIN32-NEXT: addl %ebx, %ecx
1844 ; WIN32-NEXT: adcl $0, %edi
1845 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1846 ; WIN32-NEXT: mull (%esp) # 4-byte Folded Reload
1847 ; WIN32-NEXT: movl %edx, %ebx
1848 ; WIN32-NEXT: movl %eax, %ebp
1849 ; WIN32-NEXT: addl %ecx, %ebp
1850 ; WIN32-NEXT: adcl %edi, %ebx
1851 ; WIN32-NEXT: setb %cl
1852 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1853 ; WIN32-NEXT: mull (%esp) # 4-byte Folded Reload
1854 ; WIN32-NEXT: addl %ebx, %eax
1855 ; WIN32-NEXT: movzbl %cl, %ecx
1856 ; WIN32-NEXT: adcl %ecx, %edx
1857 ; WIN32-NEXT: addl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Folded Reload
1858 ; WIN32-NEXT: adcl %esi, %edx
1859 ; WIN32-NEXT: movl %ebp, %ecx
1860 ; WIN32-NEXT: sarl $31, %ecx
1861 ; WIN32-NEXT: xorl %ecx, %edx
1862 ; WIN32-NEXT: xorl %eax, %ecx
1863 ; WIN32-NEXT: orl %edx, %ecx
1864 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1865 ; WIN32-NEXT: movl %ebp, 4(%eax)
1866 ; WIN32-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
1867 ; WIN32-NEXT: movl %ecx, (%eax)
1868 ; WIN32-NEXT: setne %al
1869 ; WIN32-NEXT: addl $12, %esp
1870 ; WIN32-NEXT: popl %esi
1871 ; WIN32-NEXT: popl %edi
1872 ; WIN32-NEXT: popl %ebx
1873 ; WIN32-NEXT: popl %ebp
1875 %v2 = load i64, ptr %ptr2
1876 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
1877 %val = extractvalue {i64, i1} %t, 0
1878 %obit = extractvalue {i64, i1} %t, 1
1879 store i64 %val, ptr %res
1883 define zeroext i1 @umuloi8_load(ptr %ptr1, i8 %v2, ptr %res) {
1884 ; SDAG-LABEL: umuloi8_load:
1886 ; SDAG-NEXT: movl %esi, %eax
1887 ; SDAG-NEXT: # kill: def $al killed $al killed $eax
1888 ; SDAG-NEXT: mulb (%rdi)
1889 ; SDAG-NEXT: seto %cl
1890 ; SDAG-NEXT: movb %al, (%rdx)
1891 ; SDAG-NEXT: movl %ecx, %eax
1894 ; FAST-LABEL: umuloi8_load:
1896 ; FAST-NEXT: movzbl (%rdi), %eax
1897 ; FAST-NEXT: mulb %sil
1898 ; FAST-NEXT: seto %cl
1899 ; FAST-NEXT: movb %al, (%rdx)
1900 ; FAST-NEXT: andb $1, %cl
1901 ; FAST-NEXT: movzbl %cl, %eax
1904 ; WIN64-LABEL: umuloi8_load:
1906 ; WIN64-NEXT: movl %edx, %eax
1907 ; WIN64-NEXT: mulb (%rcx)
1908 ; WIN64-NEXT: seto %cl
1909 ; WIN64-NEXT: movb %al, (%r8)
1910 ; WIN64-NEXT: movl %ecx, %eax
1913 ; WIN32-LABEL: umuloi8_load:
1915 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
1916 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
1917 ; WIN32-NEXT: movzbl (%eax), %eax
1918 ; WIN32-NEXT: mulb {{[0-9]+}}(%esp)
1919 ; WIN32-NEXT: seto %cl
1920 ; WIN32-NEXT: movb %al, (%edx)
1921 ; WIN32-NEXT: movl %ecx, %eax
1923 %v1 = load i8, ptr %ptr1
1924 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
1925 %val = extractvalue {i8, i1} %t, 0
1926 %obit = extractvalue {i8, i1} %t, 1
1927 store i8 %val, ptr %res
1931 define zeroext i1 @umuloi8_load2(i8 %v1, ptr %ptr2, ptr %res) {
1932 ; SDAG-LABEL: umuloi8_load2:
1934 ; SDAG-NEXT: movl %edi, %eax
1935 ; SDAG-NEXT: # kill: def $al killed $al killed $eax
1936 ; SDAG-NEXT: mulb (%rsi)
1937 ; SDAG-NEXT: seto %cl
1938 ; SDAG-NEXT: movb %al, (%rdx)
1939 ; SDAG-NEXT: movl %ecx, %eax
1942 ; FAST-LABEL: umuloi8_load2:
1944 ; FAST-NEXT: movl %edi, %eax
1945 ; FAST-NEXT: # kill: def $al killed $al killed $eax
1946 ; FAST-NEXT: mulb (%rsi)
1947 ; FAST-NEXT: seto %cl
1948 ; FAST-NEXT: movb %al, (%rdx)
1949 ; FAST-NEXT: andb $1, %cl
1950 ; FAST-NEXT: movzbl %cl, %eax
1953 ; WIN64-LABEL: umuloi8_load2:
1955 ; WIN64-NEXT: movl %ecx, %eax
1956 ; WIN64-NEXT: mulb (%rdx)
1957 ; WIN64-NEXT: seto %cl
1958 ; WIN64-NEXT: movb %al, (%r8)
1959 ; WIN64-NEXT: movl %ecx, %eax
1962 ; WIN32-LABEL: umuloi8_load2:
1964 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
1965 ; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax
1966 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
1967 ; WIN32-NEXT: mulb (%ecx)
1968 ; WIN32-NEXT: seto %cl
1969 ; WIN32-NEXT: movb %al, (%edx)
1970 ; WIN32-NEXT: movl %ecx, %eax
1972 %v2 = load i8, ptr %ptr2
1973 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
1974 %val = extractvalue {i8, i1} %t, 0
1975 %obit = extractvalue {i8, i1} %t, 1
1976 store i8 %val, ptr %res
1980 define zeroext i1 @umuloi16_load(ptr %ptr1, i16 %v2, ptr %res) {
1981 ; SDAG-LABEL: umuloi16_load:
1983 ; SDAG-NEXT: movq %rdx, %rcx
1984 ; SDAG-NEXT: movl %esi, %eax
1985 ; SDAG-NEXT: # kill: def $ax killed $ax killed $eax
1986 ; SDAG-NEXT: mulw (%rdi)
1987 ; SDAG-NEXT: seto %dl
1988 ; SDAG-NEXT: movw %ax, (%rcx)
1989 ; SDAG-NEXT: movl %edx, %eax
1992 ; FAST-LABEL: umuloi16_load:
1994 ; FAST-NEXT: movq %rdx, %rcx
1995 ; FAST-NEXT: movzwl (%rdi), %eax
1996 ; FAST-NEXT: mulw %si
1997 ; FAST-NEXT: seto %dl
1998 ; FAST-NEXT: movw %ax, (%rcx)
1999 ; FAST-NEXT: andb $1, %dl
2000 ; FAST-NEXT: movzbl %dl, %eax
2003 ; WIN64-LABEL: umuloi16_load:
2005 ; WIN64-NEXT: movl %edx, %eax
2006 ; WIN64-NEXT: mulw (%rcx)
2007 ; WIN64-NEXT: seto %cl
2008 ; WIN64-NEXT: movw %ax, (%r8)
2009 ; WIN64-NEXT: movl %ecx, %eax
2012 ; WIN32-LABEL: umuloi16_load:
2014 ; WIN32-NEXT: pushl %esi
2015 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
2016 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
2017 ; WIN32-NEXT: movzwl (%eax), %eax
2018 ; WIN32-NEXT: mulw {{[0-9]+}}(%esp)
2019 ; WIN32-NEXT: seto %cl
2020 ; WIN32-NEXT: movw %ax, (%esi)
2021 ; WIN32-NEXT: movl %ecx, %eax
2022 ; WIN32-NEXT: popl %esi
2024 %v1 = load i16, ptr %ptr1
2025 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
2026 %val = extractvalue {i16, i1} %t, 0
2027 %obit = extractvalue {i16, i1} %t, 1
2028 store i16 %val, ptr %res
2032 define zeroext i1 @umuloi16_load2(i16 %v1, ptr %ptr2, ptr %res) {
2033 ; SDAG-LABEL: umuloi16_load2:
2035 ; SDAG-NEXT: movq %rdx, %rcx
2036 ; SDAG-NEXT: movl %edi, %eax
2037 ; SDAG-NEXT: # kill: def $ax killed $ax killed $eax
2038 ; SDAG-NEXT: mulw (%rsi)
2039 ; SDAG-NEXT: seto %dl
2040 ; SDAG-NEXT: movw %ax, (%rcx)
2041 ; SDAG-NEXT: movl %edx, %eax
2044 ; FAST-LABEL: umuloi16_load2:
2046 ; FAST-NEXT: movq %rdx, %rcx
2047 ; FAST-NEXT: movl %edi, %eax
2048 ; FAST-NEXT: # kill: def $ax killed $ax killed $eax
2049 ; FAST-NEXT: mulw (%rsi)
2050 ; FAST-NEXT: seto %dl
2051 ; FAST-NEXT: movw %ax, (%rcx)
2052 ; FAST-NEXT: andb $1, %dl
2053 ; FAST-NEXT: movzbl %dl, %eax
2056 ; WIN64-LABEL: umuloi16_load2:
2058 ; WIN64-NEXT: movl %ecx, %eax
2059 ; WIN64-NEXT: mulw (%rdx)
2060 ; WIN64-NEXT: seto %cl
2061 ; WIN64-NEXT: movw %ax, (%r8)
2062 ; WIN64-NEXT: movl %ecx, %eax
2065 ; WIN32-LABEL: umuloi16_load2:
2067 ; WIN32-NEXT: pushl %esi
2068 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
2069 ; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax
2070 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
2071 ; WIN32-NEXT: mulw (%ecx)
2072 ; WIN32-NEXT: seto %cl
2073 ; WIN32-NEXT: movw %ax, (%esi)
2074 ; WIN32-NEXT: movl %ecx, %eax
2075 ; WIN32-NEXT: popl %esi
2077 %v2 = load i16, ptr %ptr2
2078 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
2079 %val = extractvalue {i16, i1} %t, 0
2080 %obit = extractvalue {i16, i1} %t, 1
2081 store i16 %val, ptr %res
2085 define zeroext i1 @umuloi32_load(ptr %ptr1, i32 %v2, ptr %res) {
2086 ; SDAG-LABEL: umuloi32_load:
2088 ; SDAG-NEXT: movq %rdx, %rcx
2089 ; SDAG-NEXT: movl %esi, %eax
2090 ; SDAG-NEXT: mull (%rdi)
2091 ; SDAG-NEXT: seto %dl
2092 ; SDAG-NEXT: movl %eax, (%rcx)
2093 ; SDAG-NEXT: movl %edx, %eax
2096 ; FAST-LABEL: umuloi32_load:
2098 ; FAST-NEXT: movq %rdx, %rcx
2099 ; FAST-NEXT: movl (%rdi), %eax
2100 ; FAST-NEXT: mull %esi
2101 ; FAST-NEXT: seto %dl
2102 ; FAST-NEXT: movl %eax, (%rcx)
2103 ; FAST-NEXT: andb $1, %dl
2104 ; FAST-NEXT: movzbl %dl, %eax
2107 ; WIN64-LABEL: umuloi32_load:
2109 ; WIN64-NEXT: movl %edx, %eax
2110 ; WIN64-NEXT: mull (%rcx)
2111 ; WIN64-NEXT: seto %cl
2112 ; WIN64-NEXT: movl %eax, (%r8)
2113 ; WIN64-NEXT: movl %ecx, %eax
2116 ; WIN32-LABEL: umuloi32_load:
2118 ; WIN32-NEXT: pushl %esi
2119 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
2120 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
2121 ; WIN32-NEXT: movl (%eax), %eax
2122 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
2123 ; WIN32-NEXT: seto %cl
2124 ; WIN32-NEXT: movl %eax, (%esi)
2125 ; WIN32-NEXT: movl %ecx, %eax
2126 ; WIN32-NEXT: popl %esi
2128 %v1 = load i32, ptr %ptr1
2129 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
2130 %val = extractvalue {i32, i1} %t, 0
2131 %obit = extractvalue {i32, i1} %t, 1
2132 store i32 %val, ptr %res
2136 define zeroext i1 @umuloi32_load2(i32 %v1, ptr %ptr2, ptr %res) {
2137 ; SDAG-LABEL: umuloi32_load2:
2139 ; SDAG-NEXT: movq %rdx, %rcx
2140 ; SDAG-NEXT: movl %edi, %eax
2141 ; SDAG-NEXT: mull (%rsi)
2142 ; SDAG-NEXT: seto %dl
2143 ; SDAG-NEXT: movl %eax, (%rcx)
2144 ; SDAG-NEXT: movl %edx, %eax
2147 ; FAST-LABEL: umuloi32_load2:
2149 ; FAST-NEXT: movq %rdx, %rcx
2150 ; FAST-NEXT: movl %edi, %eax
2151 ; FAST-NEXT: mull (%rsi)
2152 ; FAST-NEXT: seto %dl
2153 ; FAST-NEXT: movl %eax, (%rcx)
2154 ; FAST-NEXT: andb $1, %dl
2155 ; FAST-NEXT: movzbl %dl, %eax
2158 ; WIN64-LABEL: umuloi32_load2:
2160 ; WIN64-NEXT: movl %ecx, %eax
2161 ; WIN64-NEXT: mull (%rdx)
2162 ; WIN64-NEXT: seto %cl
2163 ; WIN64-NEXT: movl %eax, (%r8)
2164 ; WIN64-NEXT: movl %ecx, %eax
2167 ; WIN32-LABEL: umuloi32_load2:
2169 ; WIN32-NEXT: pushl %esi
2170 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
2171 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
2172 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
2173 ; WIN32-NEXT: mull (%ecx)
2174 ; WIN32-NEXT: seto %cl
2175 ; WIN32-NEXT: movl %eax, (%esi)
2176 ; WIN32-NEXT: movl %ecx, %eax
2177 ; WIN32-NEXT: popl %esi
2179 %v2 = load i32, ptr %ptr2
2180 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
2181 %val = extractvalue {i32, i1} %t, 0
2182 %obit = extractvalue {i32, i1} %t, 1
2183 store i32 %val, ptr %res
2187 define zeroext i1 @umuloi64_load(ptr %ptr1, i64 %v2, ptr %res) {
2188 ; SDAG-LABEL: umuloi64_load:
2190 ; SDAG-NEXT: movq %rdx, %rcx
2191 ; SDAG-NEXT: movq %rsi, %rax
2192 ; SDAG-NEXT: mulq (%rdi)
2193 ; SDAG-NEXT: seto %dl
2194 ; SDAG-NEXT: movq %rax, (%rcx)
2195 ; SDAG-NEXT: movl %edx, %eax
2198 ; FAST-LABEL: umuloi64_load:
2200 ; FAST-NEXT: movq %rdx, %rcx
2201 ; FAST-NEXT: movq (%rdi), %rax
2202 ; FAST-NEXT: mulq %rsi
2203 ; FAST-NEXT: seto %dl
2204 ; FAST-NEXT: movq %rax, (%rcx)
2205 ; FAST-NEXT: andb $1, %dl
2206 ; FAST-NEXT: movzbl %dl, %eax
2209 ; WIN64-LABEL: umuloi64_load:
2211 ; WIN64-NEXT: movq %rdx, %rax
2212 ; WIN64-NEXT: mulq (%rcx)
2213 ; WIN64-NEXT: seto %cl
2214 ; WIN64-NEXT: movq %rax, (%r8)
2215 ; WIN64-NEXT: movl %ecx, %eax
2218 ; WIN32-LABEL: umuloi64_load:
2220 ; WIN32-NEXT: pushl %ebp
2221 ; WIN32-NEXT: pushl %ebx
2222 ; WIN32-NEXT: pushl %edi
2223 ; WIN32-NEXT: pushl %esi
2224 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
2225 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
2226 ; WIN32-NEXT: movl (%eax), %ebp
2227 ; WIN32-NEXT: movl 4(%eax), %eax
2228 ; WIN32-NEXT: testl %esi, %esi
2229 ; WIN32-NEXT: setne %dl
2230 ; WIN32-NEXT: testl %eax, %eax
2231 ; WIN32-NEXT: setne %cl
2232 ; WIN32-NEXT: andb %dl, %cl
2233 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
2234 ; WIN32-NEXT: movl %eax, %edi
2235 ; WIN32-NEXT: seto %bl
2236 ; WIN32-NEXT: movl %esi, %eax
2237 ; WIN32-NEXT: mull %ebp
2238 ; WIN32-NEXT: seto %ch
2239 ; WIN32-NEXT: orb %bl, %ch
2240 ; WIN32-NEXT: orb %cl, %ch
2241 ; WIN32-NEXT: leal (%edi,%eax), %esi
2242 ; WIN32-NEXT: movl %ebp, %eax
2243 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
2244 ; WIN32-NEXT: addl %esi, %edx
2245 ; WIN32-NEXT: setb %cl
2246 ; WIN32-NEXT: orb %ch, %cl
2247 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
2248 ; WIN32-NEXT: movl %eax, (%esi)
2249 ; WIN32-NEXT: movl %edx, 4(%esi)
2250 ; WIN32-NEXT: movl %ecx, %eax
2251 ; WIN32-NEXT: popl %esi
2252 ; WIN32-NEXT: popl %edi
2253 ; WIN32-NEXT: popl %ebx
2254 ; WIN32-NEXT: popl %ebp
2256 %v1 = load i64, ptr %ptr1
2257 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
2258 %val = extractvalue {i64, i1} %t, 0
2259 %obit = extractvalue {i64, i1} %t, 1
2260 store i64 %val, ptr %res
2264 define zeroext i1 @umuloi64_load2(i64 %v1, ptr %ptr2, ptr %res) {
2265 ; SDAG-LABEL: umuloi64_load2:
2267 ; SDAG-NEXT: movq %rdx, %rcx
2268 ; SDAG-NEXT: movq %rdi, %rax
2269 ; SDAG-NEXT: mulq (%rsi)
2270 ; SDAG-NEXT: seto %dl
2271 ; SDAG-NEXT: movq %rax, (%rcx)
2272 ; SDAG-NEXT: movl %edx, %eax
2275 ; FAST-LABEL: umuloi64_load2:
2277 ; FAST-NEXT: movq %rdx, %rcx
2278 ; FAST-NEXT: movq %rdi, %rax
2279 ; FAST-NEXT: mulq (%rsi)
2280 ; FAST-NEXT: seto %dl
2281 ; FAST-NEXT: movq %rax, (%rcx)
2282 ; FAST-NEXT: andb $1, %dl
2283 ; FAST-NEXT: movzbl %dl, %eax
2286 ; WIN64-LABEL: umuloi64_load2:
2288 ; WIN64-NEXT: movq %rcx, %rax
2289 ; WIN64-NEXT: mulq (%rdx)
2290 ; WIN64-NEXT: seto %cl
2291 ; WIN64-NEXT: movq %rax, (%r8)
2292 ; WIN64-NEXT: movl %ecx, %eax
2295 ; WIN32-LABEL: umuloi64_load2:
2297 ; WIN32-NEXT: pushl %ebp
2298 ; WIN32-NEXT: pushl %ebx
2299 ; WIN32-NEXT: pushl %edi
2300 ; WIN32-NEXT: pushl %esi
2301 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
2302 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
2303 ; WIN32-NEXT: movl (%ecx), %ebp
2304 ; WIN32-NEXT: movl 4(%ecx), %esi
2305 ; WIN32-NEXT: testl %eax, %eax
2306 ; WIN32-NEXT: setne %dl
2307 ; WIN32-NEXT: testl %esi, %esi
2308 ; WIN32-NEXT: setne %cl
2309 ; WIN32-NEXT: andb %dl, %cl
2310 ; WIN32-NEXT: mull %ebp
2311 ; WIN32-NEXT: movl %eax, %edi
2312 ; WIN32-NEXT: seto %bl
2313 ; WIN32-NEXT: movl %esi, %eax
2314 ; WIN32-NEXT: mull {{[0-9]+}}(%esp)
2315 ; WIN32-NEXT: seto %ch
2316 ; WIN32-NEXT: orb %bl, %ch
2317 ; WIN32-NEXT: orb %cl, %ch
2318 ; WIN32-NEXT: leal (%edi,%eax), %esi
2319 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
2320 ; WIN32-NEXT: mull %ebp
2321 ; WIN32-NEXT: addl %esi, %edx
2322 ; WIN32-NEXT: setb %cl
2323 ; WIN32-NEXT: orb %ch, %cl
2324 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
2325 ; WIN32-NEXT: movl %eax, (%esi)
2326 ; WIN32-NEXT: movl %edx, 4(%esi)
2327 ; WIN32-NEXT: movl %ecx, %eax
2328 ; WIN32-NEXT: popl %esi
2329 ; WIN32-NEXT: popl %edi
2330 ; WIN32-NEXT: popl %ebx
2331 ; WIN32-NEXT: popl %ebp
2333 %v2 = load i64, ptr %ptr2
2334 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
2335 %val = extractvalue {i64, i1} %t, 0
2336 %obit = extractvalue {i64, i1} %t, 1
2337 store i64 %val, ptr %res
2341 declare {i8, i1} @llvm.smul.with.overflow.i8 (i8, i8 ) nounwind readnone
2342 declare {i16, i1} @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone
2343 declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
2344 declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
2345 declare {i8, i1} @llvm.umul.with.overflow.i8 (i8, i8 ) nounwind readnone
2346 declare {i16, i1} @llvm.umul.with.overflow.i16(i16, i16) nounwind readnone
2347 declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
2348 declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone
2350 !0 = !{!"branch_weights", i32 0, i32 2147483647}