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 %ecx, %ecx
30 ; SDAG-NEXT: movl $9, %eax
31 ; SDAG-NEXT: mulq %rcx
37 ; FAST-NEXT: xorl %ecx, %ecx
38 ; FAST-NEXT: movl $9, %eax
39 ; FAST-NEXT: mulq %rcx
42 %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 0)
46 define {i64, i1} @t3() nounwind {
49 ; SDAG-NEXT: movq $-1, %rcx
50 ; SDAG-NEXT: movl $9, %eax
51 ; SDAG-NEXT: mulq %rcx
57 ; FAST-NEXT: movq $-1, %rcx
58 ; FAST-NEXT: movl $9, %eax
59 ; FAST-NEXT: mulq %rcx
62 %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 -1)
67 define zeroext i1 @smuloi8(i8 %v1, i8 %v2, i8* %res) {
68 ; SDAG-LABEL: smuloi8:
70 ; SDAG-NEXT: movl %edi, %eax
71 ; SDAG-NEXT: ## kill: def $al killed $al killed $eax
72 ; SDAG-NEXT: imulb %sil
74 ; SDAG-NEXT: movb %al, (%rdx)
75 ; SDAG-NEXT: movl %ecx, %eax
78 ; FAST-LABEL: smuloi8:
80 ; FAST-NEXT: movl %edi, %eax
81 ; FAST-NEXT: ## kill: def $al killed $al killed $eax
82 ; FAST-NEXT: imulb %sil
84 ; FAST-NEXT: movb %al, (%rdx)
85 ; FAST-NEXT: andb $1, %cl
86 ; FAST-NEXT: movzbl %cl, %eax
88 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
89 %val = extractvalue {i8, i1} %t, 0
90 %obit = extractvalue {i8, i1} %t, 1
91 store i8 %val, i8* %res
95 define zeroext i1 @smuloi16(i16 %v1, i16 %v2, i16* %res) {
96 ; SDAG-LABEL: smuloi16:
98 ; SDAG-NEXT: imulw %si, %di
100 ; SDAG-NEXT: movw %di, (%rdx)
103 ; FAST-LABEL: smuloi16:
105 ; FAST-NEXT: imulw %si, %di
106 ; FAST-NEXT: seto %al
107 ; FAST-NEXT: movw %di, (%rdx)
108 ; FAST-NEXT: andb $1, %al
109 ; FAST-NEXT: movzbl %al, %eax
111 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
112 %val = extractvalue {i16, i1} %t, 0
113 %obit = extractvalue {i16, i1} %t, 1
114 store i16 %val, i16* %res
118 define zeroext i1 @smuloi32(i32 %v1, i32 %v2, i32* %res) {
119 ; SDAG-LABEL: smuloi32:
121 ; SDAG-NEXT: imull %esi, %edi
122 ; SDAG-NEXT: seto %al
123 ; SDAG-NEXT: movl %edi, (%rdx)
126 ; FAST-LABEL: smuloi32:
128 ; FAST-NEXT: imull %esi, %edi
129 ; FAST-NEXT: seto %al
130 ; FAST-NEXT: movl %edi, (%rdx)
131 ; FAST-NEXT: andb $1, %al
132 ; FAST-NEXT: movzbl %al, %eax
134 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
135 %val = extractvalue {i32, i1} %t, 0
136 %obit = extractvalue {i32, i1} %t, 1
137 store i32 %val, i32* %res
141 define zeroext i1 @smuloi64(i64 %v1, i64 %v2, i64* %res) {
142 ; SDAG-LABEL: smuloi64:
144 ; SDAG-NEXT: imulq %rsi, %rdi
145 ; SDAG-NEXT: seto %al
146 ; SDAG-NEXT: movq %rdi, (%rdx)
149 ; FAST-LABEL: smuloi64:
151 ; FAST-NEXT: imulq %rsi, %rdi
152 ; FAST-NEXT: seto %al
153 ; FAST-NEXT: movq %rdi, (%rdx)
154 ; FAST-NEXT: andb $1, %al
155 ; FAST-NEXT: movzbl %al, %eax
157 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
158 %val = extractvalue {i64, i1} %t, 0
159 %obit = extractvalue {i64, i1} %t, 1
160 store i64 %val, i64* %res
165 define zeroext i1 @umuloi8(i8 %v1, i8 %v2, i8* %res) {
166 ; SDAG-LABEL: umuloi8:
168 ; SDAG-NEXT: movl %edi, %eax
169 ; SDAG-NEXT: ## kill: def $al killed $al killed $eax
170 ; SDAG-NEXT: mulb %sil
171 ; SDAG-NEXT: seto %cl
172 ; SDAG-NEXT: movb %al, (%rdx)
173 ; SDAG-NEXT: movl %ecx, %eax
176 ; FAST-LABEL: umuloi8:
178 ; FAST-NEXT: movl %edi, %eax
179 ; FAST-NEXT: ## kill: def $al killed $al killed $eax
180 ; FAST-NEXT: mulb %sil
181 ; FAST-NEXT: seto %cl
182 ; FAST-NEXT: movb %al, (%rdx)
183 ; FAST-NEXT: andb $1, %cl
184 ; FAST-NEXT: movzbl %cl, %eax
186 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
187 %val = extractvalue {i8, i1} %t, 0
188 %obit = extractvalue {i8, i1} %t, 1
189 store i8 %val, i8* %res
193 define zeroext i1 @umuloi16(i16 %v1, i16 %v2, i16* %res) {
194 ; SDAG-LABEL: umuloi16:
196 ; SDAG-NEXT: movq %rdx, %rcx
197 ; SDAG-NEXT: movl %edi, %eax
198 ; SDAG-NEXT: ## kill: def $ax killed $ax killed $eax
199 ; SDAG-NEXT: mulw %si
200 ; SDAG-NEXT: seto %dl
201 ; SDAG-NEXT: movw %ax, (%rcx)
202 ; SDAG-NEXT: movl %edx, %eax
205 ; FAST-LABEL: umuloi16:
207 ; FAST-NEXT: movq %rdx, %rcx
208 ; FAST-NEXT: movl %edi, %eax
209 ; FAST-NEXT: ## kill: def $ax killed $ax killed $eax
210 ; FAST-NEXT: mulw %si
211 ; FAST-NEXT: seto %dl
212 ; FAST-NEXT: movw %ax, (%rcx)
213 ; FAST-NEXT: andb $1, %dl
214 ; FAST-NEXT: movzbl %dl, %eax
216 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
217 %val = extractvalue {i16, i1} %t, 0
218 %obit = extractvalue {i16, i1} %t, 1
219 store i16 %val, i16* %res
223 define zeroext i1 @umuloi32(i32 %v1, i32 %v2, i32* %res) {
224 ; SDAG-LABEL: umuloi32:
226 ; SDAG-NEXT: movq %rdx, %rcx
227 ; SDAG-NEXT: movl %edi, %eax
228 ; SDAG-NEXT: mull %esi
229 ; SDAG-NEXT: seto %dl
230 ; SDAG-NEXT: movl %eax, (%rcx)
231 ; SDAG-NEXT: movl %edx, %eax
234 ; FAST-LABEL: umuloi32:
236 ; FAST-NEXT: movq %rdx, %rcx
237 ; FAST-NEXT: movl %edi, %eax
238 ; FAST-NEXT: mull %esi
239 ; FAST-NEXT: seto %dl
240 ; FAST-NEXT: movl %eax, (%rcx)
241 ; FAST-NEXT: andb $1, %dl
242 ; FAST-NEXT: movzbl %dl, %eax
244 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
245 %val = extractvalue {i32, i1} %t, 0
246 %obit = extractvalue {i32, i1} %t, 1
247 store i32 %val, i32* %res
251 define zeroext i1 @umuloi64(i64 %v1, i64 %v2, i64* %res) {
252 ; SDAG-LABEL: umuloi64:
254 ; SDAG-NEXT: movq %rdx, %rcx
255 ; SDAG-NEXT: movq %rdi, %rax
256 ; SDAG-NEXT: mulq %rsi
257 ; SDAG-NEXT: seto %dl
258 ; SDAG-NEXT: movq %rax, (%rcx)
259 ; SDAG-NEXT: movl %edx, %eax
262 ; FAST-LABEL: umuloi64:
264 ; FAST-NEXT: movq %rdx, %rcx
265 ; FAST-NEXT: movq %rdi, %rax
266 ; FAST-NEXT: mulq %rsi
267 ; FAST-NEXT: seto %dl
268 ; FAST-NEXT: movq %rax, (%rcx)
269 ; FAST-NEXT: andb $1, %dl
270 ; FAST-NEXT: movzbl %dl, %eax
272 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
273 %val = extractvalue {i64, i1} %t, 0
274 %obit = extractvalue {i64, i1} %t, 1
275 store i64 %val, i64* %res
280 ; Check the use of the overflow bit in combination with a select instruction.
282 define i32 @smuloselecti32(i32 %v1, i32 %v2) {
283 ; SDAG-LABEL: smuloselecti32:
285 ; SDAG-NEXT: movl %esi, %eax
286 ; SDAG-NEXT: movl %edi, %ecx
287 ; SDAG-NEXT: imull %esi, %ecx
288 ; SDAG-NEXT: cmovol %edi, %eax
291 ; FAST-LABEL: smuloselecti32:
293 ; FAST-NEXT: movl %esi, %eax
294 ; FAST-NEXT: movl %edi, %ecx
295 ; FAST-NEXT: imull %esi, %ecx
296 ; FAST-NEXT: cmovol %edi, %eax
298 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
299 %obit = extractvalue {i32, i1} %t, 1
300 %ret = select i1 %obit, i32 %v1, i32 %v2
304 define i64 @smuloselecti64(i64 %v1, i64 %v2) {
305 ; SDAG-LABEL: smuloselecti64:
307 ; SDAG-NEXT: movq %rsi, %rax
308 ; SDAG-NEXT: movq %rdi, %rcx
309 ; SDAG-NEXT: imulq %rsi, %rcx
310 ; SDAG-NEXT: cmovoq %rdi, %rax
313 ; FAST-LABEL: smuloselecti64:
315 ; FAST-NEXT: movq %rsi, %rax
316 ; FAST-NEXT: movq %rdi, %rcx
317 ; FAST-NEXT: imulq %rsi, %rcx
318 ; FAST-NEXT: cmovoq %rdi, %rax
320 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
321 %obit = extractvalue {i64, i1} %t, 1
322 %ret = select i1 %obit, i64 %v1, i64 %v2
326 define i32 @umuloselecti32(i32 %v1, i32 %v2) {
327 ; SDAG-LABEL: umuloselecti32:
329 ; SDAG-NEXT: movl %edi, %eax
330 ; SDAG-NEXT: mull %esi
331 ; SDAG-NEXT: cmovol %edi, %esi
332 ; SDAG-NEXT: movl %esi, %eax
335 ; FAST-LABEL: umuloselecti32:
337 ; FAST-NEXT: movl %edi, %eax
338 ; FAST-NEXT: mull %esi
339 ; FAST-NEXT: cmovol %edi, %esi
340 ; FAST-NEXT: movl %esi, %eax
342 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
343 %obit = extractvalue {i32, i1} %t, 1
344 %ret = select i1 %obit, i32 %v1, i32 %v2
348 define i64 @umuloselecti64(i64 %v1, i64 %v2) {
349 ; SDAG-LABEL: umuloselecti64:
351 ; SDAG-NEXT: movq %rdi, %rax
352 ; SDAG-NEXT: mulq %rsi
353 ; SDAG-NEXT: cmovoq %rdi, %rsi
354 ; SDAG-NEXT: movq %rsi, %rax
357 ; FAST-LABEL: umuloselecti64:
359 ; FAST-NEXT: movq %rdi, %rax
360 ; FAST-NEXT: mulq %rsi
361 ; FAST-NEXT: cmovoq %rdi, %rsi
362 ; FAST-NEXT: movq %rsi, %rax
364 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
365 %obit = extractvalue {i64, i1} %t, 1
366 %ret = select i1 %obit, i64 %v1, i64 %v2
371 ; Check the use of the overflow bit in combination with a branch instruction.
373 define zeroext i1 @smulobri8(i8 %v1, i8 %v2) {
374 ; SDAG-LABEL: smulobri8:
376 ; SDAG-NEXT: movl %edi, %eax
377 ; SDAG-NEXT: ## kill: def $al killed $al killed $eax
378 ; SDAG-NEXT: imulb %sil
379 ; SDAG-NEXT: jo LBB15_1
380 ; SDAG-NEXT: ## %bb.2: ## %continue
381 ; SDAG-NEXT: movb $1, %al
383 ; SDAG-NEXT: LBB15_1: ## %overflow
384 ; SDAG-NEXT: xorl %eax, %eax
387 ; FAST-LABEL: smulobri8:
389 ; FAST-NEXT: movl %edi, %eax
390 ; FAST-NEXT: ## kill: def $al killed $al killed $eax
391 ; FAST-NEXT: imulb %sil
392 ; FAST-NEXT: seto %al
393 ; FAST-NEXT: testb $1, %al
394 ; FAST-NEXT: jne LBB15_1
395 ; FAST-NEXT: ## %bb.2: ## %continue
396 ; FAST-NEXT: movb $1, %al
397 ; FAST-NEXT: andb $1, %al
398 ; FAST-NEXT: movzbl %al, %eax
400 ; FAST-NEXT: LBB15_1: ## %overflow
401 ; FAST-NEXT: xorl %eax, %eax
402 ; FAST-NEXT: andb $1, %al
403 ; FAST-NEXT: movzbl %al, %eax
405 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
406 %val = extractvalue {i8, i1} %t, 0
407 %obit = extractvalue {i8, i1} %t, 1
408 br i1 %obit, label %overflow, label %continue, !prof !0
417 define zeroext i1 @smulobri16(i16 %v1, i16 %v2) {
418 ; SDAG-LABEL: smulobri16:
420 ; SDAG-NEXT: imulw %si, %di
421 ; SDAG-NEXT: jo LBB16_1
422 ; SDAG-NEXT: ## %bb.2: ## %continue
423 ; SDAG-NEXT: movb $1, %al
425 ; SDAG-NEXT: LBB16_1: ## %overflow
426 ; SDAG-NEXT: xorl %eax, %eax
429 ; FAST-LABEL: smulobri16:
431 ; FAST-NEXT: imulw %si, %di
432 ; FAST-NEXT: seto %al
433 ; FAST-NEXT: testb $1, %al
434 ; FAST-NEXT: jne LBB16_1
435 ; FAST-NEXT: ## %bb.2: ## %continue
436 ; FAST-NEXT: movb $1, %al
437 ; FAST-NEXT: andb $1, %al
438 ; FAST-NEXT: movzbl %al, %eax
440 ; FAST-NEXT: LBB16_1: ## %overflow
441 ; FAST-NEXT: xorl %eax, %eax
442 ; FAST-NEXT: andb $1, %al
443 ; FAST-NEXT: movzbl %al, %eax
445 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
446 %val = extractvalue {i16, i1} %t, 0
447 %obit = extractvalue {i16, i1} %t, 1
448 br i1 %obit, label %overflow, label %continue, !prof !0
457 define zeroext i1 @smulobri32(i32 %v1, i32 %v2) {
458 ; SDAG-LABEL: smulobri32:
460 ; SDAG-NEXT: imull %esi, %edi
461 ; SDAG-NEXT: jo LBB17_1
462 ; SDAG-NEXT: ## %bb.2: ## %continue
463 ; SDAG-NEXT: movb $1, %al
465 ; SDAG-NEXT: LBB17_1: ## %overflow
466 ; SDAG-NEXT: xorl %eax, %eax
469 ; FAST-LABEL: smulobri32:
471 ; FAST-NEXT: imull %esi, %edi
472 ; FAST-NEXT: jo LBB17_1
473 ; FAST-NEXT: ## %bb.2: ## %continue
474 ; FAST-NEXT: movb $1, %al
475 ; FAST-NEXT: andb $1, %al
476 ; FAST-NEXT: movzbl %al, %eax
478 ; FAST-NEXT: LBB17_1: ## %overflow
479 ; FAST-NEXT: xorl %eax, %eax
480 ; FAST-NEXT: andb $1, %al
481 ; FAST-NEXT: movzbl %al, %eax
483 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
484 %val = extractvalue {i32, i1} %t, 0
485 %obit = extractvalue {i32, i1} %t, 1
486 br i1 %obit, label %overflow, label %continue, !prof !0
495 define zeroext i1 @smulobri64(i64 %v1, i64 %v2) {
496 ; SDAG-LABEL: smulobri64:
498 ; SDAG-NEXT: imulq %rsi, %rdi
499 ; SDAG-NEXT: jo LBB18_1
500 ; SDAG-NEXT: ## %bb.2: ## %continue
501 ; SDAG-NEXT: movb $1, %al
503 ; SDAG-NEXT: LBB18_1: ## %overflow
504 ; SDAG-NEXT: xorl %eax, %eax
507 ; FAST-LABEL: smulobri64:
509 ; FAST-NEXT: imulq %rsi, %rdi
510 ; FAST-NEXT: jo LBB18_1
511 ; FAST-NEXT: ## %bb.2: ## %continue
512 ; FAST-NEXT: movb $1, %al
513 ; FAST-NEXT: andb $1, %al
514 ; FAST-NEXT: movzbl %al, %eax
516 ; FAST-NEXT: LBB18_1: ## %overflow
517 ; FAST-NEXT: xorl %eax, %eax
518 ; FAST-NEXT: andb $1, %al
519 ; FAST-NEXT: movzbl %al, %eax
521 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
522 %val = extractvalue {i64, i1} %t, 0
523 %obit = extractvalue {i64, i1} %t, 1
524 br i1 %obit, label %overflow, label %continue, !prof !0
533 define zeroext i1 @umulobri8(i8 %v1, i8 %v2) {
534 ; SDAG-LABEL: umulobri8:
536 ; SDAG-NEXT: movl %edi, %eax
537 ; SDAG-NEXT: ## kill: def $al killed $al killed $eax
538 ; SDAG-NEXT: mulb %sil
539 ; SDAG-NEXT: jo LBB19_1
540 ; SDAG-NEXT: ## %bb.2: ## %continue
541 ; SDAG-NEXT: movb $1, %al
543 ; SDAG-NEXT: LBB19_1: ## %overflow
544 ; SDAG-NEXT: xorl %eax, %eax
547 ; FAST-LABEL: umulobri8:
549 ; FAST-NEXT: movl %edi, %eax
550 ; FAST-NEXT: ## kill: def $al killed $al killed $eax
551 ; FAST-NEXT: mulb %sil
552 ; FAST-NEXT: seto %al
553 ; FAST-NEXT: testb $1, %al
554 ; FAST-NEXT: jne LBB19_1
555 ; FAST-NEXT: ## %bb.2: ## %continue
556 ; FAST-NEXT: movb $1, %al
557 ; FAST-NEXT: andb $1, %al
558 ; FAST-NEXT: movzbl %al, %eax
560 ; FAST-NEXT: LBB19_1: ## %overflow
561 ; FAST-NEXT: xorl %eax, %eax
562 ; FAST-NEXT: andb $1, %al
563 ; FAST-NEXT: movzbl %al, %eax
565 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
566 %val = extractvalue {i8, i1} %t, 0
567 %obit = extractvalue {i8, i1} %t, 1
568 br i1 %obit, label %overflow, label %continue, !prof !0
577 define zeroext i1 @umulobri16(i16 %v1, i16 %v2) {
578 ; SDAG-LABEL: umulobri16:
580 ; SDAG-NEXT: movl %edi, %eax
581 ; SDAG-NEXT: ## kill: def $ax killed $ax killed $eax
582 ; SDAG-NEXT: mulw %si
583 ; SDAG-NEXT: jo LBB20_1
584 ; SDAG-NEXT: ## %bb.2: ## %continue
585 ; SDAG-NEXT: movb $1, %al
587 ; SDAG-NEXT: LBB20_1: ## %overflow
588 ; SDAG-NEXT: xorl %eax, %eax
591 ; FAST-LABEL: umulobri16:
593 ; FAST-NEXT: movl %edi, %eax
594 ; FAST-NEXT: ## kill: def $ax killed $ax killed $eax
595 ; FAST-NEXT: mulw %si
596 ; FAST-NEXT: seto %al
597 ; FAST-NEXT: testb $1, %al
598 ; FAST-NEXT: jne LBB20_1
599 ; FAST-NEXT: ## %bb.2: ## %continue
600 ; FAST-NEXT: movb $1, %al
601 ; FAST-NEXT: andb $1, %al
602 ; FAST-NEXT: movzbl %al, %eax
604 ; FAST-NEXT: LBB20_1: ## %overflow
605 ; FAST-NEXT: xorl %eax, %eax
606 ; FAST-NEXT: andb $1, %al
607 ; FAST-NEXT: movzbl %al, %eax
609 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
610 %val = extractvalue {i16, i1} %t, 0
611 %obit = extractvalue {i16, i1} %t, 1
612 br i1 %obit, label %overflow, label %continue, !prof !0
621 define zeroext i1 @umulobri32(i32 %v1, i32 %v2) {
622 ; SDAG-LABEL: umulobri32:
624 ; SDAG-NEXT: movl %edi, %eax
625 ; SDAG-NEXT: mull %esi
626 ; SDAG-NEXT: jo LBB21_1
627 ; SDAG-NEXT: ## %bb.2: ## %continue
628 ; SDAG-NEXT: movb $1, %al
630 ; SDAG-NEXT: LBB21_1: ## %overflow
631 ; SDAG-NEXT: xorl %eax, %eax
634 ; FAST-LABEL: umulobri32:
636 ; FAST-NEXT: movl %edi, %eax
637 ; FAST-NEXT: mull %esi
638 ; FAST-NEXT: jo LBB21_1
639 ; FAST-NEXT: ## %bb.2: ## %continue
640 ; FAST-NEXT: movb $1, %al
641 ; FAST-NEXT: andb $1, %al
642 ; FAST-NEXT: movzbl %al, %eax
644 ; FAST-NEXT: LBB21_1: ## %overflow
645 ; FAST-NEXT: xorl %eax, %eax
646 ; FAST-NEXT: andb $1, %al
647 ; FAST-NEXT: movzbl %al, %eax
649 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
650 %val = extractvalue {i32, i1} %t, 0
651 %obit = extractvalue {i32, i1} %t, 1
652 br i1 %obit, label %overflow, label %continue, !prof !0
661 define zeroext i1 @umulobri64(i64 %v1, i64 %v2) {
662 ; SDAG-LABEL: umulobri64:
664 ; SDAG-NEXT: movq %rdi, %rax
665 ; SDAG-NEXT: mulq %rsi
666 ; SDAG-NEXT: jo LBB22_1
667 ; SDAG-NEXT: ## %bb.2: ## %continue
668 ; SDAG-NEXT: movb $1, %al
670 ; SDAG-NEXT: LBB22_1: ## %overflow
671 ; SDAG-NEXT: xorl %eax, %eax
674 ; FAST-LABEL: umulobri64:
676 ; FAST-NEXT: movq %rdi, %rax
677 ; FAST-NEXT: mulq %rsi
678 ; FAST-NEXT: jo LBB22_1
679 ; FAST-NEXT: ## %bb.2: ## %continue
680 ; FAST-NEXT: movb $1, %al
681 ; FAST-NEXT: andb $1, %al
682 ; FAST-NEXT: movzbl %al, %eax
684 ; FAST-NEXT: LBB22_1: ## %overflow
685 ; FAST-NEXT: xorl %eax, %eax
686 ; FAST-NEXT: andb $1, %al
687 ; FAST-NEXT: movzbl %al, %eax
689 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
690 %val = extractvalue {i64, i1} %t, 0
691 %obit = extractvalue {i64, i1} %t, 1
692 br i1 %obit, label %overflow, label %continue, !prof !0
701 define i1 @bug27873(i64 %c1, i1 %c2) {
702 ; SDAG-LABEL: bug27873:
704 ; SDAG-NEXT: movq %rdi, %rax
705 ; SDAG-NEXT: movl $160, %ecx
706 ; SDAG-NEXT: mulq %rcx
707 ; SDAG-NEXT: seto %al
708 ; SDAG-NEXT: orb %sil, %al
711 ; FAST-LABEL: bug27873:
713 ; FAST-NEXT: movq %rdi, %rax
714 ; FAST-NEXT: movl $160, %ecx
715 ; FAST-NEXT: mulq %rcx
716 ; FAST-NEXT: seto %al
717 ; FAST-NEXT: orb %sil, %al
719 %mul = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %c1, i64 160)
720 %mul.overflow = extractvalue { i64, i1 } %mul, 1
721 %x1 = or i1 %c2, %mul.overflow
725 define zeroext i1 @smuloi8_load(i8* %ptr1, i8 %v2, i8* %res) {
726 ; SDAG-LABEL: smuloi8_load:
728 ; SDAG-NEXT: movl %esi, %eax
729 ; SDAG-NEXT: ## kill: def $al killed $al killed $eax
730 ; SDAG-NEXT: imulb (%rdi)
731 ; SDAG-NEXT: seto %cl
732 ; SDAG-NEXT: movb %al, (%rdx)
733 ; SDAG-NEXT: movl %ecx, %eax
736 ; FAST-LABEL: smuloi8_load:
738 ; FAST-NEXT: movb (%rdi), %al
739 ; FAST-NEXT: imulb %sil
740 ; FAST-NEXT: seto %cl
741 ; FAST-NEXT: movb %al, (%rdx)
742 ; FAST-NEXT: andb $1, %cl
743 ; FAST-NEXT: movzbl %cl, %eax
745 %v1 = load i8, i8* %ptr1
746 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
747 %val = extractvalue {i8, i1} %t, 0
748 %obit = extractvalue {i8, i1} %t, 1
749 store i8 %val, i8* %res
753 define zeroext i1 @smuloi8_load2(i8 %v1, i8* %ptr2, i8* %res) {
754 ; SDAG-LABEL: smuloi8_load2:
756 ; SDAG-NEXT: movl %edi, %eax
757 ; SDAG-NEXT: ## kill: def $al killed $al killed $eax
758 ; SDAG-NEXT: imulb (%rsi)
759 ; SDAG-NEXT: seto %cl
760 ; SDAG-NEXT: movb %al, (%rdx)
761 ; SDAG-NEXT: movl %ecx, %eax
764 ; FAST-LABEL: smuloi8_load2:
766 ; FAST-NEXT: movl %edi, %eax
767 ; FAST-NEXT: ## kill: def $al killed $al killed $eax
768 ; FAST-NEXT: imulb (%rsi)
769 ; FAST-NEXT: seto %cl
770 ; FAST-NEXT: movb %al, (%rdx)
771 ; FAST-NEXT: andb $1, %cl
772 ; FAST-NEXT: movzbl %cl, %eax
774 %v2 = load i8, i8* %ptr2
775 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
776 %val = extractvalue {i8, i1} %t, 0
777 %obit = extractvalue {i8, i1} %t, 1
778 store i8 %val, i8* %res
782 define zeroext i1 @smuloi16_load(i16* %ptr1, i16 %v2, i16* %res) {
783 ; SDAG-LABEL: smuloi16_load:
785 ; SDAG-NEXT: imulw (%rdi), %si
786 ; SDAG-NEXT: seto %al
787 ; SDAG-NEXT: movw %si, (%rdx)
790 ; FAST-LABEL: smuloi16_load:
792 ; FAST-NEXT: imulw (%rdi), %si
793 ; FAST-NEXT: seto %al
794 ; FAST-NEXT: movw %si, (%rdx)
795 ; FAST-NEXT: andb $1, %al
796 ; FAST-NEXT: movzbl %al, %eax
798 %v1 = load i16, i16* %ptr1
799 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
800 %val = extractvalue {i16, i1} %t, 0
801 %obit = extractvalue {i16, i1} %t, 1
802 store i16 %val, i16* %res
806 define zeroext i1 @smuloi16_load2(i16 %v1, i16* %ptr2, i16* %res) {
807 ; SDAG-LABEL: smuloi16_load2:
809 ; SDAG-NEXT: imulw (%rsi), %di
810 ; SDAG-NEXT: seto %al
811 ; SDAG-NEXT: movw %di, (%rdx)
814 ; FAST-LABEL: smuloi16_load2:
816 ; FAST-NEXT: imulw (%rsi), %di
817 ; FAST-NEXT: seto %al
818 ; FAST-NEXT: movw %di, (%rdx)
819 ; FAST-NEXT: andb $1, %al
820 ; FAST-NEXT: movzbl %al, %eax
822 %v2 = load i16, i16* %ptr2
823 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
824 %val = extractvalue {i16, i1} %t, 0
825 %obit = extractvalue {i16, i1} %t, 1
826 store i16 %val, i16* %res
830 define zeroext i1 @smuloi32_load(i32* %ptr1, i32 %v2, i32* %res) {
831 ; SDAG-LABEL: smuloi32_load:
833 ; SDAG-NEXT: imull (%rdi), %esi
834 ; SDAG-NEXT: seto %al
835 ; SDAG-NEXT: movl %esi, (%rdx)
838 ; FAST-LABEL: smuloi32_load:
840 ; FAST-NEXT: imull (%rdi), %esi
841 ; FAST-NEXT: seto %al
842 ; FAST-NEXT: movl %esi, (%rdx)
843 ; FAST-NEXT: andb $1, %al
844 ; FAST-NEXT: movzbl %al, %eax
846 %v1 = load i32, i32* %ptr1
847 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
848 %val = extractvalue {i32, i1} %t, 0
849 %obit = extractvalue {i32, i1} %t, 1
850 store i32 %val, i32* %res
854 define zeroext i1 @smuloi32_load2(i32 %v1, i32* %ptr2, i32* %res) {
855 ; SDAG-LABEL: smuloi32_load2:
857 ; SDAG-NEXT: imull (%rsi), %edi
858 ; SDAG-NEXT: seto %al
859 ; SDAG-NEXT: movl %edi, (%rdx)
862 ; FAST-LABEL: smuloi32_load2:
864 ; FAST-NEXT: imull (%rsi), %edi
865 ; FAST-NEXT: seto %al
866 ; FAST-NEXT: movl %edi, (%rdx)
867 ; FAST-NEXT: andb $1, %al
868 ; FAST-NEXT: movzbl %al, %eax
870 %v2 = load i32, i32* %ptr2
871 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
872 %val = extractvalue {i32, i1} %t, 0
873 %obit = extractvalue {i32, i1} %t, 1
874 store i32 %val, i32* %res
878 define zeroext i1 @smuloi64_load(i64* %ptr1, i64 %v2, i64* %res) {
879 ; SDAG-LABEL: smuloi64_load:
881 ; SDAG-NEXT: imulq (%rdi), %rsi
882 ; SDAG-NEXT: seto %al
883 ; SDAG-NEXT: movq %rsi, (%rdx)
886 ; FAST-LABEL: smuloi64_load:
888 ; FAST-NEXT: imulq (%rdi), %rsi
889 ; FAST-NEXT: seto %al
890 ; FAST-NEXT: movq %rsi, (%rdx)
891 ; FAST-NEXT: andb $1, %al
892 ; FAST-NEXT: movzbl %al, %eax
894 %v1 = load i64, i64* %ptr1
895 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
896 %val = extractvalue {i64, i1} %t, 0
897 %obit = extractvalue {i64, i1} %t, 1
898 store i64 %val, i64* %res
902 define zeroext i1 @smuloi64_load2(i64 %v1, i64* %ptr2, i64* %res) {
903 ; SDAG-LABEL: smuloi64_load2:
905 ; SDAG-NEXT: imulq (%rsi), %rdi
906 ; SDAG-NEXT: seto %al
907 ; SDAG-NEXT: movq %rdi, (%rdx)
910 ; FAST-LABEL: smuloi64_load2:
912 ; FAST-NEXT: imulq (%rsi), %rdi
913 ; FAST-NEXT: seto %al
914 ; FAST-NEXT: movq %rdi, (%rdx)
915 ; FAST-NEXT: andb $1, %al
916 ; FAST-NEXT: movzbl %al, %eax
918 %v2 = load i64, i64* %ptr2
919 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
920 %val = extractvalue {i64, i1} %t, 0
921 %obit = extractvalue {i64, i1} %t, 1
922 store i64 %val, i64* %res
926 define zeroext i1 @umuloi8_load(i8* %ptr1, i8 %v2, i8* %res) {
927 ; SDAG-LABEL: umuloi8_load:
929 ; SDAG-NEXT: movl %esi, %eax
930 ; SDAG-NEXT: ## kill: def $al killed $al killed $eax
931 ; SDAG-NEXT: mulb (%rdi)
932 ; SDAG-NEXT: seto %cl
933 ; SDAG-NEXT: movb %al, (%rdx)
934 ; SDAG-NEXT: movl %ecx, %eax
937 ; FAST-LABEL: umuloi8_load:
939 ; FAST-NEXT: movb (%rdi), %al
940 ; FAST-NEXT: mulb %sil
941 ; FAST-NEXT: seto %cl
942 ; FAST-NEXT: movb %al, (%rdx)
943 ; FAST-NEXT: andb $1, %cl
944 ; FAST-NEXT: movzbl %cl, %eax
946 %v1 = load i8, i8* %ptr1
947 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
948 %val = extractvalue {i8, i1} %t, 0
949 %obit = extractvalue {i8, i1} %t, 1
950 store i8 %val, i8* %res
954 define zeroext i1 @umuloi8_load2(i8 %v1, i8* %ptr2, i8* %res) {
955 ; SDAG-LABEL: umuloi8_load2:
957 ; SDAG-NEXT: movl %edi, %eax
958 ; SDAG-NEXT: ## kill: def $al killed $al killed $eax
959 ; SDAG-NEXT: mulb (%rsi)
960 ; SDAG-NEXT: seto %cl
961 ; SDAG-NEXT: movb %al, (%rdx)
962 ; SDAG-NEXT: movl %ecx, %eax
965 ; FAST-LABEL: umuloi8_load2:
967 ; FAST-NEXT: movl %edi, %eax
968 ; FAST-NEXT: ## kill: def $al killed $al killed $eax
969 ; FAST-NEXT: mulb (%rsi)
970 ; FAST-NEXT: seto %cl
971 ; FAST-NEXT: movb %al, (%rdx)
972 ; FAST-NEXT: andb $1, %cl
973 ; FAST-NEXT: movzbl %cl, %eax
975 %v2 = load i8, i8* %ptr2
976 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
977 %val = extractvalue {i8, i1} %t, 0
978 %obit = extractvalue {i8, i1} %t, 1
979 store i8 %val, i8* %res
983 define zeroext i1 @umuloi16_load(i16* %ptr1, i16 %v2, i16* %res) {
984 ; SDAG-LABEL: umuloi16_load:
986 ; SDAG-NEXT: movq %rdx, %rcx
987 ; SDAG-NEXT: movl %esi, %eax
988 ; SDAG-NEXT: ## kill: def $ax killed $ax killed $eax
989 ; SDAG-NEXT: mulw (%rdi)
990 ; SDAG-NEXT: seto %dl
991 ; SDAG-NEXT: movw %ax, (%rcx)
992 ; SDAG-NEXT: movl %edx, %eax
995 ; FAST-LABEL: umuloi16_load:
997 ; FAST-NEXT: movq %rdx, %rcx
998 ; FAST-NEXT: movzwl (%rdi), %eax
999 ; FAST-NEXT: mulw %si
1000 ; FAST-NEXT: seto %dl
1001 ; FAST-NEXT: movw %ax, (%rcx)
1002 ; FAST-NEXT: andb $1, %dl
1003 ; FAST-NEXT: movzbl %dl, %eax
1005 %v1 = load i16, i16* %ptr1
1006 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
1007 %val = extractvalue {i16, i1} %t, 0
1008 %obit = extractvalue {i16, i1} %t, 1
1009 store i16 %val, i16* %res
1013 define zeroext i1 @umuloi16_load2(i16 %v1, i16* %ptr2, i16* %res) {
1014 ; SDAG-LABEL: umuloi16_load2:
1016 ; SDAG-NEXT: movq %rdx, %rcx
1017 ; SDAG-NEXT: movl %edi, %eax
1018 ; SDAG-NEXT: ## kill: def $ax killed $ax killed $eax
1019 ; SDAG-NEXT: mulw (%rsi)
1020 ; SDAG-NEXT: seto %dl
1021 ; SDAG-NEXT: movw %ax, (%rcx)
1022 ; SDAG-NEXT: movl %edx, %eax
1025 ; FAST-LABEL: umuloi16_load2:
1027 ; FAST-NEXT: movq %rdx, %rcx
1028 ; FAST-NEXT: movl %edi, %eax
1029 ; FAST-NEXT: ## kill: def $ax killed $ax killed $eax
1030 ; FAST-NEXT: mulw (%rsi)
1031 ; FAST-NEXT: seto %dl
1032 ; FAST-NEXT: movw %ax, (%rcx)
1033 ; FAST-NEXT: andb $1, %dl
1034 ; FAST-NEXT: movzbl %dl, %eax
1036 %v2 = load i16, i16* %ptr2
1037 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
1038 %val = extractvalue {i16, i1} %t, 0
1039 %obit = extractvalue {i16, i1} %t, 1
1040 store i16 %val, i16* %res
1044 define zeroext i1 @umuloi32_load(i32* %ptr1, i32 %v2, i32* %res) {
1045 ; SDAG-LABEL: umuloi32_load:
1047 ; SDAG-NEXT: movq %rdx, %rcx
1048 ; SDAG-NEXT: movl %esi, %eax
1049 ; SDAG-NEXT: mull (%rdi)
1050 ; SDAG-NEXT: seto %dl
1051 ; SDAG-NEXT: movl %eax, (%rcx)
1052 ; SDAG-NEXT: movl %edx, %eax
1055 ; FAST-LABEL: umuloi32_load:
1057 ; FAST-NEXT: movq %rdx, %rcx
1058 ; FAST-NEXT: movl (%rdi), %eax
1059 ; FAST-NEXT: mull %esi
1060 ; FAST-NEXT: seto %dl
1061 ; FAST-NEXT: movl %eax, (%rcx)
1062 ; FAST-NEXT: andb $1, %dl
1063 ; FAST-NEXT: movzbl %dl, %eax
1065 %v1 = load i32, i32* %ptr1
1066 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
1067 %val = extractvalue {i32, i1} %t, 0
1068 %obit = extractvalue {i32, i1} %t, 1
1069 store i32 %val, i32* %res
1073 define zeroext i1 @umuloi32_load2(i32 %v1, i32* %ptr2, i32* %res) {
1074 ; SDAG-LABEL: umuloi32_load2:
1076 ; SDAG-NEXT: movq %rdx, %rcx
1077 ; SDAG-NEXT: movl %edi, %eax
1078 ; SDAG-NEXT: mull (%rsi)
1079 ; SDAG-NEXT: seto %dl
1080 ; SDAG-NEXT: movl %eax, (%rcx)
1081 ; SDAG-NEXT: movl %edx, %eax
1084 ; FAST-LABEL: umuloi32_load2:
1086 ; FAST-NEXT: movq %rdx, %rcx
1087 ; FAST-NEXT: movl %edi, %eax
1088 ; FAST-NEXT: mull (%rsi)
1089 ; FAST-NEXT: seto %dl
1090 ; FAST-NEXT: movl %eax, (%rcx)
1091 ; FAST-NEXT: andb $1, %dl
1092 ; FAST-NEXT: movzbl %dl, %eax
1094 %v2 = load i32, i32* %ptr2
1095 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
1096 %val = extractvalue {i32, i1} %t, 0
1097 %obit = extractvalue {i32, i1} %t, 1
1098 store i32 %val, i32* %res
1102 define zeroext i1 @umuloi64_load(i64* %ptr1, i64 %v2, i64* %res) {
1103 ; SDAG-LABEL: umuloi64_load:
1105 ; SDAG-NEXT: movq %rdx, %rcx
1106 ; SDAG-NEXT: movq %rsi, %rax
1107 ; SDAG-NEXT: mulq (%rdi)
1108 ; SDAG-NEXT: seto %dl
1109 ; SDAG-NEXT: movq %rax, (%rcx)
1110 ; SDAG-NEXT: movl %edx, %eax
1113 ; FAST-LABEL: umuloi64_load:
1115 ; FAST-NEXT: movq %rdx, %rcx
1116 ; FAST-NEXT: movq (%rdi), %rax
1117 ; FAST-NEXT: mulq %rsi
1118 ; FAST-NEXT: seto %dl
1119 ; FAST-NEXT: movq %rax, (%rcx)
1120 ; FAST-NEXT: andb $1, %dl
1121 ; FAST-NEXT: movzbl %dl, %eax
1123 %v1 = load i64, i64* %ptr1
1124 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
1125 %val = extractvalue {i64, i1} %t, 0
1126 %obit = extractvalue {i64, i1} %t, 1
1127 store i64 %val, i64* %res
1131 define zeroext i1 @umuloi64_load2(i64 %v1, i64* %ptr2, i64* %res) {
1132 ; SDAG-LABEL: umuloi64_load2:
1134 ; SDAG-NEXT: movq %rdx, %rcx
1135 ; SDAG-NEXT: movq %rdi, %rax
1136 ; SDAG-NEXT: mulq (%rsi)
1137 ; SDAG-NEXT: seto %dl
1138 ; SDAG-NEXT: movq %rax, (%rcx)
1139 ; SDAG-NEXT: movl %edx, %eax
1142 ; FAST-LABEL: umuloi64_load2:
1144 ; FAST-NEXT: movq %rdx, %rcx
1145 ; FAST-NEXT: movq %rdi, %rax
1146 ; FAST-NEXT: mulq (%rsi)
1147 ; FAST-NEXT: seto %dl
1148 ; FAST-NEXT: movq %rax, (%rcx)
1149 ; FAST-NEXT: andb $1, %dl
1150 ; FAST-NEXT: movzbl %dl, %eax
1152 %v2 = load i64, i64* %ptr2
1153 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
1154 %val = extractvalue {i64, i1} %t, 0
1155 %obit = extractvalue {i64, i1} %t, 1
1156 store i64 %val, i64* %res
1160 declare {i8, i1} @llvm.smul.with.overflow.i8 (i8, i8 ) nounwind readnone
1161 declare {i16, i1} @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone
1162 declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
1163 declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
1164 declare {i8, i1} @llvm.umul.with.overflow.i8 (i8, i8 ) nounwind readnone
1165 declare {i16, i1} @llvm.umul.with.overflow.i16(i16, i16) nounwind readnone
1166 declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
1167 declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone
1169 !0 = !{!"branch_weights", i32 0, i32 2147483647}