1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -disable-peephole -mtriple=x86_64-darwin-unknown < %s | FileCheck %s --check-prefix=SDAG
3 ; RUN: llc -disable-peephole -mtriple=x86_64-darwin-unknown -fast-isel -fast-isel-abort=1 < %s | FileCheck %s --check-prefix=FAST
4 ; RUN: llc -disable-peephole -mtriple=x86_64-darwin-unknown -mcpu=knl < %s | FileCheck %s --check-prefix=SDAG --check-prefix=KNL
6 define {i64, i1} @t1() nounwind {
9 ; SDAG-NEXT: movl $8, %ecx
10 ; SDAG-NEXT: movl $9, %eax
11 ; SDAG-NEXT: mulq %rcx
17 ; FAST-NEXT: movl $8, %ecx
18 ; FAST-NEXT: movl $9, %eax
19 ; FAST-NEXT: mulq %rcx
22 %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 8)
26 define {i64, i1} @t2() nounwind {
29 ; SDAG-NEXT: xorl %eax, %eax
30 ; SDAG-NEXT: xorl %edx, %edx
35 ; FAST-NEXT: xorl %eax, %eax
36 ; FAST-NEXT: xorl %edx, %edx
38 %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 0)
42 define {i64, i1} @t3() nounwind {
45 ; SDAG-NEXT: movq $-1, %rcx
46 ; SDAG-NEXT: movl $9, %eax
47 ; SDAG-NEXT: mulq %rcx
53 ; FAST-NEXT: movq $-1, %rcx
54 ; FAST-NEXT: movl $9, %eax
55 ; FAST-NEXT: mulq %rcx
58 %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 -1)
63 define zeroext i1 @smuloi8(i8 %v1, i8 %v2, i8* %res) {
64 ; SDAG-LABEL: smuloi8:
66 ; SDAG-NEXT: movl %edi, %eax
67 ; SDAG-NEXT: ## kill: def $al killed $al killed $eax
68 ; SDAG-NEXT: imulb %sil
70 ; SDAG-NEXT: movb %al, (%rdx)
71 ; SDAG-NEXT: movl %ecx, %eax
74 ; FAST-LABEL: smuloi8:
76 ; FAST-NEXT: movl %edi, %eax
77 ; FAST-NEXT: ## kill: def $al killed $al killed $eax
78 ; FAST-NEXT: imulb %sil
80 ; FAST-NEXT: movb %al, (%rdx)
81 ; FAST-NEXT: andb $1, %cl
82 ; FAST-NEXT: movzbl %cl, %eax
84 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
85 %val = extractvalue {i8, i1} %t, 0
86 %obit = extractvalue {i8, i1} %t, 1
87 store i8 %val, i8* %res
91 define zeroext i1 @smuloi16(i16 %v1, i16 %v2, i16* %res) {
92 ; SDAG-LABEL: smuloi16:
94 ; SDAG-NEXT: imulw %si, %di
96 ; SDAG-NEXT: movw %di, (%rdx)
99 ; FAST-LABEL: smuloi16:
101 ; FAST-NEXT: imulw %si, %di
102 ; FAST-NEXT: seto %al
103 ; FAST-NEXT: movw %di, (%rdx)
104 ; FAST-NEXT: andb $1, %al
105 ; FAST-NEXT: movzbl %al, %eax
107 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
108 %val = extractvalue {i16, i1} %t, 0
109 %obit = extractvalue {i16, i1} %t, 1
110 store i16 %val, i16* %res
114 define zeroext i1 @smuloi32(i32 %v1, i32 %v2, i32* %res) {
115 ; SDAG-LABEL: smuloi32:
117 ; SDAG-NEXT: imull %esi, %edi
118 ; SDAG-NEXT: seto %al
119 ; SDAG-NEXT: movl %edi, (%rdx)
122 ; FAST-LABEL: smuloi32:
124 ; FAST-NEXT: imull %esi, %edi
125 ; FAST-NEXT: seto %al
126 ; FAST-NEXT: movl %edi, (%rdx)
127 ; FAST-NEXT: andb $1, %al
128 ; FAST-NEXT: movzbl %al, %eax
130 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
131 %val = extractvalue {i32, i1} %t, 0
132 %obit = extractvalue {i32, i1} %t, 1
133 store i32 %val, i32* %res
137 define zeroext i1 @smuloi64(i64 %v1, i64 %v2, i64* %res) {
138 ; SDAG-LABEL: smuloi64:
140 ; SDAG-NEXT: imulq %rsi, %rdi
141 ; SDAG-NEXT: seto %al
142 ; SDAG-NEXT: movq %rdi, (%rdx)
145 ; FAST-LABEL: smuloi64:
147 ; FAST-NEXT: imulq %rsi, %rdi
148 ; FAST-NEXT: seto %al
149 ; FAST-NEXT: movq %rdi, (%rdx)
150 ; FAST-NEXT: andb $1, %al
151 ; FAST-NEXT: movzbl %al, %eax
153 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
154 %val = extractvalue {i64, i1} %t, 0
155 %obit = extractvalue {i64, i1} %t, 1
156 store i64 %val, i64* %res
161 define zeroext i1 @umuloi8(i8 %v1, i8 %v2, i8* %res) {
162 ; SDAG-LABEL: umuloi8:
164 ; SDAG-NEXT: movl %edi, %eax
165 ; SDAG-NEXT: ## kill: def $al killed $al killed $eax
166 ; SDAG-NEXT: mulb %sil
167 ; SDAG-NEXT: seto %cl
168 ; SDAG-NEXT: movb %al, (%rdx)
169 ; SDAG-NEXT: movl %ecx, %eax
172 ; FAST-LABEL: umuloi8:
174 ; FAST-NEXT: movl %edi, %eax
175 ; FAST-NEXT: ## kill: def $al killed $al killed $eax
176 ; FAST-NEXT: mulb %sil
177 ; FAST-NEXT: seto %cl
178 ; FAST-NEXT: movb %al, (%rdx)
179 ; FAST-NEXT: andb $1, %cl
180 ; FAST-NEXT: movzbl %cl, %eax
182 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
183 %val = extractvalue {i8, i1} %t, 0
184 %obit = extractvalue {i8, i1} %t, 1
185 store i8 %val, i8* %res
189 define zeroext i1 @umuloi16(i16 %v1, i16 %v2, i16* %res) {
190 ; SDAG-LABEL: umuloi16:
192 ; SDAG-NEXT: movq %rdx, %rcx
193 ; SDAG-NEXT: movl %edi, %eax
194 ; SDAG-NEXT: ## kill: def $ax killed $ax killed $eax
195 ; SDAG-NEXT: mulw %si
196 ; SDAG-NEXT: seto %dl
197 ; SDAG-NEXT: movw %ax, (%rcx)
198 ; SDAG-NEXT: movl %edx, %eax
201 ; FAST-LABEL: umuloi16:
203 ; FAST-NEXT: movq %rdx, %rcx
204 ; FAST-NEXT: movl %edi, %eax
205 ; FAST-NEXT: ## kill: def $ax killed $ax killed $eax
206 ; FAST-NEXT: mulw %si
207 ; FAST-NEXT: seto %dl
208 ; FAST-NEXT: movw %ax, (%rcx)
209 ; FAST-NEXT: andb $1, %dl
210 ; FAST-NEXT: movzbl %dl, %eax
212 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
213 %val = extractvalue {i16, i1} %t, 0
214 %obit = extractvalue {i16, i1} %t, 1
215 store i16 %val, i16* %res
219 define zeroext i1 @umuloi32(i32 %v1, i32 %v2, i32* %res) {
220 ; SDAG-LABEL: umuloi32:
222 ; SDAG-NEXT: movq %rdx, %rcx
223 ; SDAG-NEXT: movl %edi, %eax
224 ; SDAG-NEXT: mull %esi
225 ; SDAG-NEXT: seto %dl
226 ; SDAG-NEXT: movl %eax, (%rcx)
227 ; SDAG-NEXT: movl %edx, %eax
230 ; FAST-LABEL: umuloi32:
232 ; FAST-NEXT: movq %rdx, %rcx
233 ; FAST-NEXT: movl %edi, %eax
234 ; FAST-NEXT: mull %esi
235 ; FAST-NEXT: seto %dl
236 ; FAST-NEXT: movl %eax, (%rcx)
237 ; FAST-NEXT: andb $1, %dl
238 ; FAST-NEXT: movzbl %dl, %eax
240 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
241 %val = extractvalue {i32, i1} %t, 0
242 %obit = extractvalue {i32, i1} %t, 1
243 store i32 %val, i32* %res
247 define zeroext i1 @umuloi64(i64 %v1, i64 %v2, i64* %res) {
248 ; SDAG-LABEL: umuloi64:
250 ; SDAG-NEXT: movq %rdx, %rcx
251 ; SDAG-NEXT: movq %rdi, %rax
252 ; SDAG-NEXT: mulq %rsi
253 ; SDAG-NEXT: seto %dl
254 ; SDAG-NEXT: movq %rax, (%rcx)
255 ; SDAG-NEXT: movl %edx, %eax
258 ; FAST-LABEL: umuloi64:
260 ; FAST-NEXT: movq %rdx, %rcx
261 ; FAST-NEXT: movq %rdi, %rax
262 ; FAST-NEXT: mulq %rsi
263 ; FAST-NEXT: seto %dl
264 ; FAST-NEXT: movq %rax, (%rcx)
265 ; FAST-NEXT: andb $1, %dl
266 ; FAST-NEXT: movzbl %dl, %eax
268 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
269 %val = extractvalue {i64, i1} %t, 0
270 %obit = extractvalue {i64, i1} %t, 1
271 store i64 %val, i64* %res
276 ; Check the use of the overflow bit in combination with a select instruction.
278 define i32 @smuloselecti32(i32 %v1, i32 %v2) {
279 ; SDAG-LABEL: smuloselecti32:
281 ; SDAG-NEXT: movl %esi, %eax
282 ; SDAG-NEXT: movl %edi, %ecx
283 ; SDAG-NEXT: imull %esi, %ecx
284 ; SDAG-NEXT: cmovol %edi, %eax
287 ; FAST-LABEL: smuloselecti32:
289 ; FAST-NEXT: movl %esi, %eax
290 ; FAST-NEXT: movl %edi, %ecx
291 ; FAST-NEXT: imull %esi, %ecx
292 ; FAST-NEXT: cmovol %edi, %eax
294 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
295 %obit = extractvalue {i32, i1} %t, 1
296 %ret = select i1 %obit, i32 %v1, i32 %v2
300 define i64 @smuloselecti64(i64 %v1, i64 %v2) {
301 ; SDAG-LABEL: smuloselecti64:
303 ; SDAG-NEXT: movq %rsi, %rax
304 ; SDAG-NEXT: movq %rdi, %rcx
305 ; SDAG-NEXT: imulq %rsi, %rcx
306 ; SDAG-NEXT: cmovoq %rdi, %rax
309 ; FAST-LABEL: smuloselecti64:
311 ; FAST-NEXT: movq %rsi, %rax
312 ; FAST-NEXT: movq %rdi, %rcx
313 ; FAST-NEXT: imulq %rsi, %rcx
314 ; FAST-NEXT: cmovoq %rdi, %rax
316 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
317 %obit = extractvalue {i64, i1} %t, 1
318 %ret = select i1 %obit, i64 %v1, i64 %v2
322 define i32 @umuloselecti32(i32 %v1, i32 %v2) {
323 ; SDAG-LABEL: umuloselecti32:
325 ; SDAG-NEXT: movl %edi, %eax
326 ; SDAG-NEXT: mull %esi
327 ; SDAG-NEXT: cmovol %edi, %esi
328 ; SDAG-NEXT: movl %esi, %eax
331 ; FAST-LABEL: umuloselecti32:
333 ; FAST-NEXT: movl %edi, %eax
334 ; FAST-NEXT: mull %esi
335 ; FAST-NEXT: cmovol %edi, %esi
336 ; FAST-NEXT: movl %esi, %eax
338 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
339 %obit = extractvalue {i32, i1} %t, 1
340 %ret = select i1 %obit, i32 %v1, i32 %v2
344 define i64 @umuloselecti64(i64 %v1, i64 %v2) {
345 ; SDAG-LABEL: umuloselecti64:
347 ; SDAG-NEXT: movq %rdi, %rax
348 ; SDAG-NEXT: mulq %rsi
349 ; SDAG-NEXT: cmovoq %rdi, %rsi
350 ; SDAG-NEXT: movq %rsi, %rax
353 ; FAST-LABEL: umuloselecti64:
355 ; FAST-NEXT: movq %rdi, %rax
356 ; FAST-NEXT: mulq %rsi
357 ; FAST-NEXT: cmovoq %rdi, %rsi
358 ; FAST-NEXT: movq %rsi, %rax
360 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
361 %obit = extractvalue {i64, i1} %t, 1
362 %ret = select i1 %obit, i64 %v1, i64 %v2
367 ; Check the use of the overflow bit in combination with a branch instruction.
369 define zeroext i1 @smulobri8(i8 %v1, i8 %v2) {
370 ; SDAG-LABEL: smulobri8:
372 ; SDAG-NEXT: movl %edi, %eax
373 ; SDAG-NEXT: ## kill: def $al killed $al killed $eax
374 ; SDAG-NEXT: imulb %sil
375 ; SDAG-NEXT: jo LBB15_1
376 ; SDAG-NEXT: ## %bb.2: ## %continue
377 ; SDAG-NEXT: movb $1, %al
379 ; SDAG-NEXT: LBB15_1: ## %overflow
380 ; SDAG-NEXT: xorl %eax, %eax
383 ; FAST-LABEL: smulobri8:
385 ; FAST-NEXT: movl %edi, %eax
386 ; FAST-NEXT: ## kill: def $al killed $al killed $eax
387 ; FAST-NEXT: imulb %sil
388 ; FAST-NEXT: seto %al
389 ; FAST-NEXT: testb $1, %al
390 ; FAST-NEXT: jne LBB15_1
391 ; FAST-NEXT: ## %bb.2: ## %continue
392 ; FAST-NEXT: movb $1, %al
393 ; FAST-NEXT: andb $1, %al
394 ; FAST-NEXT: movzbl %al, %eax
396 ; FAST-NEXT: LBB15_1: ## %overflow
397 ; FAST-NEXT: xorl %eax, %eax
398 ; FAST-NEXT: andb $1, %al
399 ; FAST-NEXT: movzbl %al, %eax
401 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
402 %val = extractvalue {i8, i1} %t, 0
403 %obit = extractvalue {i8, i1} %t, 1
404 br i1 %obit, label %overflow, label %continue, !prof !0
413 define zeroext i1 @smulobri16(i16 %v1, i16 %v2) {
414 ; SDAG-LABEL: smulobri16:
416 ; SDAG-NEXT: imulw %si, %di
417 ; SDAG-NEXT: jo LBB16_1
418 ; SDAG-NEXT: ## %bb.2: ## %continue
419 ; SDAG-NEXT: movb $1, %al
421 ; SDAG-NEXT: LBB16_1: ## %overflow
422 ; SDAG-NEXT: xorl %eax, %eax
425 ; FAST-LABEL: smulobri16:
427 ; FAST-NEXT: imulw %si, %di
428 ; FAST-NEXT: seto %al
429 ; FAST-NEXT: testb $1, %al
430 ; FAST-NEXT: jne LBB16_1
431 ; FAST-NEXT: ## %bb.2: ## %continue
432 ; FAST-NEXT: movb $1, %al
433 ; FAST-NEXT: andb $1, %al
434 ; FAST-NEXT: movzbl %al, %eax
436 ; FAST-NEXT: LBB16_1: ## %overflow
437 ; FAST-NEXT: xorl %eax, %eax
438 ; FAST-NEXT: andb $1, %al
439 ; FAST-NEXT: movzbl %al, %eax
441 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
442 %val = extractvalue {i16, i1} %t, 0
443 %obit = extractvalue {i16, i1} %t, 1
444 br i1 %obit, label %overflow, label %continue, !prof !0
453 define zeroext i1 @smulobri32(i32 %v1, i32 %v2) {
454 ; SDAG-LABEL: smulobri32:
456 ; SDAG-NEXT: imull %esi, %edi
457 ; SDAG-NEXT: jo LBB17_1
458 ; SDAG-NEXT: ## %bb.2: ## %continue
459 ; SDAG-NEXT: movb $1, %al
461 ; SDAG-NEXT: LBB17_1: ## %overflow
462 ; SDAG-NEXT: xorl %eax, %eax
465 ; FAST-LABEL: smulobri32:
467 ; FAST-NEXT: imull %esi, %edi
468 ; FAST-NEXT: jo LBB17_1
469 ; FAST-NEXT: ## %bb.2: ## %continue
470 ; FAST-NEXT: movb $1, %al
471 ; FAST-NEXT: andb $1, %al
472 ; FAST-NEXT: movzbl %al, %eax
474 ; FAST-NEXT: LBB17_1: ## %overflow
475 ; FAST-NEXT: xorl %eax, %eax
476 ; FAST-NEXT: andb $1, %al
477 ; FAST-NEXT: movzbl %al, %eax
479 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
480 %val = extractvalue {i32, i1} %t, 0
481 %obit = extractvalue {i32, i1} %t, 1
482 br i1 %obit, label %overflow, label %continue, !prof !0
491 define zeroext i1 @smulobri64(i64 %v1, i64 %v2) {
492 ; SDAG-LABEL: smulobri64:
494 ; SDAG-NEXT: imulq %rsi, %rdi
495 ; SDAG-NEXT: jo LBB18_1
496 ; SDAG-NEXT: ## %bb.2: ## %continue
497 ; SDAG-NEXT: movb $1, %al
499 ; SDAG-NEXT: LBB18_1: ## %overflow
500 ; SDAG-NEXT: xorl %eax, %eax
503 ; FAST-LABEL: smulobri64:
505 ; FAST-NEXT: imulq %rsi, %rdi
506 ; FAST-NEXT: jo LBB18_1
507 ; FAST-NEXT: ## %bb.2: ## %continue
508 ; FAST-NEXT: movb $1, %al
509 ; FAST-NEXT: andb $1, %al
510 ; FAST-NEXT: movzbl %al, %eax
512 ; FAST-NEXT: LBB18_1: ## %overflow
513 ; FAST-NEXT: xorl %eax, %eax
514 ; FAST-NEXT: andb $1, %al
515 ; FAST-NEXT: movzbl %al, %eax
517 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
518 %val = extractvalue {i64, i1} %t, 0
519 %obit = extractvalue {i64, i1} %t, 1
520 br i1 %obit, label %overflow, label %continue, !prof !0
529 define zeroext i1 @umulobri8(i8 %v1, i8 %v2) {
530 ; SDAG-LABEL: umulobri8:
532 ; SDAG-NEXT: movl %edi, %eax
533 ; SDAG-NEXT: ## kill: def $al killed $al killed $eax
534 ; SDAG-NEXT: mulb %sil
535 ; SDAG-NEXT: jo LBB19_1
536 ; SDAG-NEXT: ## %bb.2: ## %continue
537 ; SDAG-NEXT: movb $1, %al
539 ; SDAG-NEXT: LBB19_1: ## %overflow
540 ; SDAG-NEXT: xorl %eax, %eax
543 ; FAST-LABEL: umulobri8:
545 ; FAST-NEXT: movl %edi, %eax
546 ; FAST-NEXT: ## kill: def $al killed $al killed $eax
547 ; FAST-NEXT: mulb %sil
548 ; FAST-NEXT: seto %al
549 ; FAST-NEXT: testb $1, %al
550 ; FAST-NEXT: jne LBB19_1
551 ; FAST-NEXT: ## %bb.2: ## %continue
552 ; FAST-NEXT: movb $1, %al
553 ; FAST-NEXT: andb $1, %al
554 ; FAST-NEXT: movzbl %al, %eax
556 ; FAST-NEXT: LBB19_1: ## %overflow
557 ; FAST-NEXT: xorl %eax, %eax
558 ; FAST-NEXT: andb $1, %al
559 ; FAST-NEXT: movzbl %al, %eax
561 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
562 %val = extractvalue {i8, i1} %t, 0
563 %obit = extractvalue {i8, i1} %t, 1
564 br i1 %obit, label %overflow, label %continue, !prof !0
573 define zeroext i1 @umulobri16(i16 %v1, i16 %v2) {
574 ; SDAG-LABEL: umulobri16:
576 ; SDAG-NEXT: movl %edi, %eax
577 ; SDAG-NEXT: ## kill: def $ax killed $ax killed $eax
578 ; SDAG-NEXT: mulw %si
579 ; SDAG-NEXT: jo LBB20_1
580 ; SDAG-NEXT: ## %bb.2: ## %continue
581 ; SDAG-NEXT: movb $1, %al
583 ; SDAG-NEXT: LBB20_1: ## %overflow
584 ; SDAG-NEXT: xorl %eax, %eax
587 ; FAST-LABEL: umulobri16:
589 ; FAST-NEXT: movl %edi, %eax
590 ; FAST-NEXT: ## kill: def $ax killed $ax killed $eax
591 ; FAST-NEXT: mulw %si
592 ; FAST-NEXT: seto %al
593 ; FAST-NEXT: testb $1, %al
594 ; FAST-NEXT: jne LBB20_1
595 ; FAST-NEXT: ## %bb.2: ## %continue
596 ; FAST-NEXT: movb $1, %al
597 ; FAST-NEXT: andb $1, %al
598 ; FAST-NEXT: movzbl %al, %eax
600 ; FAST-NEXT: LBB20_1: ## %overflow
601 ; FAST-NEXT: xorl %eax, %eax
602 ; FAST-NEXT: andb $1, %al
603 ; FAST-NEXT: movzbl %al, %eax
605 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
606 %val = extractvalue {i16, i1} %t, 0
607 %obit = extractvalue {i16, i1} %t, 1
608 br i1 %obit, label %overflow, label %continue, !prof !0
617 define zeroext i1 @umulobri32(i32 %v1, i32 %v2) {
618 ; SDAG-LABEL: umulobri32:
620 ; SDAG-NEXT: movl %edi, %eax
621 ; SDAG-NEXT: mull %esi
622 ; SDAG-NEXT: jo LBB21_1
623 ; SDAG-NEXT: ## %bb.2: ## %continue
624 ; SDAG-NEXT: movb $1, %al
626 ; SDAG-NEXT: LBB21_1: ## %overflow
627 ; SDAG-NEXT: xorl %eax, %eax
630 ; FAST-LABEL: umulobri32:
632 ; FAST-NEXT: movl %edi, %eax
633 ; FAST-NEXT: mull %esi
634 ; FAST-NEXT: jo LBB21_1
635 ; FAST-NEXT: ## %bb.2: ## %continue
636 ; FAST-NEXT: movb $1, %al
637 ; FAST-NEXT: andb $1, %al
638 ; FAST-NEXT: movzbl %al, %eax
640 ; FAST-NEXT: LBB21_1: ## %overflow
641 ; FAST-NEXT: xorl %eax, %eax
642 ; FAST-NEXT: andb $1, %al
643 ; FAST-NEXT: movzbl %al, %eax
645 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
646 %val = extractvalue {i32, i1} %t, 0
647 %obit = extractvalue {i32, i1} %t, 1
648 br i1 %obit, label %overflow, label %continue, !prof !0
657 define zeroext i1 @umulobri64(i64 %v1, i64 %v2) {
658 ; SDAG-LABEL: umulobri64:
660 ; SDAG-NEXT: movq %rdi, %rax
661 ; SDAG-NEXT: mulq %rsi
662 ; SDAG-NEXT: jo LBB22_1
663 ; SDAG-NEXT: ## %bb.2: ## %continue
664 ; SDAG-NEXT: movb $1, %al
666 ; SDAG-NEXT: LBB22_1: ## %overflow
667 ; SDAG-NEXT: xorl %eax, %eax
670 ; FAST-LABEL: umulobri64:
672 ; FAST-NEXT: movq %rdi, %rax
673 ; FAST-NEXT: mulq %rsi
674 ; FAST-NEXT: jo LBB22_1
675 ; FAST-NEXT: ## %bb.2: ## %continue
676 ; FAST-NEXT: movb $1, %al
677 ; FAST-NEXT: andb $1, %al
678 ; FAST-NEXT: movzbl %al, %eax
680 ; FAST-NEXT: LBB22_1: ## %overflow
681 ; FAST-NEXT: xorl %eax, %eax
682 ; FAST-NEXT: andb $1, %al
683 ; FAST-NEXT: movzbl %al, %eax
685 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
686 %val = extractvalue {i64, i1} %t, 0
687 %obit = extractvalue {i64, i1} %t, 1
688 br i1 %obit, label %overflow, label %continue, !prof !0
697 define i1 @bug27873(i64 %c1, i1 %c2) {
698 ; SDAG-LABEL: bug27873:
700 ; SDAG-NEXT: movq %rdi, %rax
701 ; SDAG-NEXT: movl $160, %ecx
702 ; SDAG-NEXT: mulq %rcx
703 ; SDAG-NEXT: seto %al
704 ; SDAG-NEXT: orb %sil, %al
707 ; FAST-LABEL: bug27873:
709 ; FAST-NEXT: movq %rdi, %rax
710 ; FAST-NEXT: movl $160, %ecx
711 ; FAST-NEXT: mulq %rcx
712 ; FAST-NEXT: seto %al
713 ; FAST-NEXT: orb %sil, %al
715 %mul = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %c1, i64 160)
716 %mul.overflow = extractvalue { i64, i1 } %mul, 1
717 %x1 = or i1 %c2, %mul.overflow
721 define zeroext i1 @smuloi8_load(i8* %ptr1, i8 %v2, i8* %res) {
722 ; SDAG-LABEL: smuloi8_load:
724 ; SDAG-NEXT: movl %esi, %eax
725 ; SDAG-NEXT: ## kill: def $al killed $al killed $eax
726 ; SDAG-NEXT: imulb (%rdi)
727 ; SDAG-NEXT: seto %cl
728 ; SDAG-NEXT: movb %al, (%rdx)
729 ; SDAG-NEXT: movl %ecx, %eax
732 ; FAST-LABEL: smuloi8_load:
734 ; FAST-NEXT: movb (%rdi), %al
735 ; FAST-NEXT: imulb %sil
736 ; FAST-NEXT: seto %cl
737 ; FAST-NEXT: movb %al, (%rdx)
738 ; FAST-NEXT: andb $1, %cl
739 ; FAST-NEXT: movzbl %cl, %eax
741 %v1 = load i8, i8* %ptr1
742 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
743 %val = extractvalue {i8, i1} %t, 0
744 %obit = extractvalue {i8, i1} %t, 1
745 store i8 %val, i8* %res
749 define zeroext i1 @smuloi8_load2(i8 %v1, i8* %ptr2, i8* %res) {
750 ; SDAG-LABEL: smuloi8_load2:
752 ; SDAG-NEXT: movl %edi, %eax
753 ; SDAG-NEXT: ## kill: def $al killed $al killed $eax
754 ; SDAG-NEXT: imulb (%rsi)
755 ; SDAG-NEXT: seto %cl
756 ; SDAG-NEXT: movb %al, (%rdx)
757 ; SDAG-NEXT: movl %ecx, %eax
760 ; FAST-LABEL: smuloi8_load2:
762 ; FAST-NEXT: movl %edi, %eax
763 ; FAST-NEXT: ## kill: def $al killed $al killed $eax
764 ; FAST-NEXT: imulb (%rsi)
765 ; FAST-NEXT: seto %cl
766 ; FAST-NEXT: movb %al, (%rdx)
767 ; FAST-NEXT: andb $1, %cl
768 ; FAST-NEXT: movzbl %cl, %eax
770 %v2 = load i8, i8* %ptr2
771 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
772 %val = extractvalue {i8, i1} %t, 0
773 %obit = extractvalue {i8, i1} %t, 1
774 store i8 %val, i8* %res
778 define zeroext i1 @smuloi16_load(i16* %ptr1, i16 %v2, i16* %res) {
779 ; SDAG-LABEL: smuloi16_load:
781 ; SDAG-NEXT: imulw (%rdi), %si
782 ; SDAG-NEXT: seto %al
783 ; SDAG-NEXT: movw %si, (%rdx)
786 ; FAST-LABEL: smuloi16_load:
788 ; FAST-NEXT: imulw (%rdi), %si
789 ; FAST-NEXT: seto %al
790 ; FAST-NEXT: movw %si, (%rdx)
791 ; FAST-NEXT: andb $1, %al
792 ; FAST-NEXT: movzbl %al, %eax
794 %v1 = load i16, i16* %ptr1
795 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
796 %val = extractvalue {i16, i1} %t, 0
797 %obit = extractvalue {i16, i1} %t, 1
798 store i16 %val, i16* %res
802 define zeroext i1 @smuloi16_load2(i16 %v1, i16* %ptr2, i16* %res) {
803 ; SDAG-LABEL: smuloi16_load2:
805 ; SDAG-NEXT: imulw (%rsi), %di
806 ; SDAG-NEXT: seto %al
807 ; SDAG-NEXT: movw %di, (%rdx)
810 ; FAST-LABEL: smuloi16_load2:
812 ; FAST-NEXT: imulw (%rsi), %di
813 ; FAST-NEXT: seto %al
814 ; FAST-NEXT: movw %di, (%rdx)
815 ; FAST-NEXT: andb $1, %al
816 ; FAST-NEXT: movzbl %al, %eax
818 %v2 = load i16, i16* %ptr2
819 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
820 %val = extractvalue {i16, i1} %t, 0
821 %obit = extractvalue {i16, i1} %t, 1
822 store i16 %val, i16* %res
826 define zeroext i1 @smuloi32_load(i32* %ptr1, i32 %v2, i32* %res) {
827 ; SDAG-LABEL: smuloi32_load:
829 ; SDAG-NEXT: imull (%rdi), %esi
830 ; SDAG-NEXT: seto %al
831 ; SDAG-NEXT: movl %esi, (%rdx)
834 ; FAST-LABEL: smuloi32_load:
836 ; FAST-NEXT: imull (%rdi), %esi
837 ; FAST-NEXT: seto %al
838 ; FAST-NEXT: movl %esi, (%rdx)
839 ; FAST-NEXT: andb $1, %al
840 ; FAST-NEXT: movzbl %al, %eax
842 %v1 = load i32, i32* %ptr1
843 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
844 %val = extractvalue {i32, i1} %t, 0
845 %obit = extractvalue {i32, i1} %t, 1
846 store i32 %val, i32* %res
850 define zeroext i1 @smuloi32_load2(i32 %v1, i32* %ptr2, i32* %res) {
851 ; SDAG-LABEL: smuloi32_load2:
853 ; SDAG-NEXT: imull (%rsi), %edi
854 ; SDAG-NEXT: seto %al
855 ; SDAG-NEXT: movl %edi, (%rdx)
858 ; FAST-LABEL: smuloi32_load2:
860 ; FAST-NEXT: imull (%rsi), %edi
861 ; FAST-NEXT: seto %al
862 ; FAST-NEXT: movl %edi, (%rdx)
863 ; FAST-NEXT: andb $1, %al
864 ; FAST-NEXT: movzbl %al, %eax
866 %v2 = load i32, i32* %ptr2
867 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
868 %val = extractvalue {i32, i1} %t, 0
869 %obit = extractvalue {i32, i1} %t, 1
870 store i32 %val, i32* %res
874 define zeroext i1 @smuloi64_load(i64* %ptr1, i64 %v2, i64* %res) {
875 ; SDAG-LABEL: smuloi64_load:
877 ; SDAG-NEXT: imulq (%rdi), %rsi
878 ; SDAG-NEXT: seto %al
879 ; SDAG-NEXT: movq %rsi, (%rdx)
882 ; FAST-LABEL: smuloi64_load:
884 ; FAST-NEXT: imulq (%rdi), %rsi
885 ; FAST-NEXT: seto %al
886 ; FAST-NEXT: movq %rsi, (%rdx)
887 ; FAST-NEXT: andb $1, %al
888 ; FAST-NEXT: movzbl %al, %eax
890 %v1 = load i64, i64* %ptr1
891 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
892 %val = extractvalue {i64, i1} %t, 0
893 %obit = extractvalue {i64, i1} %t, 1
894 store i64 %val, i64* %res
898 define zeroext i1 @smuloi64_load2(i64 %v1, i64* %ptr2, i64* %res) {
899 ; SDAG-LABEL: smuloi64_load2:
901 ; SDAG-NEXT: imulq (%rsi), %rdi
902 ; SDAG-NEXT: seto %al
903 ; SDAG-NEXT: movq %rdi, (%rdx)
906 ; FAST-LABEL: smuloi64_load2:
908 ; FAST-NEXT: imulq (%rsi), %rdi
909 ; FAST-NEXT: seto %al
910 ; FAST-NEXT: movq %rdi, (%rdx)
911 ; FAST-NEXT: andb $1, %al
912 ; FAST-NEXT: movzbl %al, %eax
914 %v2 = load i64, i64* %ptr2
915 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
916 %val = extractvalue {i64, i1} %t, 0
917 %obit = extractvalue {i64, i1} %t, 1
918 store i64 %val, i64* %res
922 define zeroext i1 @umuloi8_load(i8* %ptr1, i8 %v2, i8* %res) {
923 ; SDAG-LABEL: umuloi8_load:
925 ; SDAG-NEXT: movl %esi, %eax
926 ; SDAG-NEXT: ## kill: def $al killed $al killed $eax
927 ; SDAG-NEXT: mulb (%rdi)
928 ; SDAG-NEXT: seto %cl
929 ; SDAG-NEXT: movb %al, (%rdx)
930 ; SDAG-NEXT: movl %ecx, %eax
933 ; FAST-LABEL: umuloi8_load:
935 ; FAST-NEXT: movb (%rdi), %al
936 ; FAST-NEXT: mulb %sil
937 ; FAST-NEXT: seto %cl
938 ; FAST-NEXT: movb %al, (%rdx)
939 ; FAST-NEXT: andb $1, %cl
940 ; FAST-NEXT: movzbl %cl, %eax
942 %v1 = load i8, i8* %ptr1
943 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
944 %val = extractvalue {i8, i1} %t, 0
945 %obit = extractvalue {i8, i1} %t, 1
946 store i8 %val, i8* %res
950 define zeroext i1 @umuloi8_load2(i8 %v1, i8* %ptr2, i8* %res) {
951 ; SDAG-LABEL: umuloi8_load2:
953 ; SDAG-NEXT: movl %edi, %eax
954 ; SDAG-NEXT: ## kill: def $al killed $al killed $eax
955 ; SDAG-NEXT: mulb (%rsi)
956 ; SDAG-NEXT: seto %cl
957 ; SDAG-NEXT: movb %al, (%rdx)
958 ; SDAG-NEXT: movl %ecx, %eax
961 ; FAST-LABEL: umuloi8_load2:
963 ; FAST-NEXT: movl %edi, %eax
964 ; FAST-NEXT: ## kill: def $al killed $al killed $eax
965 ; FAST-NEXT: mulb (%rsi)
966 ; FAST-NEXT: seto %cl
967 ; FAST-NEXT: movb %al, (%rdx)
968 ; FAST-NEXT: andb $1, %cl
969 ; FAST-NEXT: movzbl %cl, %eax
971 %v2 = load i8, i8* %ptr2
972 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
973 %val = extractvalue {i8, i1} %t, 0
974 %obit = extractvalue {i8, i1} %t, 1
975 store i8 %val, i8* %res
979 define zeroext i1 @umuloi16_load(i16* %ptr1, i16 %v2, i16* %res) {
980 ; SDAG-LABEL: umuloi16_load:
982 ; SDAG-NEXT: movq %rdx, %rcx
983 ; SDAG-NEXT: movl %esi, %eax
984 ; SDAG-NEXT: ## kill: def $ax killed $ax killed $eax
985 ; SDAG-NEXT: mulw (%rdi)
986 ; SDAG-NEXT: seto %dl
987 ; SDAG-NEXT: movw %ax, (%rcx)
988 ; SDAG-NEXT: movl %edx, %eax
991 ; FAST-LABEL: umuloi16_load:
993 ; FAST-NEXT: movq %rdx, %rcx
994 ; FAST-NEXT: movzwl (%rdi), %eax
995 ; FAST-NEXT: mulw %si
996 ; FAST-NEXT: seto %dl
997 ; FAST-NEXT: movw %ax, (%rcx)
998 ; FAST-NEXT: andb $1, %dl
999 ; FAST-NEXT: movzbl %dl, %eax
1001 %v1 = load i16, i16* %ptr1
1002 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
1003 %val = extractvalue {i16, i1} %t, 0
1004 %obit = extractvalue {i16, i1} %t, 1
1005 store i16 %val, i16* %res
1009 define zeroext i1 @umuloi16_load2(i16 %v1, i16* %ptr2, i16* %res) {
1010 ; SDAG-LABEL: umuloi16_load2:
1012 ; SDAG-NEXT: movq %rdx, %rcx
1013 ; SDAG-NEXT: movl %edi, %eax
1014 ; SDAG-NEXT: ## kill: def $ax killed $ax killed $eax
1015 ; SDAG-NEXT: mulw (%rsi)
1016 ; SDAG-NEXT: seto %dl
1017 ; SDAG-NEXT: movw %ax, (%rcx)
1018 ; SDAG-NEXT: movl %edx, %eax
1021 ; FAST-LABEL: umuloi16_load2:
1023 ; FAST-NEXT: movq %rdx, %rcx
1024 ; FAST-NEXT: movl %edi, %eax
1025 ; FAST-NEXT: ## kill: def $ax killed $ax killed $eax
1026 ; FAST-NEXT: mulw (%rsi)
1027 ; FAST-NEXT: seto %dl
1028 ; FAST-NEXT: movw %ax, (%rcx)
1029 ; FAST-NEXT: andb $1, %dl
1030 ; FAST-NEXT: movzbl %dl, %eax
1032 %v2 = load i16, i16* %ptr2
1033 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
1034 %val = extractvalue {i16, i1} %t, 0
1035 %obit = extractvalue {i16, i1} %t, 1
1036 store i16 %val, i16* %res
1040 define zeroext i1 @umuloi32_load(i32* %ptr1, i32 %v2, i32* %res) {
1041 ; SDAG-LABEL: umuloi32_load:
1043 ; SDAG-NEXT: movq %rdx, %rcx
1044 ; SDAG-NEXT: movl %esi, %eax
1045 ; SDAG-NEXT: mull (%rdi)
1046 ; SDAG-NEXT: seto %dl
1047 ; SDAG-NEXT: movl %eax, (%rcx)
1048 ; SDAG-NEXT: movl %edx, %eax
1051 ; FAST-LABEL: umuloi32_load:
1053 ; FAST-NEXT: movq %rdx, %rcx
1054 ; FAST-NEXT: movl (%rdi), %eax
1055 ; FAST-NEXT: mull %esi
1056 ; FAST-NEXT: seto %dl
1057 ; FAST-NEXT: movl %eax, (%rcx)
1058 ; FAST-NEXT: andb $1, %dl
1059 ; FAST-NEXT: movzbl %dl, %eax
1061 %v1 = load i32, i32* %ptr1
1062 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
1063 %val = extractvalue {i32, i1} %t, 0
1064 %obit = extractvalue {i32, i1} %t, 1
1065 store i32 %val, i32* %res
1069 define zeroext i1 @umuloi32_load2(i32 %v1, i32* %ptr2, i32* %res) {
1070 ; SDAG-LABEL: umuloi32_load2:
1072 ; SDAG-NEXT: movq %rdx, %rcx
1073 ; SDAG-NEXT: movl %edi, %eax
1074 ; SDAG-NEXT: mull (%rsi)
1075 ; SDAG-NEXT: seto %dl
1076 ; SDAG-NEXT: movl %eax, (%rcx)
1077 ; SDAG-NEXT: movl %edx, %eax
1080 ; FAST-LABEL: umuloi32_load2:
1082 ; FAST-NEXT: movq %rdx, %rcx
1083 ; FAST-NEXT: movl %edi, %eax
1084 ; FAST-NEXT: mull (%rsi)
1085 ; FAST-NEXT: seto %dl
1086 ; FAST-NEXT: movl %eax, (%rcx)
1087 ; FAST-NEXT: andb $1, %dl
1088 ; FAST-NEXT: movzbl %dl, %eax
1090 %v2 = load i32, i32* %ptr2
1091 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
1092 %val = extractvalue {i32, i1} %t, 0
1093 %obit = extractvalue {i32, i1} %t, 1
1094 store i32 %val, i32* %res
1098 define zeroext i1 @umuloi64_load(i64* %ptr1, i64 %v2, i64* %res) {
1099 ; SDAG-LABEL: umuloi64_load:
1101 ; SDAG-NEXT: movq %rdx, %rcx
1102 ; SDAG-NEXT: movq %rsi, %rax
1103 ; SDAG-NEXT: mulq (%rdi)
1104 ; SDAG-NEXT: seto %dl
1105 ; SDAG-NEXT: movq %rax, (%rcx)
1106 ; SDAG-NEXT: movl %edx, %eax
1109 ; FAST-LABEL: umuloi64_load:
1111 ; FAST-NEXT: movq %rdx, %rcx
1112 ; FAST-NEXT: movq (%rdi), %rax
1113 ; FAST-NEXT: mulq %rsi
1114 ; FAST-NEXT: seto %dl
1115 ; FAST-NEXT: movq %rax, (%rcx)
1116 ; FAST-NEXT: andb $1, %dl
1117 ; FAST-NEXT: movzbl %dl, %eax
1119 %v1 = load i64, i64* %ptr1
1120 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
1121 %val = extractvalue {i64, i1} %t, 0
1122 %obit = extractvalue {i64, i1} %t, 1
1123 store i64 %val, i64* %res
1127 define zeroext i1 @umuloi64_load2(i64 %v1, i64* %ptr2, i64* %res) {
1128 ; SDAG-LABEL: umuloi64_load2:
1130 ; SDAG-NEXT: movq %rdx, %rcx
1131 ; SDAG-NEXT: movq %rdi, %rax
1132 ; SDAG-NEXT: mulq (%rsi)
1133 ; SDAG-NEXT: seto %dl
1134 ; SDAG-NEXT: movq %rax, (%rcx)
1135 ; SDAG-NEXT: movl %edx, %eax
1138 ; FAST-LABEL: umuloi64_load2:
1140 ; FAST-NEXT: movq %rdx, %rcx
1141 ; FAST-NEXT: movq %rdi, %rax
1142 ; FAST-NEXT: mulq (%rsi)
1143 ; FAST-NEXT: seto %dl
1144 ; FAST-NEXT: movq %rax, (%rcx)
1145 ; FAST-NEXT: andb $1, %dl
1146 ; FAST-NEXT: movzbl %dl, %eax
1148 %v2 = load i64, i64* %ptr2
1149 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
1150 %val = extractvalue {i64, i1} %t, 0
1151 %obit = extractvalue {i64, i1} %t, 1
1152 store i64 %val, i64* %res
1156 declare {i8, i1} @llvm.smul.with.overflow.i8 (i8, i8 ) nounwind readnone
1157 declare {i16, i1} @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone
1158 declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
1159 declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
1160 declare {i8, i1} @llvm.umul.with.overflow.i8 (i8, i8 ) nounwind readnone
1161 declare {i16, i1} @llvm.umul.with.overflow.i16(i16, i16) nounwind readnone
1162 declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
1163 declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone
1165 !0 = !{!"branch_weights", i32 0, i32 2147483647}