1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=x86_64-darwin-unknown < %s | FileCheck %s --check-prefix=SDAG
3; RUN: llc -mtriple=x86_64-darwin-unknown -fast-isel -fast-isel-abort=1 < %s | FileCheck %s --check-prefix=FAST
4; RUN: llc -mtriple=x86_64-darwin-unknown -mcpu=knl < %s | FileCheck %s --check-prefix=KNL
5
6define {i64, i1} @t1() nounwind {
7; SDAG-LABEL: t1:
8; SDAG:       ## BB#0:
9; SDAG-NEXT:    movl $8, %ecx
10; SDAG-NEXT:    movl $9, %eax
11; SDAG-NEXT:    mulq %rcx
12; SDAG-NEXT:    seto %dl
13; SDAG-NEXT:    retq
14;
15; FAST-LABEL: t1:
16; FAST:       ## BB#0:
17; FAST-NEXT:    movl $8, %ecx
18; FAST-NEXT:    movl $9, %eax
19; FAST-NEXT:    mulq %rcx
20; FAST-NEXT:    seto %dl
21; FAST-NEXT:    retq
22;
23; KNL-LABEL: t1:
24; KNL:       ## BB#0:
25; KNL-NEXT:    movl $8, %ecx
26; KNL-NEXT:    movl $9, %eax
27; KNL-NEXT:    mulq %rcx
28; KNL-NEXT:    seto %dl
29; KNL-NEXT:    retq
30  %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 8)
31  ret {i64, i1} %1
32}
33
34define {i64, i1} @t2() nounwind {
35; SDAG-LABEL: t2:
36; SDAG:       ## BB#0:
37; SDAG-NEXT:    xorl %ecx, %ecx
38; SDAG-NEXT:    movl $9, %eax
39; SDAG-NEXT:    mulq %rcx
40; SDAG-NEXT:    seto %dl
41; SDAG-NEXT:    retq
42;
43; FAST-LABEL: t2:
44; FAST:       ## BB#0:
45; FAST-NEXT:    xorl %ecx, %ecx
46; FAST-NEXT:    movl $9, %eax
47; FAST-NEXT:    mulq %rcx
48; FAST-NEXT:    seto %dl
49; FAST-NEXT:    retq
50;
51; KNL-LABEL: t2:
52; KNL:       ## BB#0:
53; KNL-NEXT:    xorl %ecx, %ecx
54; KNL-NEXT:    movl $9, %eax
55; KNL-NEXT:    mulq %rcx
56; KNL-NEXT:    seto %dl
57; KNL-NEXT:    retq
58  %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 0)
59  ret {i64, i1} %1
60}
61
62define {i64, i1} @t3() nounwind {
63; SDAG-LABEL: t3:
64; SDAG:       ## BB#0:
65; SDAG-NEXT:    movq $-1, %rcx
66; SDAG-NEXT:    movl $9, %eax
67; SDAG-NEXT:    mulq %rcx
68; SDAG-NEXT:    seto %dl
69; SDAG-NEXT:    retq
70;
71; FAST-LABEL: t3:
72; FAST:       ## BB#0:
73; FAST-NEXT:    movq $-1, %rcx
74; FAST-NEXT:    movl $9, %eax
75; FAST-NEXT:    mulq %rcx
76; FAST-NEXT:    seto %dl
77; FAST-NEXT:    retq
78;
79; KNL-LABEL: t3:
80; KNL:       ## BB#0:
81; KNL-NEXT:    movq $-1, %rcx
82; KNL-NEXT:    movl $9, %eax
83; KNL-NEXT:    mulq %rcx
84; KNL-NEXT:    seto %dl
85; KNL-NEXT:    retq
86  %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 -1)
87  ret {i64, i1} %1
88}
89
90; SMULO
91define zeroext i1 @smuloi8(i8 %v1, i8 %v2, i8* %res) {
92; SDAG-LABEL: smuloi8:
93; SDAG:       ## BB#0:
94; SDAG-NEXT:    movl %edi, %eax
95; SDAG-NEXT:    imulb %sil
96; SDAG-NEXT:    seto %cl
97; SDAG-NEXT:    movb %al, (%rdx)
98; SDAG-NEXT:    movl %ecx, %eax
99; SDAG-NEXT:    retq
100;
101; FAST-LABEL: smuloi8:
102; FAST:       ## BB#0:
103; FAST-NEXT:    movl %edi, %eax
104; FAST-NEXT:    imulb %sil
105; FAST-NEXT:    seto %cl
106; FAST-NEXT:    movb %al, (%rdx)
107; FAST-NEXT:    andb $1, %cl
108; FAST-NEXT:    movzbl %cl, %eax
109; FAST-NEXT:    retq
110;
111; KNL-LABEL: smuloi8:
112; KNL:       ## BB#0:
113; KNL-NEXT:    movl %edi, %eax
114; KNL-NEXT:    imulb %sil
115; KNL-NEXT:    seto %cl
116; KNL-NEXT:    movb %al, (%rdx)
117; KNL-NEXT:    movl %ecx, %eax
118; KNL-NEXT:    retq
119  %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
120  %val = extractvalue {i8, i1} %t, 0
121  %obit = extractvalue {i8, i1} %t, 1
122  store i8 %val, i8* %res
123  ret i1 %obit
124}
125
126define zeroext i1 @smuloi16(i16 %v1, i16 %v2, i16* %res) {
127; SDAG-LABEL: smuloi16:
128; SDAG:       ## BB#0:
129; SDAG-NEXT:    imulw %si, %di
130; SDAG-NEXT:    seto %al
131; SDAG-NEXT:    movw %di, (%rdx)
132; SDAG-NEXT:    retq
133;
134; FAST-LABEL: smuloi16:
135; FAST:       ## BB#0:
136; FAST-NEXT:    imulw %si, %di
137; FAST-NEXT:    seto %al
138; FAST-NEXT:    movw %di, (%rdx)
139; FAST-NEXT:    andb $1, %al
140; FAST-NEXT:    movzbl %al, %eax
141; FAST-NEXT:    retq
142;
143; KNL-LABEL: smuloi16:
144; KNL:       ## BB#0:
145; KNL-NEXT:    imulw %si, %di
146; KNL-NEXT:    seto %al
147; KNL-NEXT:    movw %di, (%rdx)
148; KNL-NEXT:    retq
149  %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
150  %val = extractvalue {i16, i1} %t, 0
151  %obit = extractvalue {i16, i1} %t, 1
152  store i16 %val, i16* %res
153  ret i1 %obit
154}
155
156define zeroext i1 @smuloi32(i32 %v1, i32 %v2, i32* %res) {
157; SDAG-LABEL: smuloi32:
158; SDAG:       ## BB#0:
159; SDAG-NEXT:    imull %esi, %edi
160; SDAG-NEXT:    seto %al
161; SDAG-NEXT:    movl %edi, (%rdx)
162; SDAG-NEXT:    retq
163;
164; FAST-LABEL: smuloi32:
165; FAST:       ## BB#0:
166; FAST-NEXT:    imull %esi, %edi
167; FAST-NEXT:    seto %al
168; FAST-NEXT:    movl %edi, (%rdx)
169; FAST-NEXT:    andb $1, %al
170; FAST-NEXT:    movzbl %al, %eax
171; FAST-NEXT:    retq
172;
173; KNL-LABEL: smuloi32:
174; KNL:       ## BB#0:
175; KNL-NEXT:    imull %esi, %edi
176; KNL-NEXT:    seto %al
177; KNL-NEXT:    movl %edi, (%rdx)
178; KNL-NEXT:    retq
179  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
180  %val = extractvalue {i32, i1} %t, 0
181  %obit = extractvalue {i32, i1} %t, 1
182  store i32 %val, i32* %res
183  ret i1 %obit
184}
185
186define zeroext i1 @smuloi64(i64 %v1, i64 %v2, i64* %res) {
187; SDAG-LABEL: smuloi64:
188; SDAG:       ## BB#0:
189; SDAG-NEXT:    imulq %rsi, %rdi
190; SDAG-NEXT:    seto %al
191; SDAG-NEXT:    movq %rdi, (%rdx)
192; SDAG-NEXT:    retq
193;
194; FAST-LABEL: smuloi64:
195; FAST:       ## BB#0:
196; FAST-NEXT:    imulq %rsi, %rdi
197; FAST-NEXT:    seto %al
198; FAST-NEXT:    movq %rdi, (%rdx)
199; FAST-NEXT:    andb $1, %al
200; FAST-NEXT:    movzbl %al, %eax
201; FAST-NEXT:    retq
202;
203; KNL-LABEL: smuloi64:
204; KNL:       ## BB#0:
205; KNL-NEXT:    imulq %rsi, %rdi
206; KNL-NEXT:    seto %al
207; KNL-NEXT:    movq %rdi, (%rdx)
208; KNL-NEXT:    retq
209  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
210  %val = extractvalue {i64, i1} %t, 0
211  %obit = extractvalue {i64, i1} %t, 1
212  store i64 %val, i64* %res
213  ret i1 %obit
214}
215
216; UMULO
217define zeroext i1 @umuloi8(i8 %v1, i8 %v2, i8* %res) {
218; SDAG-LABEL: umuloi8:
219; SDAG:       ## BB#0:
220; SDAG-NEXT:    movl %edi, %eax
221; SDAG-NEXT:    mulb %sil
222; SDAG-NEXT:    seto %cl
223; SDAG-NEXT:    movb %al, (%rdx)
224; SDAG-NEXT:    movl %ecx, %eax
225; SDAG-NEXT:    retq
226;
227; FAST-LABEL: umuloi8:
228; FAST:       ## BB#0:
229; FAST-NEXT:    movl %edi, %eax
230; FAST-NEXT:    mulb %sil
231; FAST-NEXT:    seto %cl
232; FAST-NEXT:    movb %al, (%rdx)
233; FAST-NEXT:    andb $1, %cl
234; FAST-NEXT:    movzbl %cl, %eax
235; FAST-NEXT:    retq
236;
237; KNL-LABEL: umuloi8:
238; KNL:       ## BB#0:
239; KNL-NEXT:    movl %edi, %eax
240; KNL-NEXT:    mulb %sil
241; KNL-NEXT:    seto %cl
242; KNL-NEXT:    movb %al, (%rdx)
243; KNL-NEXT:    movl %ecx, %eax
244; KNL-NEXT:    retq
245  %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
246  %val = extractvalue {i8, i1} %t, 0
247  %obit = extractvalue {i8, i1} %t, 1
248  store i8 %val, i8* %res
249  ret i1 %obit
250}
251
252define zeroext i1 @umuloi16(i16 %v1, i16 %v2, i16* %res) {
253; SDAG-LABEL: umuloi16:
254; SDAG:       ## BB#0:
255; SDAG-NEXT:    movq %rdx, %rcx
256; SDAG-NEXT:    movl %edi, %eax
257; SDAG-NEXT:    mulw %si
258; SDAG-NEXT:    seto %dl
259; SDAG-NEXT:    movw %ax, (%rcx)
260; SDAG-NEXT:    movl %edx, %eax
261; SDAG-NEXT:    retq
262;
263; FAST-LABEL: umuloi16:
264; FAST:       ## BB#0:
265; FAST-NEXT:    movq %rdx, %rcx
266; FAST-NEXT:    movl %edi, %eax
267; FAST-NEXT:    mulw %si
268; FAST-NEXT:    seto %dl
269; FAST-NEXT:    movw %ax, (%rcx)
270; FAST-NEXT:    andb $1, %dl
271; FAST-NEXT:    movzbl %dl, %eax
272; FAST-NEXT:    retq
273;
274; KNL-LABEL: umuloi16:
275; KNL:       ## BB#0:
276; KNL-NEXT:    movq %rdx, %rcx
277; KNL-NEXT:    movl %edi, %eax
278; KNL-NEXT:    mulw %si
279; KNL-NEXT:    seto %dl
280; KNL-NEXT:    movw %ax, (%rcx)
281; KNL-NEXT:    movl %edx, %eax
282; KNL-NEXT:    retq
283  %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
284  %val = extractvalue {i16, i1} %t, 0
285  %obit = extractvalue {i16, i1} %t, 1
286  store i16 %val, i16* %res
287  ret i1 %obit
288}
289
290define zeroext i1 @umuloi32(i32 %v1, i32 %v2, i32* %res) {
291; SDAG-LABEL: umuloi32:
292; SDAG:       ## BB#0:
293; SDAG-NEXT:    movq %rdx, %rcx
294; SDAG-NEXT:    movl %edi, %eax
295; SDAG-NEXT:    mull %esi
296; SDAG-NEXT:    seto %dl
297; SDAG-NEXT:    movl %eax, (%rcx)
298; SDAG-NEXT:    movl %edx, %eax
299; SDAG-NEXT:    retq
300;
301; FAST-LABEL: umuloi32:
302; FAST:       ## BB#0:
303; FAST-NEXT:    movq %rdx, %rcx
304; FAST-NEXT:    movl %edi, %eax
305; FAST-NEXT:    mull %esi
306; FAST-NEXT:    seto %dl
307; FAST-NEXT:    movl %eax, (%rcx)
308; FAST-NEXT:    andb $1, %dl
309; FAST-NEXT:    movzbl %dl, %eax
310; FAST-NEXT:    retq
311;
312; KNL-LABEL: umuloi32:
313; KNL:       ## BB#0:
314; KNL-NEXT:    movq %rdx, %rcx
315; KNL-NEXT:    movl %edi, %eax
316; KNL-NEXT:    mull %esi
317; KNL-NEXT:    seto %dl
318; KNL-NEXT:    movl %eax, (%rcx)
319; KNL-NEXT:    movl %edx, %eax
320; KNL-NEXT:    retq
321  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
322  %val = extractvalue {i32, i1} %t, 0
323  %obit = extractvalue {i32, i1} %t, 1
324  store i32 %val, i32* %res
325  ret i1 %obit
326}
327
328define zeroext i1 @umuloi64(i64 %v1, i64 %v2, i64* %res) {
329; SDAG-LABEL: umuloi64:
330; SDAG:       ## BB#0:
331; SDAG-NEXT:    movq %rdx, %rcx
332; SDAG-NEXT:    movq %rdi, %rax
333; SDAG-NEXT:    mulq %rsi
334; SDAG-NEXT:    seto %dl
335; SDAG-NEXT:    movq %rax, (%rcx)
336; SDAG-NEXT:    movl %edx, %eax
337; SDAG-NEXT:    retq
338;
339; FAST-LABEL: umuloi64:
340; FAST:       ## BB#0:
341; FAST-NEXT:    movq %rdx, %rcx
342; FAST-NEXT:    movq %rdi, %rax
343; FAST-NEXT:    mulq %rsi
344; FAST-NEXT:    seto %dl
345; FAST-NEXT:    movq %rax, (%rcx)
346; FAST-NEXT:    andb $1, %dl
347; FAST-NEXT:    movzbl %dl, %eax
348; FAST-NEXT:    retq
349;
350; KNL-LABEL: umuloi64:
351; KNL:       ## BB#0:
352; KNL-NEXT:    movq %rdx, %rcx
353; KNL-NEXT:    movq %rdi, %rax
354; KNL-NEXT:    mulq %rsi
355; KNL-NEXT:    seto %dl
356; KNL-NEXT:    movq %rax, (%rcx)
357; KNL-NEXT:    movl %edx, %eax
358; KNL-NEXT:    retq
359  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
360  %val = extractvalue {i64, i1} %t, 0
361  %obit = extractvalue {i64, i1} %t, 1
362  store i64 %val, i64* %res
363  ret i1 %obit
364}
365
366;
367; Check the use of the overflow bit in combination with a select instruction.
368;
369define i32 @smuloselecti32(i32 %v1, i32 %v2) {
370; SDAG-LABEL: smuloselecti32:
371; SDAG:       ## BB#0:
372; SDAG-NEXT:    movl %edi, %eax
373; SDAG-NEXT:    imull %esi, %eax
374; SDAG-NEXT:    cmovol %edi, %esi
375; SDAG-NEXT:    movl %esi, %eax
376; SDAG-NEXT:    retq
377;
378; FAST-LABEL: smuloselecti32:
379; FAST:       ## BB#0:
380; FAST-NEXT:    movl %edi, %eax
381; FAST-NEXT:    imull %esi, %eax
382; FAST-NEXT:    cmovol %edi, %esi
383; FAST-NEXT:    movl %esi, %eax
384; FAST-NEXT:    retq
385;
386; KNL-LABEL: smuloselecti32:
387; KNL:       ## BB#0:
388; KNL-NEXT:    movl %edi, %eax
389; KNL-NEXT:    imull %esi, %eax
390; KNL-NEXT:    cmovol %edi, %esi
391; KNL-NEXT:    movl %esi, %eax
392; KNL-NEXT:    retq
393  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
394  %obit = extractvalue {i32, i1} %t, 1
395  %ret = select i1 %obit, i32 %v1, i32 %v2
396  ret i32 %ret
397}
398
399define i64 @smuloselecti64(i64 %v1, i64 %v2) {
400; SDAG-LABEL: smuloselecti64:
401; SDAG:       ## BB#0:
402; SDAG-NEXT:    movq %rdi, %rax
403; SDAG-NEXT:    imulq %rsi, %rax
404; SDAG-NEXT:    cmovoq %rdi, %rsi
405; SDAG-NEXT:    movq %rsi, %rax
406; SDAG-NEXT:    retq
407;
408; FAST-LABEL: smuloselecti64:
409; FAST:       ## BB#0:
410; FAST-NEXT:    movq %rdi, %rax
411; FAST-NEXT:    imulq %rsi, %rax
412; FAST-NEXT:    cmovoq %rdi, %rsi
413; FAST-NEXT:    movq %rsi, %rax
414; FAST-NEXT:    retq
415;
416; KNL-LABEL: smuloselecti64:
417; KNL:       ## BB#0:
418; KNL-NEXT:    movq %rdi, %rax
419; KNL-NEXT:    imulq %rsi, %rax
420; KNL-NEXT:    cmovoq %rdi, %rsi
421; KNL-NEXT:    movq %rsi, %rax
422; KNL-NEXT:    retq
423  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
424  %obit = extractvalue {i64, i1} %t, 1
425  %ret = select i1 %obit, i64 %v1, i64 %v2
426  ret i64 %ret
427}
428
429define i32 @umuloselecti32(i32 %v1, i32 %v2) {
430; SDAG-LABEL: umuloselecti32:
431; SDAG:       ## BB#0:
432; SDAG-NEXT:    movl %edi, %eax
433; SDAG-NEXT:    mull %esi
434; SDAG-NEXT:    cmovol %edi, %esi
435; SDAG-NEXT:    movl %esi, %eax
436; SDAG-NEXT:    retq
437;
438; FAST-LABEL: umuloselecti32:
439; FAST:       ## BB#0:
440; FAST-NEXT:    movl %edi, %eax
441; FAST-NEXT:    mull %esi
442; FAST-NEXT:    cmovol %edi, %esi
443; FAST-NEXT:    movl %esi, %eax
444; FAST-NEXT:    retq
445;
446; KNL-LABEL: umuloselecti32:
447; KNL:       ## BB#0:
448; KNL-NEXT:    movl %edi, %eax
449; KNL-NEXT:    mull %esi
450; KNL-NEXT:    cmovol %edi, %esi
451; KNL-NEXT:    movl %esi, %eax
452; KNL-NEXT:    retq
453  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
454  %obit = extractvalue {i32, i1} %t, 1
455  %ret = select i1 %obit, i32 %v1, i32 %v2
456  ret i32 %ret
457}
458
459define i64 @umuloselecti64(i64 %v1, i64 %v2) {
460; SDAG-LABEL: umuloselecti64:
461; SDAG:       ## BB#0:
462; SDAG-NEXT:    movq %rdi, %rax
463; SDAG-NEXT:    mulq %rsi
464; SDAG-NEXT:    cmovoq %rdi, %rsi
465; SDAG-NEXT:    movq %rsi, %rax
466; SDAG-NEXT:    retq
467;
468; FAST-LABEL: umuloselecti64:
469; FAST:       ## BB#0:
470; FAST-NEXT:    movq %rdi, %rax
471; FAST-NEXT:    mulq %rsi
472; FAST-NEXT:    cmovoq %rdi, %rsi
473; FAST-NEXT:    movq %rsi, %rax
474; FAST-NEXT:    retq
475;
476; KNL-LABEL: umuloselecti64:
477; KNL:       ## BB#0:
478; KNL-NEXT:    movq %rdi, %rax
479; KNL-NEXT:    mulq %rsi
480; KNL-NEXT:    cmovoq %rdi, %rsi
481; KNL-NEXT:    movq %rsi, %rax
482; KNL-NEXT:    retq
483  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
484  %obit = extractvalue {i64, i1} %t, 1
485  %ret = select i1 %obit, i64 %v1, i64 %v2
486  ret i64 %ret
487}
488
489;
490; Check the use of the overflow bit in combination with a branch instruction.
491;
492define zeroext i1 @smulobri32(i32 %v1, i32 %v2) {
493; SDAG-LABEL: smulobri32:
494; SDAG:       ## BB#0:
495; SDAG-NEXT:    imull %esi, %edi
496; SDAG-NEXT:    jo LBB15_1
497; SDAG-NEXT:  ## BB#2: ## %continue
498; SDAG-NEXT:    movb $1, %al
499; SDAG-NEXT:    retq
500; SDAG-NEXT:  LBB15_1: ## %overflow
501; SDAG-NEXT:    xorl %eax, %eax
502; SDAG-NEXT:    retq
503;
504; FAST-LABEL: smulobri32:
505; FAST:       ## BB#0:
506; FAST-NEXT:    imull %esi, %edi
507; FAST-NEXT:    jo LBB15_1
508; FAST-NEXT:  ## BB#2: ## %continue
509; FAST-NEXT:    movb $1, %al
510; FAST-NEXT:    andb $1, %al
511; FAST-NEXT:    movzbl %al, %eax
512; FAST-NEXT:    retq
513; FAST-NEXT:  LBB15_1: ## %overflow
514; FAST-NEXT:    xorl %eax, %eax
515; FAST-NEXT:    andb $1, %al
516; FAST-NEXT:    movzbl %al, %eax
517; FAST-NEXT:    retq
518;
519; KNL-LABEL: smulobri32:
520; KNL:       ## BB#0:
521; KNL-NEXT:    imull %esi, %edi
522; KNL-NEXT:    jo LBB15_1
523; KNL-NEXT:  ## BB#2: ## %continue
524; KNL-NEXT:    movb $1, %al
525; KNL-NEXT:    retq
526; KNL-NEXT:  LBB15_1: ## %overflow
527; KNL-NEXT:    xorl %eax, %eax
528; KNL-NEXT:    retq
529  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
530  %val = extractvalue {i32, i1} %t, 0
531  %obit = extractvalue {i32, i1} %t, 1
532  br i1 %obit, label %overflow, label %continue, !prof !0
533
534overflow:
535  ret i1 false
536
537continue:
538  ret i1 true
539}
540
541define zeroext i1 @smulobri64(i64 %v1, i64 %v2) {
542; SDAG-LABEL: smulobri64:
543; SDAG:       ## BB#0:
544; SDAG-NEXT:    imulq %rsi, %rdi
545; SDAG-NEXT:    jo LBB16_1
546; SDAG-NEXT:  ## BB#2: ## %continue
547; SDAG-NEXT:    movb $1, %al
548; SDAG-NEXT:    retq
549; SDAG-NEXT:  LBB16_1: ## %overflow
550; SDAG-NEXT:    xorl %eax, %eax
551; SDAG-NEXT:    retq
552;
553; FAST-LABEL: smulobri64:
554; FAST:       ## BB#0:
555; FAST-NEXT:    imulq %rsi, %rdi
556; FAST-NEXT:    jo LBB16_1
557; FAST-NEXT:  ## BB#2: ## %continue
558; FAST-NEXT:    movb $1, %al
559; FAST-NEXT:    andb $1, %al
560; FAST-NEXT:    movzbl %al, %eax
561; FAST-NEXT:    retq
562; FAST-NEXT:  LBB16_1: ## %overflow
563; FAST-NEXT:    xorl %eax, %eax
564; FAST-NEXT:    andb $1, %al
565; FAST-NEXT:    movzbl %al, %eax
566; FAST-NEXT:    retq
567;
568; KNL-LABEL: smulobri64:
569; KNL:       ## BB#0:
570; KNL-NEXT:    imulq %rsi, %rdi
571; KNL-NEXT:    jo LBB16_1
572; KNL-NEXT:  ## BB#2: ## %continue
573; KNL-NEXT:    movb $1, %al
574; KNL-NEXT:    retq
575; KNL-NEXT:  LBB16_1: ## %overflow
576; KNL-NEXT:    xorl %eax, %eax
577; KNL-NEXT:    retq
578  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
579  %val = extractvalue {i64, i1} %t, 0
580  %obit = extractvalue {i64, i1} %t, 1
581  br i1 %obit, label %overflow, label %continue, !prof !0
582
583overflow:
584  ret i1 false
585
586continue:
587  ret i1 true
588}
589
590define zeroext i1 @umulobri32(i32 %v1, i32 %v2) {
591; SDAG-LABEL: umulobri32:
592; SDAG:       ## BB#0:
593; SDAG-NEXT:    movl %edi, %eax
594; SDAG-NEXT:    mull %esi
595; SDAG-NEXT:    jo LBB17_1
596; SDAG-NEXT:  ## BB#2: ## %continue
597; SDAG-NEXT:    movb $1, %al
598; SDAG-NEXT:    retq
599; SDAG-NEXT:  LBB17_1: ## %overflow
600; SDAG-NEXT:    xorl %eax, %eax
601; SDAG-NEXT:    retq
602;
603; FAST-LABEL: umulobri32:
604; FAST:       ## BB#0:
605; FAST-NEXT:    movl %edi, %eax
606; FAST-NEXT:    mull %esi
607; FAST-NEXT:    jo LBB17_1
608; FAST-NEXT:  ## BB#2: ## %continue
609; FAST-NEXT:    movb $1, %al
610; FAST-NEXT:    andb $1, %al
611; FAST-NEXT:    movzbl %al, %eax
612; FAST-NEXT:    retq
613; FAST-NEXT:  LBB17_1: ## %overflow
614; FAST-NEXT:    xorl %eax, %eax
615; FAST-NEXT:    andb $1, %al
616; FAST-NEXT:    movzbl %al, %eax
617; FAST-NEXT:    retq
618;
619; KNL-LABEL: umulobri32:
620; KNL:       ## BB#0:
621; KNL-NEXT:    movl %edi, %eax
622; KNL-NEXT:    mull %esi
623; KNL-NEXT:    jo LBB17_1
624; KNL-NEXT:  ## BB#2: ## %continue
625; KNL-NEXT:    movb $1, %al
626; KNL-NEXT:    retq
627; KNL-NEXT:  LBB17_1: ## %overflow
628; KNL-NEXT:    xorl %eax, %eax
629; KNL-NEXT:    retq
630  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
631  %val = extractvalue {i32, i1} %t, 0
632  %obit = extractvalue {i32, i1} %t, 1
633  br i1 %obit, label %overflow, label %continue, !prof !0
634
635overflow:
636  ret i1 false
637
638continue:
639  ret i1 true
640}
641
642define zeroext i1 @umulobri64(i64 %v1, i64 %v2) {
643; SDAG-LABEL: umulobri64:
644; SDAG:       ## BB#0:
645; SDAG-NEXT:    movq %rdi, %rax
646; SDAG-NEXT:    mulq %rsi
647; SDAG-NEXT:    jo LBB18_1
648; SDAG-NEXT:  ## BB#2: ## %continue
649; SDAG-NEXT:    movb $1, %al
650; SDAG-NEXT:    retq
651; SDAG-NEXT:  LBB18_1: ## %overflow
652; SDAG-NEXT:    xorl %eax, %eax
653; SDAG-NEXT:    retq
654;
655; FAST-LABEL: umulobri64:
656; FAST:       ## BB#0:
657; FAST-NEXT:    movq %rdi, %rax
658; FAST-NEXT:    mulq %rsi
659; FAST-NEXT:    jo LBB18_1
660; FAST-NEXT:  ## BB#2: ## %continue
661; FAST-NEXT:    movb $1, %al
662; FAST-NEXT:    andb $1, %al
663; FAST-NEXT:    movzbl %al, %eax
664; FAST-NEXT:    retq
665; FAST-NEXT:  LBB18_1: ## %overflow
666; FAST-NEXT:    xorl %eax, %eax
667; FAST-NEXT:    andb $1, %al
668; FAST-NEXT:    movzbl %al, %eax
669; FAST-NEXT:    retq
670;
671; KNL-LABEL: umulobri64:
672; KNL:       ## BB#0:
673; KNL-NEXT:    movq %rdi, %rax
674; KNL-NEXT:    mulq %rsi
675; KNL-NEXT:    jo LBB18_1
676; KNL-NEXT:  ## BB#2: ## %continue
677; KNL-NEXT:    movb $1, %al
678; KNL-NEXT:    retq
679; KNL-NEXT:  LBB18_1: ## %overflow
680; KNL-NEXT:    xorl %eax, %eax
681; KNL-NEXT:    retq
682  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
683  %val = extractvalue {i64, i1} %t, 0
684  %obit = extractvalue {i64, i1} %t, 1
685  br i1 %obit, label %overflow, label %continue, !prof !0
686
687overflow:
688  ret i1 false
689
690continue:
691  ret i1 true
692}
693
694define i1 @bug27873(i64 %c1, i1 %c2) {
695; SDAG-LABEL: bug27873:
696; SDAG:       ## BB#0:
697; SDAG-NEXT:    movl $160, %ecx
698; SDAG-NEXT:    movq %rdi, %rax
699; SDAG-NEXT:    mulq %rcx
700; SDAG-NEXT:    seto %al
701; SDAG-NEXT:    orb %sil, %al
702; SDAG-NEXT:    retq
703;
704; FAST-LABEL: bug27873:
705; FAST:       ## BB#0:
706; FAST-NEXT:    movl $160, %ecx
707; FAST-NEXT:    movq %rdi, %rax
708; FAST-NEXT:    mulq %rcx
709; FAST-NEXT:    seto %al
710; FAST-NEXT:    orb %sil, %al
711; FAST-NEXT:    retq
712;
713; KNL-LABEL: bug27873:
714; KNL:       ## BB#0:
715; KNL-NEXT:    andl $1, %esi
716; KNL-NEXT:    kmovw %esi, %k0
717; KNL-NEXT:    movl $160, %ecx
718; KNL-NEXT:    movq %rdi, %rax
719; KNL-NEXT:    mulq %rcx
720; KNL-NEXT:    seto %al
721; KNL-NEXT:    andl $1, %eax
722; KNL-NEXT:    kmovw %eax, %k1
723; KNL-NEXT:    korw %k1, %k0, %k0
724; KNL-NEXT:    kmovw %k0, %eax
725; KNL-NEXT:    ## kill: %AL<def> %AL<kill> %EAX<kill>
726; KNL-NEXT:    retq
727  %mul = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %c1, i64 160)
728  %mul.overflow = extractvalue { i64, i1 } %mul, 1
729  %x1 = or i1 %c2, %mul.overflow
730  ret i1 %x1
731}
732
733declare {i8,  i1} @llvm.smul.with.overflow.i8 (i8,  i8 ) nounwind readnone
734declare {i16, i1} @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone
735declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
736declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
737declare {i8,  i1} @llvm.umul.with.overflow.i8 (i8,  i8 ) nounwind readnone
738declare {i16, i1} @llvm.umul.with.overflow.i16(i16, i16) nounwind readnone
739declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
740declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone
741
742!0 = !{!"branch_weights", i32 0, i32 2147483647}
743