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
7
8define {i64, i1} @t1() nounwind {
9; CHECK-LABEL: t1:
10; CHECK:       # %bb.0:
11; CHECK-NEXT:    movl $72, %eax
12; CHECK-NEXT:    xorl %edx, %edx
13; CHECK-NEXT:    retq
14;
15; WIN32-LABEL: t1:
16; WIN32:       # %bb.0:
17; WIN32-NEXT:    movl $72, %eax
18; WIN32-NEXT:    xorl %edx, %edx
19; WIN32-NEXT:    xorl %ecx, %ecx
20; WIN32-NEXT:    retl
21  %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 8)
22  ret {i64, i1} %1
23}
24
25define {i64, i1} @t2() nounwind {
26; CHECK-LABEL: t2:
27; CHECK:       # %bb.0:
28; CHECK-NEXT:    xorl %eax, %eax
29; CHECK-NEXT:    xorl %edx, %edx
30; CHECK-NEXT:    retq
31;
32; WIN32-LABEL: t2:
33; WIN32:       # %bb.0:
34; WIN32-NEXT:    xorl %eax, %eax
35; WIN32-NEXT:    xorl %edx, %edx
36; WIN32-NEXT:    xorl %ecx, %ecx
37; WIN32-NEXT:    retl
38  %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 0)
39  ret {i64, i1} %1
40}
41
42define {i64, i1} @t3() nounwind {
43; CHECK-LABEL: t3:
44; CHECK:       # %bb.0:
45; CHECK-NEXT:    movq $-9, %rax
46; CHECK-NEXT:    movb $1, %dl
47; CHECK-NEXT:    retq
48;
49; WIN32-LABEL: t3:
50; WIN32:       # %bb.0:
51; WIN32-NEXT:    movl $-9, %eax
52; WIN32-NEXT:    movl $-1, %edx
53; WIN32-NEXT:    movb $1, %cl
54; WIN32-NEXT:    retl
55  %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 -1)
56  ret {i64, i1} %1
57}
58
59; SMULO
60define zeroext i1 @smuloi8(i8 %v1, i8 %v2, i8* %res) {
61; SDAG-LABEL: smuloi8:
62; SDAG:       # %bb.0:
63; SDAG-NEXT:    movl %edi, %eax
64; SDAG-NEXT:    # kill: def $al killed $al killed $eax
65; SDAG-NEXT:    imulb %sil
66; SDAG-NEXT:    seto %cl
67; SDAG-NEXT:    movb %al, (%rdx)
68; SDAG-NEXT:    movl %ecx, %eax
69; SDAG-NEXT:    retq
70;
71; FAST-LABEL: smuloi8:
72; FAST:       # %bb.0:
73; FAST-NEXT:    movl %edi, %eax
74; FAST-NEXT:    # kill: def $al killed $al killed $eax
75; FAST-NEXT:    imulb %sil
76; FAST-NEXT:    seto %cl
77; FAST-NEXT:    movb %al, (%rdx)
78; FAST-NEXT:    andb $1, %cl
79; FAST-NEXT:    movzbl %cl, %eax
80; FAST-NEXT:    retq
81;
82; WIN64-LABEL: smuloi8:
83; WIN64:       # %bb.0:
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
89; WIN64-NEXT:    retq
90;
91; WIN32-LABEL: smuloi8:
92; WIN32:       # %bb.0:
93; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edx
94; WIN32-NEXT:    movb {{[0-9]+}}(%esp), %al
95; WIN32-NEXT:    imulb {{[0-9]+}}(%esp)
96; WIN32-NEXT:    seto %cl
97; WIN32-NEXT:    movb %al, (%edx)
98; WIN32-NEXT:    movl %ecx, %eax
99; WIN32-NEXT:    retl
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, i8* %res
104  ret i1 %obit
105}
106
107define zeroext i1 @smuloi16(i16 %v1, i16 %v2, i16* %res) {
108; SDAG-LABEL: smuloi16:
109; SDAG:       # %bb.0:
110; SDAG-NEXT:    imulw %si, %di
111; SDAG-NEXT:    seto %al
112; SDAG-NEXT:    movw %di, (%rdx)
113; SDAG-NEXT:    retq
114;
115; FAST-LABEL: smuloi16:
116; FAST:       # %bb.0:
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
122; FAST-NEXT:    retq
123;
124; WIN64-LABEL: smuloi16:
125; WIN64:       # %bb.0:
126; WIN64-NEXT:    imulw %dx, %cx
127; WIN64-NEXT:    seto %al
128; WIN64-NEXT:    movw %cx, (%r8)
129; WIN64-NEXT:    retq
130;
131; WIN32-LABEL: smuloi16:
132; WIN32:       # %bb.0:
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)
138; WIN32-NEXT:    retl
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, i16* %res
143  ret i1 %obit
144}
145
146define zeroext i1 @smuloi32(i32 %v1, i32 %v2, i32* %res) {
147; SDAG-LABEL: smuloi32:
148; SDAG:       # %bb.0:
149; SDAG-NEXT:    imull %esi, %edi
150; SDAG-NEXT:    seto %al
151; SDAG-NEXT:    movl %edi, (%rdx)
152; SDAG-NEXT:    retq
153;
154; FAST-LABEL: smuloi32:
155; FAST:       # %bb.0:
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
161; FAST-NEXT:    retq
162;
163; WIN64-LABEL: smuloi32:
164; WIN64:       # %bb.0:
165; WIN64-NEXT:    imull %edx, %ecx
166; WIN64-NEXT:    seto %al
167; WIN64-NEXT:    movl %ecx, (%r8)
168; WIN64-NEXT:    retq
169;
170; WIN32-LABEL: smuloi32:
171; WIN32:       # %bb.0:
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)
177; WIN32-NEXT:    retl
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, i32* %res
182  ret i1 %obit
183}
184
185define zeroext i1 @smuloi64(i64 %v1, i64 %v2, i64* %res) {
186; SDAG-LABEL: smuloi64:
187; SDAG:       # %bb.0:
188; SDAG-NEXT:    imulq %rsi, %rdi
189; SDAG-NEXT:    seto %al
190; SDAG-NEXT:    movq %rdi, (%rdx)
191; SDAG-NEXT:    retq
192;
193; FAST-LABEL: smuloi64:
194; FAST:       # %bb.0:
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
200; FAST-NEXT:    retq
201;
202; WIN64-LABEL: smuloi64:
203; WIN64:       # %bb.0:
204; WIN64-NEXT:    imulq %rdx, %rcx
205; WIN64-NEXT:    seto %al
206; WIN64-NEXT:    movq %rcx, (%r8)
207; WIN64-NEXT:    retq
208;
209; WIN32-LABEL: smuloi64:
210; WIN32:       # %bb.0:
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), %ebp
218; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
219; WIN32-NEXT:    movl %ecx, %edi
220; WIN32-NEXT:    sarl $31, %edi
221; WIN32-NEXT:    movl %eax, %esi
222; WIN32-NEXT:    imull %edi, %esi
223; WIN32-NEXT:    mull %edi
224; WIN32-NEXT:    movl %eax, %ebx
225; WIN32-NEXT:    addl %esi, %edx
226; WIN32-NEXT:    movl %ebp, %esi
227; WIN32-NEXT:    imull %ebp, %edi
228; WIN32-NEXT:    addl %edx, %edi
229; WIN32-NEXT:    sarl $31, %esi
230; WIN32-NEXT:    movl %esi, %ebp
231; WIN32-NEXT:    imull %ecx, %ebp
232; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
233; WIN32-NEXT:    movl %esi, %eax
234; WIN32-NEXT:    mull %ecx
235; WIN32-NEXT:    addl %ebp, %edx
236; WIN32-NEXT:    imull %ecx, %esi
237; WIN32-NEXT:    addl %edx, %esi
238; WIN32-NEXT:    addl %ebx, %eax
239; WIN32-NEXT:    movl %eax, (%esp) # 4-byte Spill
240; WIN32-NEXT:    adcl %edi, %esi
241; WIN32-NEXT:    movl %ecx, %eax
242; WIN32-NEXT:    movl %ecx, %edi
243; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
244; WIN32-NEXT:    mull %ecx
245; WIN32-NEXT:    movl %edx, %ebp
246; WIN32-NEXT:    movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
247; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
248; WIN32-NEXT:    mull %ecx
249; WIN32-NEXT:    movl %edx, %ebx
250; WIN32-NEXT:    movl %eax, %ecx
251; WIN32-NEXT:    addl %ebp, %ecx
252; WIN32-NEXT:    adcl $0, %ebx
253; WIN32-NEXT:    movl %edi, %eax
254; WIN32-NEXT:    mull {{[0-9]+}}(%esp)
255; WIN32-NEXT:    movl %edx, %edi
256; WIN32-NEXT:    movl %eax, %ebp
257; WIN32-NEXT:    addl %ecx, %ebp
258; WIN32-NEXT:    adcl %ebx, %edi
259; WIN32-NEXT:    setb %cl
260; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
261; WIN32-NEXT:    mull {{[0-9]+}}(%esp)
262; WIN32-NEXT:    addl %edi, %eax
263; WIN32-NEXT:    movzbl %cl, %ecx
264; WIN32-NEXT:    adcl %ecx, %edx
265; WIN32-NEXT:    addl (%esp), %eax # 4-byte Folded Reload
266; WIN32-NEXT:    adcl %esi, %edx
267; WIN32-NEXT:    movl %ebp, %ecx
268; WIN32-NEXT:    sarl $31, %ecx
269; WIN32-NEXT:    xorl %ecx, %edx
270; WIN32-NEXT:    xorl %eax, %ecx
271; WIN32-NEXT:    orl %edx, %ecx
272; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
273; WIN32-NEXT:    movl %ebp, 4(%eax)
274; WIN32-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
275; WIN32-NEXT:    movl %ecx, (%eax)
276; WIN32-NEXT:    setne %al
277; WIN32-NEXT:    addl $8, %esp
278; WIN32-NEXT:    popl %esi
279; WIN32-NEXT:    popl %edi
280; WIN32-NEXT:    popl %ebx
281; WIN32-NEXT:    popl %ebp
282; WIN32-NEXT:    retl
283  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
284  %val = extractvalue {i64, i1} %t, 0
285  %obit = extractvalue {i64, i1} %t, 1
286  store i64 %val, i64* %res
287  ret i1 %obit
288}
289
290; UMULO
291define zeroext i1 @umuloi8(i8 %v1, i8 %v2, i8* %res) {
292; SDAG-LABEL: umuloi8:
293; SDAG:       # %bb.0:
294; SDAG-NEXT:    movl %edi, %eax
295; SDAG-NEXT:    # kill: def $al killed $al killed $eax
296; SDAG-NEXT:    mulb %sil
297; SDAG-NEXT:    seto %cl
298; SDAG-NEXT:    movb %al, (%rdx)
299; SDAG-NEXT:    movl %ecx, %eax
300; SDAG-NEXT:    retq
301;
302; FAST-LABEL: umuloi8:
303; FAST:       # %bb.0:
304; FAST-NEXT:    movl %edi, %eax
305; FAST-NEXT:    # kill: def $al killed $al killed $eax
306; FAST-NEXT:    mulb %sil
307; FAST-NEXT:    seto %cl
308; FAST-NEXT:    movb %al, (%rdx)
309; FAST-NEXT:    andb $1, %cl
310; FAST-NEXT:    movzbl %cl, %eax
311; FAST-NEXT:    retq
312;
313; WIN64-LABEL: umuloi8:
314; WIN64:       # %bb.0:
315; WIN64-NEXT:    movl %ecx, %eax
316; WIN64-NEXT:    mulb %dl
317; WIN64-NEXT:    seto %cl
318; WIN64-NEXT:    movb %al, (%r8)
319; WIN64-NEXT:    movl %ecx, %eax
320; WIN64-NEXT:    retq
321;
322; WIN32-LABEL: umuloi8:
323; WIN32:       # %bb.0:
324; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edx
325; WIN32-NEXT:    movb {{[0-9]+}}(%esp), %al
326; WIN32-NEXT:    mulb {{[0-9]+}}(%esp)
327; WIN32-NEXT:    seto %cl
328; WIN32-NEXT:    movb %al, (%edx)
329; WIN32-NEXT:    movl %ecx, %eax
330; WIN32-NEXT:    retl
331  %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
332  %val = extractvalue {i8, i1} %t, 0
333  %obit = extractvalue {i8, i1} %t, 1
334  store i8 %val, i8* %res
335  ret i1 %obit
336}
337
338define zeroext i1 @umuloi16(i16 %v1, i16 %v2, i16* %res) {
339; SDAG-LABEL: umuloi16:
340; SDAG:       # %bb.0:
341; SDAG-NEXT:    movq %rdx, %rcx
342; SDAG-NEXT:    movl %edi, %eax
343; SDAG-NEXT:    # kill: def $ax killed $ax killed $eax
344; SDAG-NEXT:    mulw %si
345; SDAG-NEXT:    seto %dl
346; SDAG-NEXT:    movw %ax, (%rcx)
347; SDAG-NEXT:    movl %edx, %eax
348; SDAG-NEXT:    retq
349;
350; FAST-LABEL: umuloi16:
351; FAST:       # %bb.0:
352; FAST-NEXT:    movq %rdx, %rcx
353; FAST-NEXT:    movl %edi, %eax
354; FAST-NEXT:    # kill: def $ax killed $ax killed $eax
355; FAST-NEXT:    mulw %si
356; FAST-NEXT:    seto %dl
357; FAST-NEXT:    movw %ax, (%rcx)
358; FAST-NEXT:    andb $1, %dl
359; FAST-NEXT:    movzbl %dl, %eax
360; FAST-NEXT:    retq
361;
362; WIN64-LABEL: umuloi16:
363; WIN64:       # %bb.0:
364; WIN64-NEXT:    movl %ecx, %eax
365; WIN64-NEXT:    mulw %dx
366; WIN64-NEXT:    seto %cl
367; WIN64-NEXT:    movw %ax, (%r8)
368; WIN64-NEXT:    movl %ecx, %eax
369; WIN64-NEXT:    retq
370;
371; WIN32-LABEL: umuloi16:
372; WIN32:       # %bb.0:
373; WIN32-NEXT:    pushl %esi
374; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
375; WIN32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
376; WIN32-NEXT:    mulw {{[0-9]+}}(%esp)
377; WIN32-NEXT:    seto %cl
378; WIN32-NEXT:    movw %ax, (%esi)
379; WIN32-NEXT:    movl %ecx, %eax
380; WIN32-NEXT:    popl %esi
381; WIN32-NEXT:    retl
382  %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
383  %val = extractvalue {i16, i1} %t, 0
384  %obit = extractvalue {i16, i1} %t, 1
385  store i16 %val, i16* %res
386  ret i1 %obit
387}
388
389define zeroext i1 @umuloi32(i32 %v1, i32 %v2, i32* %res) {
390; SDAG-LABEL: umuloi32:
391; SDAG:       # %bb.0:
392; SDAG-NEXT:    movq %rdx, %rcx
393; SDAG-NEXT:    movl %edi, %eax
394; SDAG-NEXT:    mull %esi
395; SDAG-NEXT:    seto %dl
396; SDAG-NEXT:    movl %eax, (%rcx)
397; SDAG-NEXT:    movl %edx, %eax
398; SDAG-NEXT:    retq
399;
400; FAST-LABEL: umuloi32:
401; FAST:       # %bb.0:
402; FAST-NEXT:    movq %rdx, %rcx
403; FAST-NEXT:    movl %edi, %eax
404; FAST-NEXT:    mull %esi
405; FAST-NEXT:    seto %dl
406; FAST-NEXT:    movl %eax, (%rcx)
407; FAST-NEXT:    andb $1, %dl
408; FAST-NEXT:    movzbl %dl, %eax
409; FAST-NEXT:    retq
410;
411; WIN64-LABEL: umuloi32:
412; WIN64:       # %bb.0:
413; WIN64-NEXT:    movl %ecx, %eax
414; WIN64-NEXT:    mull %edx
415; WIN64-NEXT:    seto %cl
416; WIN64-NEXT:    movl %eax, (%r8)
417; WIN64-NEXT:    movl %ecx, %eax
418; WIN64-NEXT:    retq
419;
420; WIN32-LABEL: umuloi32:
421; WIN32:       # %bb.0:
422; WIN32-NEXT:    pushl %esi
423; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
424; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
425; WIN32-NEXT:    mull {{[0-9]+}}(%esp)
426; WIN32-NEXT:    seto %cl
427; WIN32-NEXT:    movl %eax, (%esi)
428; WIN32-NEXT:    movl %ecx, %eax
429; WIN32-NEXT:    popl %esi
430; WIN32-NEXT:    retl
431  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
432  %val = extractvalue {i32, i1} %t, 0
433  %obit = extractvalue {i32, i1} %t, 1
434  store i32 %val, i32* %res
435  ret i1 %obit
436}
437
438define zeroext i1 @umuloi64(i64 %v1, i64 %v2, i64* %res) {
439; SDAG-LABEL: umuloi64:
440; SDAG:       # %bb.0:
441; SDAG-NEXT:    movq %rdx, %rcx
442; SDAG-NEXT:    movq %rdi, %rax
443; SDAG-NEXT:    mulq %rsi
444; SDAG-NEXT:    seto %dl
445; SDAG-NEXT:    movq %rax, (%rcx)
446; SDAG-NEXT:    movl %edx, %eax
447; SDAG-NEXT:    retq
448;
449; FAST-LABEL: umuloi64:
450; FAST:       # %bb.0:
451; FAST-NEXT:    movq %rdx, %rcx
452; FAST-NEXT:    movq %rdi, %rax
453; FAST-NEXT:    mulq %rsi
454; FAST-NEXT:    seto %dl
455; FAST-NEXT:    movq %rax, (%rcx)
456; FAST-NEXT:    andb $1, %dl
457; FAST-NEXT:    movzbl %dl, %eax
458; FAST-NEXT:    retq
459;
460; WIN64-LABEL: umuloi64:
461; WIN64:       # %bb.0:
462; WIN64-NEXT:    movq %rcx, %rax
463; WIN64-NEXT:    mulq %rdx
464; WIN64-NEXT:    seto %cl
465; WIN64-NEXT:    movq %rax, (%r8)
466; WIN64-NEXT:    movl %ecx, %eax
467; WIN64-NEXT:    retq
468;
469; WIN32-LABEL: umuloi64:
470; WIN32:       # %bb.0:
471; WIN32-NEXT:    pushl %ebp
472; WIN32-NEXT:    pushl %ebx
473; WIN32-NEXT:    pushl %edi
474; WIN32-NEXT:    pushl %esi
475; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
476; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
477; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ebp
478; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
479; WIN32-NEXT:    testl %esi, %esi
480; WIN32-NEXT:    setne %dl
481; WIN32-NEXT:    testl %eax, %eax
482; WIN32-NEXT:    setne %bl
483; WIN32-NEXT:    andb %dl, %bl
484; WIN32-NEXT:    mull %ebp
485; WIN32-NEXT:    movl %eax, %edi
486; WIN32-NEXT:    seto %bh
487; WIN32-NEXT:    movl %esi, %eax
488; WIN32-NEXT:    mull %ecx
489; WIN32-NEXT:    movl %ecx, %edx
490; WIN32-NEXT:    movl %eax, %esi
491; WIN32-NEXT:    seto %ch
492; WIN32-NEXT:    orb %bh, %ch
493; WIN32-NEXT:    addl %edi, %esi
494; WIN32-NEXT:    movl %edx, %eax
495; WIN32-NEXT:    mull %ebp
496; WIN32-NEXT:    addl %esi, %edx
497; WIN32-NEXT:    setb %cl
498; WIN32-NEXT:    orb %ch, %cl
499; WIN32-NEXT:    orb %bl, %cl
500; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
501; WIN32-NEXT:    movl %eax, (%esi)
502; WIN32-NEXT:    movl %edx, 4(%esi)
503; WIN32-NEXT:    movl %ecx, %eax
504; WIN32-NEXT:    popl %esi
505; WIN32-NEXT:    popl %edi
506; WIN32-NEXT:    popl %ebx
507; WIN32-NEXT:    popl %ebp
508; WIN32-NEXT:    retl
509  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
510  %val = extractvalue {i64, i1} %t, 0
511  %obit = extractvalue {i64, i1} %t, 1
512  store i64 %val, i64* %res
513  ret i1 %obit
514}
515
516;
517; Check the use of the overflow bit in combination with a select instruction.
518;
519define i32 @smuloselecti32(i32 %v1, i32 %v2) {
520; LINUX-LABEL: smuloselecti32:
521; LINUX:       # %bb.0:
522; LINUX-NEXT:    movl %esi, %eax
523; LINUX-NEXT:    movl %edi, %ecx
524; LINUX-NEXT:    imull %esi, %ecx
525; LINUX-NEXT:    cmovol %edi, %eax
526; LINUX-NEXT:    retq
527;
528; WIN64-LABEL: smuloselecti32:
529; WIN64:       # %bb.0:
530; WIN64-NEXT:    movl %edx, %eax
531; WIN64-NEXT:    movl %ecx, %edx
532; WIN64-NEXT:    imull %eax, %edx
533; WIN64-NEXT:    cmovol %ecx, %eax
534; WIN64-NEXT:    retq
535;
536; WIN32-LABEL: smuloselecti32:
537; WIN32:       # %bb.0:
538; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
539; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
540; WIN32-NEXT:    movl %eax, %edx
541; WIN32-NEXT:    imull %ecx, %edx
542; WIN32-NEXT:    jo LBB11_2
543; WIN32-NEXT:  # %bb.1:
544; WIN32-NEXT:    movl %ecx, %eax
545; WIN32-NEXT:  LBB11_2:
546; WIN32-NEXT:    retl
547  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
548  %obit = extractvalue {i32, i1} %t, 1
549  %ret = select i1 %obit, i32 %v1, i32 %v2
550  ret i32 %ret
551}
552
553define i64 @smuloselecti64(i64 %v1, i64 %v2) {
554; LINUX-LABEL: smuloselecti64:
555; LINUX:       # %bb.0:
556; LINUX-NEXT:    movq %rsi, %rax
557; LINUX-NEXT:    movq %rdi, %rcx
558; LINUX-NEXT:    imulq %rsi, %rcx
559; LINUX-NEXT:    cmovoq %rdi, %rax
560; LINUX-NEXT:    retq
561;
562; WIN64-LABEL: smuloselecti64:
563; WIN64:       # %bb.0:
564; WIN64-NEXT:    movq %rdx, %rax
565; WIN64-NEXT:    movq %rcx, %rdx
566; WIN64-NEXT:    imulq %rax, %rdx
567; WIN64-NEXT:    cmovoq %rcx, %rax
568; WIN64-NEXT:    retq
569;
570; WIN32-LABEL: smuloselecti64:
571; WIN32:       # %bb.0:
572; WIN32-NEXT:    pushl %ebp
573; WIN32-NEXT:    pushl %ebx
574; WIN32-NEXT:    pushl %edi
575; WIN32-NEXT:    pushl %esi
576; WIN32-NEXT:    pushl %eax
577; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ebp
578; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ebx
579; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
580; WIN32-NEXT:    movl %eax, %ecx
581; WIN32-NEXT:    movl %eax, %esi
582; WIN32-NEXT:    sarl $31, %ecx
583; WIN32-NEXT:    movl %ebp, %edi
584; WIN32-NEXT:    imull %ecx, %edi
585; WIN32-NEXT:    movl %ebp, %eax
586; WIN32-NEXT:    mull %ecx
587; WIN32-NEXT:    movl %eax, (%esp) # 4-byte Spill
588; WIN32-NEXT:    addl %edi, %edx
589; WIN32-NEXT:    imull %ebx, %ecx
590; WIN32-NEXT:    addl %edx, %ecx
591; WIN32-NEXT:    sarl $31, %ebx
592; WIN32-NEXT:    movl %ebx, %edi
593; WIN32-NEXT:    imull %esi, %edi
594; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
595; WIN32-NEXT:    movl %ebx, %eax
596; WIN32-NEXT:    mull %esi
597; WIN32-NEXT:    addl %edi, %edx
598; WIN32-NEXT:    movl %esi, %edi
599; WIN32-NEXT:    imull %esi, %ebx
600; WIN32-NEXT:    addl %edx, %ebx
601; WIN32-NEXT:    addl (%esp), %eax # 4-byte Folded Reload
602; WIN32-NEXT:    movl %eax, (%esp) # 4-byte Spill
603; WIN32-NEXT:    adcl %ecx, %ebx
604; WIN32-NEXT:    movl %edi, %eax
605; WIN32-NEXT:    mull %ebp
606; WIN32-NEXT:    movl %edx, %esi
607; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
608; WIN32-NEXT:    mull %ebp
609; WIN32-NEXT:    movl %edx, %ecx
610; WIN32-NEXT:    movl %eax, %ebp
611; WIN32-NEXT:    addl %esi, %ebp
612; WIN32-NEXT:    adcl $0, %ecx
613; WIN32-NEXT:    movl %edi, %eax
614; WIN32-NEXT:    mull {{[0-9]+}}(%esp)
615; WIN32-NEXT:    movl %edx, %edi
616; WIN32-NEXT:    movl %eax, %esi
617; WIN32-NEXT:    addl %ebp, %esi
618; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ebp
619; WIN32-NEXT:    adcl %ecx, %edi
620; WIN32-NEXT:    setb %cl
621; WIN32-NEXT:    movl %ebp, %eax
622; WIN32-NEXT:    mull {{[0-9]+}}(%esp)
623; WIN32-NEXT:    addl %edi, %eax
624; WIN32-NEXT:    movzbl %cl, %ecx
625; WIN32-NEXT:    adcl %ecx, %edx
626; WIN32-NEXT:    addl (%esp), %eax # 4-byte Folded Reload
627; WIN32-NEXT:    adcl %ebx, %edx
628; WIN32-NEXT:    sarl $31, %esi
629; WIN32-NEXT:    xorl %esi, %edx
630; WIN32-NEXT:    xorl %eax, %esi
631; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
632; WIN32-NEXT:    orl %edx, %esi
633; WIN32-NEXT:    jne LBB12_2
634; WIN32-NEXT:  # %bb.1:
635; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
636; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ebp
637; WIN32-NEXT:  LBB12_2:
638; WIN32-NEXT:    movl %ebp, %edx
639; WIN32-NEXT:    addl $4, %esp
640; WIN32-NEXT:    popl %esi
641; WIN32-NEXT:    popl %edi
642; WIN32-NEXT:    popl %ebx
643; WIN32-NEXT:    popl %ebp
644; WIN32-NEXT:    retl
645  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
646  %obit = extractvalue {i64, i1} %t, 1
647  %ret = select i1 %obit, i64 %v1, i64 %v2
648  ret i64 %ret
649}
650
651define i32 @umuloselecti32(i32 %v1, i32 %v2) {
652; LINUX-LABEL: umuloselecti32:
653; LINUX:       # %bb.0:
654; LINUX-NEXT:    movl %edi, %eax
655; LINUX-NEXT:    mull %esi
656; LINUX-NEXT:    cmovol %edi, %esi
657; LINUX-NEXT:    movl %esi, %eax
658; LINUX-NEXT:    retq
659;
660; WIN64-LABEL: umuloselecti32:
661; WIN64:       # %bb.0:
662; WIN64-NEXT:    movl %edx, %r8d
663; WIN64-NEXT:    movl %ecx, %eax
664; WIN64-NEXT:    mull %edx
665; WIN64-NEXT:    cmovol %ecx, %r8d
666; WIN64-NEXT:    movl %r8d, %eax
667; WIN64-NEXT:    retq
668;
669; WIN32-LABEL: umuloselecti32:
670; WIN32:       # %bb.0:
671; WIN32-NEXT:    pushl %esi
672; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
673; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
674; WIN32-NEXT:    movl %ecx, %eax
675; WIN32-NEXT:    mull %esi
676; WIN32-NEXT:    jo LBB13_2
677; WIN32-NEXT:  # %bb.1:
678; WIN32-NEXT:    movl %esi, %ecx
679; WIN32-NEXT:  LBB13_2:
680; WIN32-NEXT:    movl %ecx, %eax
681; WIN32-NEXT:    popl %esi
682; WIN32-NEXT:    retl
683  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
684  %obit = extractvalue {i32, i1} %t, 1
685  %ret = select i1 %obit, i32 %v1, i32 %v2
686  ret i32 %ret
687}
688
689define i64 @umuloselecti64(i64 %v1, i64 %v2) {
690; LINUX-LABEL: umuloselecti64:
691; LINUX:       # %bb.0:
692; LINUX-NEXT:    movq %rdi, %rax
693; LINUX-NEXT:    mulq %rsi
694; LINUX-NEXT:    cmovoq %rdi, %rsi
695; LINUX-NEXT:    movq %rsi, %rax
696; LINUX-NEXT:    retq
697;
698; WIN64-LABEL: umuloselecti64:
699; WIN64:       # %bb.0:
700; WIN64-NEXT:    movq %rdx, %r8
701; WIN64-NEXT:    movq %rcx, %rax
702; WIN64-NEXT:    mulq %rdx
703; WIN64-NEXT:    cmovoq %rcx, %r8
704; WIN64-NEXT:    movq %r8, %rax
705; WIN64-NEXT:    retq
706;
707; WIN32-LABEL: umuloselecti64:
708; WIN32:       # %bb.0:
709; WIN32-NEXT:    pushl %ebp
710; WIN32-NEXT:    pushl %ebx
711; WIN32-NEXT:    pushl %edi
712; WIN32-NEXT:    pushl %esi
713; WIN32-NEXT:    pushl %eax
714; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
715; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
716; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ebp
717; WIN32-NEXT:    testl %ebp, %ebp
718; WIN32-NEXT:    setne %al
719; WIN32-NEXT:    testl %esi, %esi
720; WIN32-NEXT:    setne %bl
721; WIN32-NEXT:    andb %al, %bl
722; WIN32-NEXT:    movl %esi, %eax
723; WIN32-NEXT:    mull {{[0-9]+}}(%esp)
724; WIN32-NEXT:    movl %eax, %edi
725; WIN32-NEXT:    seto {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Folded Spill
726; WIN32-NEXT:    movl %ebp, %eax
727; WIN32-NEXT:    mull %ecx
728; WIN32-NEXT:    movl %eax, %ebp
729; WIN32-NEXT:    seto %bh
730; WIN32-NEXT:    orb {{[-0-9]+}}(%e{{[sb]}}p), %bh # 1-byte Folded Reload
731; WIN32-NEXT:    addl %edi, %ebp
732; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edi
733; WIN32-NEXT:    movl %ecx, %eax
734; WIN32-NEXT:    mull %edi
735; WIN32-NEXT:    addl %ebp, %edx
736; WIN32-NEXT:    setb %al
737; WIN32-NEXT:    orb %bh, %al
738; WIN32-NEXT:    orb %bl, %al
739; WIN32-NEXT:    testb %al, %al
740; WIN32-NEXT:    jne LBB14_2
741; WIN32-NEXT:  # %bb.1:
742; WIN32-NEXT:    movl %edi, %ecx
743; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
744; WIN32-NEXT:  LBB14_2:
745; WIN32-NEXT:    movl %ecx, %eax
746; WIN32-NEXT:    movl %esi, %edx
747; WIN32-NEXT:    addl $4, %esp
748; WIN32-NEXT:    popl %esi
749; WIN32-NEXT:    popl %edi
750; WIN32-NEXT:    popl %ebx
751; WIN32-NEXT:    popl %ebp
752; WIN32-NEXT:    retl
753  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
754  %obit = extractvalue {i64, i1} %t, 1
755  %ret = select i1 %obit, i64 %v1, i64 %v2
756  ret i64 %ret
757}
758
759;
760; Check the use of the overflow bit in combination with a branch instruction.
761;
762define zeroext i1 @smulobri8(i8 %v1, i8 %v2) {
763; SDAG-LABEL: smulobri8:
764; SDAG:       # %bb.0:
765; SDAG-NEXT:    movl %edi, %eax
766; SDAG-NEXT:    # kill: def $al killed $al killed $eax
767; SDAG-NEXT:    imulb %sil
768; SDAG-NEXT:    jo .LBB15_1
769; SDAG-NEXT:  # %bb.2: # %continue
770; SDAG-NEXT:    movb $1, %al
771; SDAG-NEXT:    retq
772; SDAG-NEXT:  .LBB15_1: # %overflow
773; SDAG-NEXT:    xorl %eax, %eax
774; SDAG-NEXT:    retq
775;
776; FAST-LABEL: smulobri8:
777; FAST:       # %bb.0:
778; FAST-NEXT:    movl %edi, %eax
779; FAST-NEXT:    # kill: def $al killed $al killed $eax
780; FAST-NEXT:    imulb %sil
781; FAST-NEXT:    seto %al
782; FAST-NEXT:    testb $1, %al
783; FAST-NEXT:    jne .LBB15_1
784; FAST-NEXT:  # %bb.2: # %continue
785; FAST-NEXT:    movb $1, %al
786; FAST-NEXT:    andb $1, %al
787; FAST-NEXT:    movzbl %al, %eax
788; FAST-NEXT:    retq
789; FAST-NEXT:  .LBB15_1: # %overflow
790; FAST-NEXT:    xorl %eax, %eax
791; FAST-NEXT:    andb $1, %al
792; FAST-NEXT:    movzbl %al, %eax
793; FAST-NEXT:    retq
794;
795; WIN64-LABEL: smulobri8:
796; WIN64:       # %bb.0:
797; WIN64-NEXT:    movl %ecx, %eax
798; WIN64-NEXT:    imulb %dl
799; WIN64-NEXT:    jo .LBB15_1
800; WIN64-NEXT:  # %bb.2: # %continue
801; WIN64-NEXT:    movb $1, %al
802; WIN64-NEXT:    retq
803; WIN64-NEXT:  .LBB15_1: # %overflow
804; WIN64-NEXT:    xorl %eax, %eax
805; WIN64-NEXT:    retq
806;
807; WIN32-LABEL: smulobri8:
808; WIN32:       # %bb.0:
809; WIN32-NEXT:    movb {{[0-9]+}}(%esp), %al
810; WIN32-NEXT:    imulb {{[0-9]+}}(%esp)
811; WIN32-NEXT:    jo LBB15_1
812; WIN32-NEXT:  # %bb.2: # %continue
813; WIN32-NEXT:    movb $1, %al
814; WIN32-NEXT:    retl
815; WIN32-NEXT:  LBB15_1: # %overflow
816; WIN32-NEXT:    xorl %eax, %eax
817; WIN32-NEXT:    retl
818  %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
819  %val = extractvalue {i8, i1} %t, 0
820  %obit = extractvalue {i8, i1} %t, 1
821  br i1 %obit, label %overflow, label %continue, !prof !0
822
823overflow:
824  ret i1 false
825
826continue:
827  ret i1 true
828}
829
830define zeroext i1 @smulobri16(i16 %v1, i16 %v2) {
831; SDAG-LABEL: smulobri16:
832; SDAG:       # %bb.0:
833; SDAG-NEXT:    imulw %si, %di
834; SDAG-NEXT:    jo .LBB16_1
835; SDAG-NEXT:  # %bb.2: # %continue
836; SDAG-NEXT:    movb $1, %al
837; SDAG-NEXT:    retq
838; SDAG-NEXT:  .LBB16_1: # %overflow
839; SDAG-NEXT:    xorl %eax, %eax
840; SDAG-NEXT:    retq
841;
842; FAST-LABEL: smulobri16:
843; FAST:       # %bb.0:
844; FAST-NEXT:    imulw %si, %di
845; FAST-NEXT:    seto %al
846; FAST-NEXT:    testb $1, %al
847; FAST-NEXT:    jne .LBB16_1
848; FAST-NEXT:  # %bb.2: # %continue
849; FAST-NEXT:    movb $1, %al
850; FAST-NEXT:    andb $1, %al
851; FAST-NEXT:    movzbl %al, %eax
852; FAST-NEXT:    retq
853; FAST-NEXT:  .LBB16_1: # %overflow
854; FAST-NEXT:    xorl %eax, %eax
855; FAST-NEXT:    andb $1, %al
856; FAST-NEXT:    movzbl %al, %eax
857; FAST-NEXT:    retq
858;
859; WIN64-LABEL: smulobri16:
860; WIN64:       # %bb.0:
861; WIN64-NEXT:    imulw %dx, %cx
862; WIN64-NEXT:    jo .LBB16_1
863; WIN64-NEXT:  # %bb.2: # %continue
864; WIN64-NEXT:    movb $1, %al
865; WIN64-NEXT:    retq
866; WIN64-NEXT:  .LBB16_1: # %overflow
867; WIN64-NEXT:    xorl %eax, %eax
868; WIN64-NEXT:    retq
869;
870; WIN32-LABEL: smulobri16:
871; WIN32:       # %bb.0:
872; WIN32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
873; WIN32-NEXT:    imulw {{[0-9]+}}(%esp), %ax
874; WIN32-NEXT:    jo LBB16_1
875; WIN32-NEXT:  # %bb.2: # %continue
876; WIN32-NEXT:    movb $1, %al
877; WIN32-NEXT:    retl
878; WIN32-NEXT:  LBB16_1: # %overflow
879; WIN32-NEXT:    xorl %eax, %eax
880; WIN32-NEXT:    retl
881  %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
882  %val = extractvalue {i16, i1} %t, 0
883  %obit = extractvalue {i16, i1} %t, 1
884  br i1 %obit, label %overflow, label %continue, !prof !0
885
886overflow:
887  ret i1 false
888
889continue:
890  ret i1 true
891}
892
893define zeroext i1 @smulobri32(i32 %v1, i32 %v2) {
894; SDAG-LABEL: smulobri32:
895; SDAG:       # %bb.0:
896; SDAG-NEXT:    imull %esi, %edi
897; SDAG-NEXT:    jo .LBB17_1
898; SDAG-NEXT:  # %bb.2: # %continue
899; SDAG-NEXT:    movb $1, %al
900; SDAG-NEXT:    retq
901; SDAG-NEXT:  .LBB17_1: # %overflow
902; SDAG-NEXT:    xorl %eax, %eax
903; SDAG-NEXT:    retq
904;
905; FAST-LABEL: smulobri32:
906; FAST:       # %bb.0:
907; FAST-NEXT:    imull %esi, %edi
908; FAST-NEXT:    jo .LBB17_1
909; FAST-NEXT:  # %bb.2: # %continue
910; FAST-NEXT:    movb $1, %al
911; FAST-NEXT:    andb $1, %al
912; FAST-NEXT:    movzbl %al, %eax
913; FAST-NEXT:    retq
914; FAST-NEXT:  .LBB17_1: # %overflow
915; FAST-NEXT:    xorl %eax, %eax
916; FAST-NEXT:    andb $1, %al
917; FAST-NEXT:    movzbl %al, %eax
918; FAST-NEXT:    retq
919;
920; WIN64-LABEL: smulobri32:
921; WIN64:       # %bb.0:
922; WIN64-NEXT:    imull %edx, %ecx
923; WIN64-NEXT:    jo .LBB17_1
924; WIN64-NEXT:  # %bb.2: # %continue
925; WIN64-NEXT:    movb $1, %al
926; WIN64-NEXT:    retq
927; WIN64-NEXT:  .LBB17_1: # %overflow
928; WIN64-NEXT:    xorl %eax, %eax
929; WIN64-NEXT:    retq
930;
931; WIN32-LABEL: smulobri32:
932; WIN32:       # %bb.0:
933; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
934; WIN32-NEXT:    imull {{[0-9]+}}(%esp), %eax
935; WIN32-NEXT:    jo LBB17_1
936; WIN32-NEXT:  # %bb.2: # %continue
937; WIN32-NEXT:    movb $1, %al
938; WIN32-NEXT:    retl
939; WIN32-NEXT:  LBB17_1: # %overflow
940; WIN32-NEXT:    xorl %eax, %eax
941; WIN32-NEXT:    retl
942  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
943  %val = extractvalue {i32, i1} %t, 0
944  %obit = extractvalue {i32, i1} %t, 1
945  br i1 %obit, label %overflow, label %continue, !prof !0
946
947overflow:
948  ret i1 false
949
950continue:
951  ret i1 true
952}
953
954define zeroext i1 @smulobri64(i64 %v1, i64 %v2) {
955; SDAG-LABEL: smulobri64:
956; SDAG:       # %bb.0:
957; SDAG-NEXT:    imulq %rsi, %rdi
958; SDAG-NEXT:    jo .LBB18_1
959; SDAG-NEXT:  # %bb.2: # %continue
960; SDAG-NEXT:    movb $1, %al
961; SDAG-NEXT:    retq
962; SDAG-NEXT:  .LBB18_1: # %overflow
963; SDAG-NEXT:    xorl %eax, %eax
964; SDAG-NEXT:    retq
965;
966; FAST-LABEL: smulobri64:
967; FAST:       # %bb.0:
968; FAST-NEXT:    imulq %rsi, %rdi
969; FAST-NEXT:    jo .LBB18_1
970; FAST-NEXT:  # %bb.2: # %continue
971; FAST-NEXT:    movb $1, %al
972; FAST-NEXT:    andb $1, %al
973; FAST-NEXT:    movzbl %al, %eax
974; FAST-NEXT:    retq
975; FAST-NEXT:  .LBB18_1: # %overflow
976; FAST-NEXT:    xorl %eax, %eax
977; FAST-NEXT:    andb $1, %al
978; FAST-NEXT:    movzbl %al, %eax
979; FAST-NEXT:    retq
980;
981; WIN64-LABEL: smulobri64:
982; WIN64:       # %bb.0:
983; WIN64-NEXT:    imulq %rdx, %rcx
984; WIN64-NEXT:    jo .LBB18_1
985; WIN64-NEXT:  # %bb.2: # %continue
986; WIN64-NEXT:    movb $1, %al
987; WIN64-NEXT:    retq
988; WIN64-NEXT:  .LBB18_1: # %overflow
989; WIN64-NEXT:    xorl %eax, %eax
990; WIN64-NEXT:    retq
991;
992; WIN32-LABEL: smulobri64:
993; WIN32:       # %bb.0:
994; WIN32-NEXT:    pushl %ebp
995; WIN32-NEXT:    pushl %ebx
996; WIN32-NEXT:    pushl %edi
997; WIN32-NEXT:    pushl %esi
998; WIN32-NEXT:    pushl %eax
999; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1000; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ebx
1001; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1002; WIN32-NEXT:    movl %ecx, %edi
1003; WIN32-NEXT:    sarl $31, %edi
1004; WIN32-NEXT:    movl %eax, %esi
1005; WIN32-NEXT:    imull %edi, %esi
1006; WIN32-NEXT:    mull %edi
1007; WIN32-NEXT:    movl %eax, %ebp
1008; WIN32-NEXT:    addl %esi, %edx
1009; WIN32-NEXT:    movl %ebx, %esi
1010; WIN32-NEXT:    imull %ebx, %edi
1011; WIN32-NEXT:    addl %edx, %edi
1012; WIN32-NEXT:    sarl $31, %esi
1013; WIN32-NEXT:    movl %esi, %ebx
1014; WIN32-NEXT:    imull %ecx, %ebx
1015; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1016; WIN32-NEXT:    movl %esi, %eax
1017; WIN32-NEXT:    mull %ecx
1018; WIN32-NEXT:    addl %ebx, %edx
1019; WIN32-NEXT:    imull %ecx, %esi
1020; WIN32-NEXT:    addl %edx, %esi
1021; WIN32-NEXT:    addl %ebp, %eax
1022; WIN32-NEXT:    movl %eax, (%esp) # 4-byte Spill
1023; WIN32-NEXT:    adcl %edi, %esi
1024; WIN32-NEXT:    movl %ecx, %eax
1025; WIN32-NEXT:    movl %ecx, %edi
1026; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1027; WIN32-NEXT:    mull %ecx
1028; WIN32-NEXT:    movl %edx, %ebx
1029; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1030; WIN32-NEXT:    mull %ecx
1031; WIN32-NEXT:    movl %edx, %ebp
1032; WIN32-NEXT:    movl %eax, %ecx
1033; WIN32-NEXT:    addl %ebx, %ecx
1034; WIN32-NEXT:    adcl $0, %ebp
1035; WIN32-NEXT:    movl %edi, %eax
1036; WIN32-NEXT:    mull {{[0-9]+}}(%esp)
1037; WIN32-NEXT:    movl %edx, %edi
1038; WIN32-NEXT:    movl %eax, %ebx
1039; WIN32-NEXT:    addl %ecx, %ebx
1040; WIN32-NEXT:    adcl %ebp, %edi
1041; WIN32-NEXT:    setb %cl
1042; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1043; WIN32-NEXT:    mull {{[0-9]+}}(%esp)
1044; WIN32-NEXT:    addl %edi, %eax
1045; WIN32-NEXT:    movzbl %cl, %ecx
1046; WIN32-NEXT:    adcl %ecx, %edx
1047; WIN32-NEXT:    addl (%esp), %eax # 4-byte Folded Reload
1048; WIN32-NEXT:    adcl %esi, %edx
1049; WIN32-NEXT:    sarl $31, %ebx
1050; WIN32-NEXT:    xorl %ebx, %edx
1051; WIN32-NEXT:    xorl %eax, %ebx
1052; WIN32-NEXT:    orl %edx, %ebx
1053; WIN32-NEXT:    jne LBB18_1
1054; WIN32-NEXT:  # %bb.3: # %continue
1055; WIN32-NEXT:    movb $1, %al
1056; WIN32-NEXT:  LBB18_2: # %overflow
1057; WIN32-NEXT:    addl $4, %esp
1058; WIN32-NEXT:    popl %esi
1059; WIN32-NEXT:    popl %edi
1060; WIN32-NEXT:    popl %ebx
1061; WIN32-NEXT:    popl %ebp
1062; WIN32-NEXT:    retl
1063; WIN32-NEXT:  LBB18_1: # %overflow
1064; WIN32-NEXT:    xorl %eax, %eax
1065; WIN32-NEXT:    jmp LBB18_2
1066  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
1067  %val = extractvalue {i64, i1} %t, 0
1068  %obit = extractvalue {i64, i1} %t, 1
1069  br i1 %obit, label %overflow, label %continue, !prof !0
1070
1071overflow:
1072  ret i1 false
1073
1074continue:
1075  ret i1 true
1076}
1077
1078define zeroext i1 @umulobri8(i8 %v1, i8 %v2) {
1079; SDAG-LABEL: umulobri8:
1080; SDAG:       # %bb.0:
1081; SDAG-NEXT:    movl %edi, %eax
1082; SDAG-NEXT:    # kill: def $al killed $al killed $eax
1083; SDAG-NEXT:    mulb %sil
1084; SDAG-NEXT:    jo .LBB19_1
1085; SDAG-NEXT:  # %bb.2: # %continue
1086; SDAG-NEXT:    movb $1, %al
1087; SDAG-NEXT:    retq
1088; SDAG-NEXT:  .LBB19_1: # %overflow
1089; SDAG-NEXT:    xorl %eax, %eax
1090; SDAG-NEXT:    retq
1091;
1092; FAST-LABEL: umulobri8:
1093; FAST:       # %bb.0:
1094; FAST-NEXT:    movl %edi, %eax
1095; FAST-NEXT:    # kill: def $al killed $al killed $eax
1096; FAST-NEXT:    mulb %sil
1097; FAST-NEXT:    seto %al
1098; FAST-NEXT:    testb $1, %al
1099; FAST-NEXT:    jne .LBB19_1
1100; FAST-NEXT:  # %bb.2: # %continue
1101; FAST-NEXT:    movb $1, %al
1102; FAST-NEXT:    andb $1, %al
1103; FAST-NEXT:    movzbl %al, %eax
1104; FAST-NEXT:    retq
1105; FAST-NEXT:  .LBB19_1: # %overflow
1106; FAST-NEXT:    xorl %eax, %eax
1107; FAST-NEXT:    andb $1, %al
1108; FAST-NEXT:    movzbl %al, %eax
1109; FAST-NEXT:    retq
1110;
1111; WIN64-LABEL: umulobri8:
1112; WIN64:       # %bb.0:
1113; WIN64-NEXT:    movl %ecx, %eax
1114; WIN64-NEXT:    mulb %dl
1115; WIN64-NEXT:    jo .LBB19_1
1116; WIN64-NEXT:  # %bb.2: # %continue
1117; WIN64-NEXT:    movb $1, %al
1118; WIN64-NEXT:    retq
1119; WIN64-NEXT:  .LBB19_1: # %overflow
1120; WIN64-NEXT:    xorl %eax, %eax
1121; WIN64-NEXT:    retq
1122;
1123; WIN32-LABEL: umulobri8:
1124; WIN32:       # %bb.0:
1125; WIN32-NEXT:    movb {{[0-9]+}}(%esp), %al
1126; WIN32-NEXT:    mulb {{[0-9]+}}(%esp)
1127; WIN32-NEXT:    jo LBB19_1
1128; WIN32-NEXT:  # %bb.2: # %continue
1129; WIN32-NEXT:    movb $1, %al
1130; WIN32-NEXT:    retl
1131; WIN32-NEXT:  LBB19_1: # %overflow
1132; WIN32-NEXT:    xorl %eax, %eax
1133; WIN32-NEXT:    retl
1134  %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
1135  %val = extractvalue {i8, i1} %t, 0
1136  %obit = extractvalue {i8, i1} %t, 1
1137  br i1 %obit, label %overflow, label %continue, !prof !0
1138
1139overflow:
1140  ret i1 false
1141
1142continue:
1143  ret i1 true
1144}
1145
1146define zeroext i1 @umulobri16(i16 %v1, i16 %v2) {
1147; SDAG-LABEL: umulobri16:
1148; SDAG:       # %bb.0:
1149; SDAG-NEXT:    movl %edi, %eax
1150; SDAG-NEXT:    # kill: def $ax killed $ax killed $eax
1151; SDAG-NEXT:    mulw %si
1152; SDAG-NEXT:    jo .LBB20_1
1153; SDAG-NEXT:  # %bb.2: # %continue
1154; SDAG-NEXT:    movb $1, %al
1155; SDAG-NEXT:    retq
1156; SDAG-NEXT:  .LBB20_1: # %overflow
1157; SDAG-NEXT:    xorl %eax, %eax
1158; SDAG-NEXT:    retq
1159;
1160; FAST-LABEL: umulobri16:
1161; FAST:       # %bb.0:
1162; FAST-NEXT:    movl %edi, %eax
1163; FAST-NEXT:    # kill: def $ax killed $ax killed $eax
1164; FAST-NEXT:    mulw %si
1165; FAST-NEXT:    seto %al
1166; FAST-NEXT:    testb $1, %al
1167; FAST-NEXT:    jne .LBB20_1
1168; FAST-NEXT:  # %bb.2: # %continue
1169; FAST-NEXT:    movb $1, %al
1170; FAST-NEXT:    andb $1, %al
1171; FAST-NEXT:    movzbl %al, %eax
1172; FAST-NEXT:    retq
1173; FAST-NEXT:  .LBB20_1: # %overflow
1174; FAST-NEXT:    xorl %eax, %eax
1175; FAST-NEXT:    andb $1, %al
1176; FAST-NEXT:    movzbl %al, %eax
1177; FAST-NEXT:    retq
1178;
1179; WIN64-LABEL: umulobri16:
1180; WIN64:       # %bb.0:
1181; WIN64-NEXT:    movl %ecx, %eax
1182; WIN64-NEXT:    mulw %dx
1183; WIN64-NEXT:    jo .LBB20_1
1184; WIN64-NEXT:  # %bb.2: # %continue
1185; WIN64-NEXT:    movb $1, %al
1186; WIN64-NEXT:    retq
1187; WIN64-NEXT:  .LBB20_1: # %overflow
1188; WIN64-NEXT:    xorl %eax, %eax
1189; WIN64-NEXT:    retq
1190;
1191; WIN32-LABEL: umulobri16:
1192; WIN32:       # %bb.0:
1193; WIN32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
1194; WIN32-NEXT:    mulw {{[0-9]+}}(%esp)
1195; WIN32-NEXT:    jo LBB20_1
1196; WIN32-NEXT:  # %bb.2: # %continue
1197; WIN32-NEXT:    movb $1, %al
1198; WIN32-NEXT:    retl
1199; WIN32-NEXT:  LBB20_1: # %overflow
1200; WIN32-NEXT:    xorl %eax, %eax
1201; WIN32-NEXT:    retl
1202  %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
1203  %val = extractvalue {i16, i1} %t, 0
1204  %obit = extractvalue {i16, i1} %t, 1
1205  br i1 %obit, label %overflow, label %continue, !prof !0
1206
1207overflow:
1208  ret i1 false
1209
1210continue:
1211  ret i1 true
1212}
1213
1214define zeroext i1 @umulobri32(i32 %v1, i32 %v2) {
1215; SDAG-LABEL: umulobri32:
1216; SDAG:       # %bb.0:
1217; SDAG-NEXT:    movl %edi, %eax
1218; SDAG-NEXT:    mull %esi
1219; SDAG-NEXT:    jo .LBB21_1
1220; SDAG-NEXT:  # %bb.2: # %continue
1221; SDAG-NEXT:    movb $1, %al
1222; SDAG-NEXT:    retq
1223; SDAG-NEXT:  .LBB21_1: # %overflow
1224; SDAG-NEXT:    xorl %eax, %eax
1225; SDAG-NEXT:    retq
1226;
1227; FAST-LABEL: umulobri32:
1228; FAST:       # %bb.0:
1229; FAST-NEXT:    movl %edi, %eax
1230; FAST-NEXT:    mull %esi
1231; FAST-NEXT:    jo .LBB21_1
1232; FAST-NEXT:  # %bb.2: # %continue
1233; FAST-NEXT:    movb $1, %al
1234; FAST-NEXT:    andb $1, %al
1235; FAST-NEXT:    movzbl %al, %eax
1236; FAST-NEXT:    retq
1237; FAST-NEXT:  .LBB21_1: # %overflow
1238; FAST-NEXT:    xorl %eax, %eax
1239; FAST-NEXT:    andb $1, %al
1240; FAST-NEXT:    movzbl %al, %eax
1241; FAST-NEXT:    retq
1242;
1243; WIN64-LABEL: umulobri32:
1244; WIN64:       # %bb.0:
1245; WIN64-NEXT:    movl %ecx, %eax
1246; WIN64-NEXT:    mull %edx
1247; WIN64-NEXT:    jo .LBB21_1
1248; WIN64-NEXT:  # %bb.2: # %continue
1249; WIN64-NEXT:    movb $1, %al
1250; WIN64-NEXT:    retq
1251; WIN64-NEXT:  .LBB21_1: # %overflow
1252; WIN64-NEXT:    xorl %eax, %eax
1253; WIN64-NEXT:    retq
1254;
1255; WIN32-LABEL: umulobri32:
1256; WIN32:       # %bb.0:
1257; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1258; WIN32-NEXT:    mull {{[0-9]+}}(%esp)
1259; WIN32-NEXT:    jo LBB21_1
1260; WIN32-NEXT:  # %bb.2: # %continue
1261; WIN32-NEXT:    movb $1, %al
1262; WIN32-NEXT:    retl
1263; WIN32-NEXT:  LBB21_1: # %overflow
1264; WIN32-NEXT:    xorl %eax, %eax
1265; WIN32-NEXT:    retl
1266  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
1267  %val = extractvalue {i32, i1} %t, 0
1268  %obit = extractvalue {i32, i1} %t, 1
1269  br i1 %obit, label %overflow, label %continue, !prof !0
1270
1271overflow:
1272  ret i1 false
1273
1274continue:
1275  ret i1 true
1276}
1277
1278define zeroext i1 @umulobri64(i64 %v1, i64 %v2) {
1279; SDAG-LABEL: umulobri64:
1280; SDAG:       # %bb.0:
1281; SDAG-NEXT:    movq %rdi, %rax
1282; SDAG-NEXT:    mulq %rsi
1283; SDAG-NEXT:    jo .LBB22_1
1284; SDAG-NEXT:  # %bb.2: # %continue
1285; SDAG-NEXT:    movb $1, %al
1286; SDAG-NEXT:    retq
1287; SDAG-NEXT:  .LBB22_1: # %overflow
1288; SDAG-NEXT:    xorl %eax, %eax
1289; SDAG-NEXT:    retq
1290;
1291; FAST-LABEL: umulobri64:
1292; FAST:       # %bb.0:
1293; FAST-NEXT:    movq %rdi, %rax
1294; FAST-NEXT:    mulq %rsi
1295; FAST-NEXT:    jo .LBB22_1
1296; FAST-NEXT:  # %bb.2: # %continue
1297; FAST-NEXT:    movb $1, %al
1298; FAST-NEXT:    andb $1, %al
1299; FAST-NEXT:    movzbl %al, %eax
1300; FAST-NEXT:    retq
1301; FAST-NEXT:  .LBB22_1: # %overflow
1302; FAST-NEXT:    xorl %eax, %eax
1303; FAST-NEXT:    andb $1, %al
1304; FAST-NEXT:    movzbl %al, %eax
1305; FAST-NEXT:    retq
1306;
1307; WIN64-LABEL: umulobri64:
1308; WIN64:       # %bb.0:
1309; WIN64-NEXT:    movq %rcx, %rax
1310; WIN64-NEXT:    mulq %rdx
1311; WIN64-NEXT:    jo .LBB22_1
1312; WIN64-NEXT:  # %bb.2: # %continue
1313; WIN64-NEXT:    movb $1, %al
1314; WIN64-NEXT:    retq
1315; WIN64-NEXT:  .LBB22_1: # %overflow
1316; WIN64-NEXT:    xorl %eax, %eax
1317; WIN64-NEXT:    retq
1318;
1319; WIN32-LABEL: umulobri64:
1320; WIN32:       # %bb.0:
1321; WIN32-NEXT:    pushl %ebp
1322; WIN32-NEXT:    pushl %ebx
1323; WIN32-NEXT:    pushl %edi
1324; WIN32-NEXT:    pushl %esi
1325; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1326; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1327; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ebp
1328; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
1329; WIN32-NEXT:    testl %esi, %esi
1330; WIN32-NEXT:    setne %dl
1331; WIN32-NEXT:    testl %eax, %eax
1332; WIN32-NEXT:    setne %bl
1333; WIN32-NEXT:    andb %dl, %bl
1334; WIN32-NEXT:    mull %ebp
1335; WIN32-NEXT:    movl %eax, %edi
1336; WIN32-NEXT:    seto %bh
1337; WIN32-NEXT:    movl %esi, %eax
1338; WIN32-NEXT:    mull %ecx
1339; WIN32-NEXT:    movl %ecx, %edx
1340; WIN32-NEXT:    movl %eax, %esi
1341; WIN32-NEXT:    seto %cl
1342; WIN32-NEXT:    orb %bh, %cl
1343; WIN32-NEXT:    addl %edi, %esi
1344; WIN32-NEXT:    movl %edx, %eax
1345; WIN32-NEXT:    mull %ebp
1346; WIN32-NEXT:    addl %esi, %edx
1347; WIN32-NEXT:    setb %al
1348; WIN32-NEXT:    orb %cl, %al
1349; WIN32-NEXT:    orb %bl, %al
1350; WIN32-NEXT:    subb $1, %al
1351; WIN32-NEXT:    je LBB22_1
1352; WIN32-NEXT:  # %bb.3: # %continue
1353; WIN32-NEXT:    movb $1, %al
1354; WIN32-NEXT:  LBB22_2: # %overflow
1355; WIN32-NEXT:    popl %esi
1356; WIN32-NEXT:    popl %edi
1357; WIN32-NEXT:    popl %ebx
1358; WIN32-NEXT:    popl %ebp
1359; WIN32-NEXT:    retl
1360; WIN32-NEXT:  LBB22_1: # %overflow
1361; WIN32-NEXT:    xorl %eax, %eax
1362; WIN32-NEXT:    jmp LBB22_2
1363  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
1364  %val = extractvalue {i64, i1} %t, 0
1365  %obit = extractvalue {i64, i1} %t, 1
1366  br i1 %obit, label %overflow, label %continue, !prof !0
1367
1368overflow:
1369  ret i1 false
1370
1371continue:
1372  ret i1 true
1373}
1374
1375define i1 @bug27873(i64 %c1, i1 %c2) {
1376; LINUX-LABEL: bug27873:
1377; LINUX:       # %bb.0:
1378; LINUX-NEXT:    movq %rdi, %rax
1379; LINUX-NEXT:    movl $160, %ecx
1380; LINUX-NEXT:    mulq %rcx
1381; LINUX-NEXT:    seto %al
1382; LINUX-NEXT:    orb %sil, %al
1383; LINUX-NEXT:    retq
1384;
1385; WIN64-LABEL: bug27873:
1386; WIN64:       # %bb.0:
1387; WIN64-NEXT:    movl %edx, %r8d
1388; WIN64-NEXT:    movq %rcx, %rax
1389; WIN64-NEXT:    movl $160, %ecx
1390; WIN64-NEXT:    mulq %rcx
1391; WIN64-NEXT:    seto %al
1392; WIN64-NEXT:    orb %r8b, %al
1393; WIN64-NEXT:    retq
1394;
1395; WIN32-LABEL: bug27873:
1396; WIN32:       # %bb.0:
1397; WIN32-NEXT:    pushl %ebx
1398; WIN32-NEXT:    movl $160, %eax
1399; WIN32-NEXT:    mull {{[0-9]+}}(%esp)
1400; WIN32-NEXT:    movl %eax, %ecx
1401; WIN32-NEXT:    seto %bl
1402; WIN32-NEXT:    movl $160, %eax
1403; WIN32-NEXT:    mull {{[0-9]+}}(%esp)
1404; WIN32-NEXT:    addl %ecx, %edx
1405; WIN32-NEXT:    setb %al
1406; WIN32-NEXT:    orb %bl, %al
1407; WIN32-NEXT:    orb {{[0-9]+}}(%esp), %al
1408; WIN32-NEXT:    popl %ebx
1409; WIN32-NEXT:    retl
1410  %mul = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %c1, i64 160)
1411  %mul.overflow = extractvalue { i64, i1 } %mul, 1
1412  %x1 = or i1 %c2, %mul.overflow
1413  ret i1 %x1
1414}
1415
1416define zeroext i1 @smuloi8_load(i8* %ptr1, i8 %v2, i8* %res) {
1417; SDAG-LABEL: smuloi8_load:
1418; SDAG:       # %bb.0:
1419; SDAG-NEXT:    movl %esi, %eax
1420; SDAG-NEXT:    # kill: def $al killed $al killed $eax
1421; SDAG-NEXT:    imulb (%rdi)
1422; SDAG-NEXT:    seto %cl
1423; SDAG-NEXT:    movb %al, (%rdx)
1424; SDAG-NEXT:    movl %ecx, %eax
1425; SDAG-NEXT:    retq
1426;
1427; FAST-LABEL: smuloi8_load:
1428; FAST:       # %bb.0:
1429; FAST-NEXT:    movb (%rdi), %al
1430; FAST-NEXT:    imulb %sil
1431; FAST-NEXT:    seto %cl
1432; FAST-NEXT:    movb %al, (%rdx)
1433; FAST-NEXT:    andb $1, %cl
1434; FAST-NEXT:    movzbl %cl, %eax
1435; FAST-NEXT:    retq
1436;
1437; WIN64-LABEL: smuloi8_load:
1438; WIN64:       # %bb.0:
1439; WIN64-NEXT:    movl %edx, %eax
1440; WIN64-NEXT:    imulb (%rcx)
1441; WIN64-NEXT:    seto %cl
1442; WIN64-NEXT:    movb %al, (%r8)
1443; WIN64-NEXT:    movl %ecx, %eax
1444; WIN64-NEXT:    retq
1445;
1446; WIN32-LABEL: smuloi8_load:
1447; WIN32:       # %bb.0:
1448; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edx
1449; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1450; WIN32-NEXT:    movb (%eax), %al
1451; WIN32-NEXT:    imulb {{[0-9]+}}(%esp)
1452; WIN32-NEXT:    seto %cl
1453; WIN32-NEXT:    movb %al, (%edx)
1454; WIN32-NEXT:    movl %ecx, %eax
1455; WIN32-NEXT:    retl
1456  %v1 = load i8, i8* %ptr1
1457  %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
1458  %val = extractvalue {i8, i1} %t, 0
1459  %obit = extractvalue {i8, i1} %t, 1
1460  store i8 %val, i8* %res
1461  ret i1 %obit
1462}
1463
1464define zeroext i1 @smuloi8_load2(i8 %v1, i8* %ptr2, i8* %res) {
1465; SDAG-LABEL: smuloi8_load2:
1466; SDAG:       # %bb.0:
1467; SDAG-NEXT:    movl %edi, %eax
1468; SDAG-NEXT:    # kill: def $al killed $al killed $eax
1469; SDAG-NEXT:    imulb (%rsi)
1470; SDAG-NEXT:    seto %cl
1471; SDAG-NEXT:    movb %al, (%rdx)
1472; SDAG-NEXT:    movl %ecx, %eax
1473; SDAG-NEXT:    retq
1474;
1475; FAST-LABEL: smuloi8_load2:
1476; FAST:       # %bb.0:
1477; FAST-NEXT:    movl %edi, %eax
1478; FAST-NEXT:    # kill: def $al killed $al killed $eax
1479; FAST-NEXT:    imulb (%rsi)
1480; FAST-NEXT:    seto %cl
1481; FAST-NEXT:    movb %al, (%rdx)
1482; FAST-NEXT:    andb $1, %cl
1483; FAST-NEXT:    movzbl %cl, %eax
1484; FAST-NEXT:    retq
1485;
1486; WIN64-LABEL: smuloi8_load2:
1487; WIN64:       # %bb.0:
1488; WIN64-NEXT:    movl %ecx, %eax
1489; WIN64-NEXT:    imulb (%rdx)
1490; WIN64-NEXT:    seto %cl
1491; WIN64-NEXT:    movb %al, (%r8)
1492; WIN64-NEXT:    movl %ecx, %eax
1493; WIN64-NEXT:    retq
1494;
1495; WIN32-LABEL: smuloi8_load2:
1496; WIN32:       # %bb.0:
1497; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edx
1498; WIN32-NEXT:    movb {{[0-9]+}}(%esp), %al
1499; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1500; WIN32-NEXT:    imulb (%ecx)
1501; WIN32-NEXT:    seto %cl
1502; WIN32-NEXT:    movb %al, (%edx)
1503; WIN32-NEXT:    movl %ecx, %eax
1504; WIN32-NEXT:    retl
1505  %v2 = load i8, i8* %ptr2
1506  %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
1507  %val = extractvalue {i8, i1} %t, 0
1508  %obit = extractvalue {i8, i1} %t, 1
1509  store i8 %val, i8* %res
1510  ret i1 %obit
1511}
1512
1513define zeroext i1 @smuloi16_load(i16* %ptr1, i16 %v2, i16* %res) {
1514; SDAG-LABEL: smuloi16_load:
1515; SDAG:       # %bb.0:
1516; SDAG-NEXT:    imulw (%rdi), %si
1517; SDAG-NEXT:    seto %al
1518; SDAG-NEXT:    movw %si, (%rdx)
1519; SDAG-NEXT:    retq
1520;
1521; FAST-LABEL: smuloi16_load:
1522; FAST:       # %bb.0:
1523; FAST-NEXT:    imulw (%rdi), %si
1524; FAST-NEXT:    seto %al
1525; FAST-NEXT:    movw %si, (%rdx)
1526; FAST-NEXT:    andb $1, %al
1527; FAST-NEXT:    movzbl %al, %eax
1528; FAST-NEXT:    retq
1529;
1530; WIN64-LABEL: smuloi16_load:
1531; WIN64:       # %bb.0:
1532; WIN64-NEXT:    imulw (%rcx), %dx
1533; WIN64-NEXT:    seto %al
1534; WIN64-NEXT:    movw %dx, (%r8)
1535; WIN64-NEXT:    retq
1536;
1537; WIN32-LABEL: smuloi16_load:
1538; WIN32:       # %bb.0:
1539; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1540; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1541; WIN32-NEXT:    movzwl (%eax), %edx
1542; WIN32-NEXT:    imulw {{[0-9]+}}(%esp), %dx
1543; WIN32-NEXT:    seto %al
1544; WIN32-NEXT:    movw %dx, (%ecx)
1545; WIN32-NEXT:    retl
1546  %v1 = load i16, i16* %ptr1
1547  %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
1548  %val = extractvalue {i16, i1} %t, 0
1549  %obit = extractvalue {i16, i1} %t, 1
1550  store i16 %val, i16* %res
1551  ret i1 %obit
1552}
1553
1554define zeroext i1 @smuloi16_load2(i16 %v1, i16* %ptr2, i16* %res) {
1555; SDAG-LABEL: smuloi16_load2:
1556; SDAG:       # %bb.0:
1557; SDAG-NEXT:    imulw (%rsi), %di
1558; SDAG-NEXT:    seto %al
1559; SDAG-NEXT:    movw %di, (%rdx)
1560; SDAG-NEXT:    retq
1561;
1562; FAST-LABEL: smuloi16_load2:
1563; FAST:       # %bb.0:
1564; FAST-NEXT:    imulw (%rsi), %di
1565; FAST-NEXT:    seto %al
1566; FAST-NEXT:    movw %di, (%rdx)
1567; FAST-NEXT:    andb $1, %al
1568; FAST-NEXT:    movzbl %al, %eax
1569; FAST-NEXT:    retq
1570;
1571; WIN64-LABEL: smuloi16_load2:
1572; WIN64:       # %bb.0:
1573; WIN64-NEXT:    imulw (%rdx), %cx
1574; WIN64-NEXT:    seto %al
1575; WIN64-NEXT:    movw %cx, (%r8)
1576; WIN64-NEXT:    retq
1577;
1578; WIN32-LABEL: smuloi16_load2:
1579; WIN32:       # %bb.0:
1580; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1581; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1582; WIN32-NEXT:    movzwl {{[0-9]+}}(%esp), %edx
1583; WIN32-NEXT:    imulw (%eax), %dx
1584; WIN32-NEXT:    seto %al
1585; WIN32-NEXT:    movw %dx, (%ecx)
1586; WIN32-NEXT:    retl
1587  %v2 = load i16, i16* %ptr2
1588  %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
1589  %val = extractvalue {i16, i1} %t, 0
1590  %obit = extractvalue {i16, i1} %t, 1
1591  store i16 %val, i16* %res
1592  ret i1 %obit
1593}
1594
1595define zeroext i1 @smuloi32_load(i32* %ptr1, i32 %v2, i32* %res) {
1596; SDAG-LABEL: smuloi32_load:
1597; SDAG:       # %bb.0:
1598; SDAG-NEXT:    imull (%rdi), %esi
1599; SDAG-NEXT:    seto %al
1600; SDAG-NEXT:    movl %esi, (%rdx)
1601; SDAG-NEXT:    retq
1602;
1603; FAST-LABEL: smuloi32_load:
1604; FAST:       # %bb.0:
1605; FAST-NEXT:    imull (%rdi), %esi
1606; FAST-NEXT:    seto %al
1607; FAST-NEXT:    movl %esi, (%rdx)
1608; FAST-NEXT:    andb $1, %al
1609; FAST-NEXT:    movzbl %al, %eax
1610; FAST-NEXT:    retq
1611;
1612; WIN64-LABEL: smuloi32_load:
1613; WIN64:       # %bb.0:
1614; WIN64-NEXT:    imull (%rcx), %edx
1615; WIN64-NEXT:    seto %al
1616; WIN64-NEXT:    movl %edx, (%r8)
1617; WIN64-NEXT:    retq
1618;
1619; WIN32-LABEL: smuloi32_load:
1620; WIN32:       # %bb.0:
1621; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1622; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1623; WIN32-NEXT:    movl (%eax), %edx
1624; WIN32-NEXT:    imull {{[0-9]+}}(%esp), %edx
1625; WIN32-NEXT:    seto %al
1626; WIN32-NEXT:    movl %edx, (%ecx)
1627; WIN32-NEXT:    retl
1628  %v1 = load i32, i32* %ptr1
1629  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
1630  %val = extractvalue {i32, i1} %t, 0
1631  %obit = extractvalue {i32, i1} %t, 1
1632  store i32 %val, i32* %res
1633  ret i1 %obit
1634}
1635
1636define zeroext i1 @smuloi32_load2(i32 %v1, i32* %ptr2, i32* %res) {
1637; SDAG-LABEL: smuloi32_load2:
1638; SDAG:       # %bb.0:
1639; SDAG-NEXT:    imull (%rsi), %edi
1640; SDAG-NEXT:    seto %al
1641; SDAG-NEXT:    movl %edi, (%rdx)
1642; SDAG-NEXT:    retq
1643;
1644; FAST-LABEL: smuloi32_load2:
1645; FAST:       # %bb.0:
1646; FAST-NEXT:    imull (%rsi), %edi
1647; FAST-NEXT:    seto %al
1648; FAST-NEXT:    movl %edi, (%rdx)
1649; FAST-NEXT:    andb $1, %al
1650; FAST-NEXT:    movzbl %al, %eax
1651; FAST-NEXT:    retq
1652;
1653; WIN64-LABEL: smuloi32_load2:
1654; WIN64:       # %bb.0:
1655; WIN64-NEXT:    imull (%rdx), %ecx
1656; WIN64-NEXT:    seto %al
1657; WIN64-NEXT:    movl %ecx, (%r8)
1658; WIN64-NEXT:    retq
1659;
1660; WIN32-LABEL: smuloi32_load2:
1661; WIN32:       # %bb.0:
1662; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1663; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1664; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edx
1665; WIN32-NEXT:    imull (%eax), %edx
1666; WIN32-NEXT:    seto %al
1667; WIN32-NEXT:    movl %edx, (%ecx)
1668; WIN32-NEXT:    retl
1669  %v2 = load i32, i32* %ptr2
1670  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
1671  %val = extractvalue {i32, i1} %t, 0
1672  %obit = extractvalue {i32, i1} %t, 1
1673  store i32 %val, i32* %res
1674  ret i1 %obit
1675}
1676
1677define zeroext i1 @smuloi64_load(i64* %ptr1, i64 %v2, i64* %res) {
1678; SDAG-LABEL: smuloi64_load:
1679; SDAG:       # %bb.0:
1680; SDAG-NEXT:    imulq (%rdi), %rsi
1681; SDAG-NEXT:    seto %al
1682; SDAG-NEXT:    movq %rsi, (%rdx)
1683; SDAG-NEXT:    retq
1684;
1685; FAST-LABEL: smuloi64_load:
1686; FAST:       # %bb.0:
1687; FAST-NEXT:    imulq (%rdi), %rsi
1688; FAST-NEXT:    seto %al
1689; FAST-NEXT:    movq %rsi, (%rdx)
1690; FAST-NEXT:    andb $1, %al
1691; FAST-NEXT:    movzbl %al, %eax
1692; FAST-NEXT:    retq
1693;
1694; WIN64-LABEL: smuloi64_load:
1695; WIN64:       # %bb.0:
1696; WIN64-NEXT:    imulq (%rcx), %rdx
1697; WIN64-NEXT:    seto %al
1698; WIN64-NEXT:    movq %rdx, (%r8)
1699; WIN64-NEXT:    retq
1700;
1701; WIN32-LABEL: smuloi64_load:
1702; WIN32:       # %bb.0:
1703; WIN32-NEXT:    pushl %ebp
1704; WIN32-NEXT:    pushl %ebx
1705; WIN32-NEXT:    pushl %edi
1706; WIN32-NEXT:    pushl %esi
1707; WIN32-NEXT:    subl $16, %esp
1708; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ebx
1709; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1710; WIN32-NEXT:    movl (%eax), %esi
1711; WIN32-NEXT:    movl 4(%eax), %ebp
1712; WIN32-NEXT:    sarl $31, %ebx
1713; WIN32-NEXT:    movl %ebx, %ecx
1714; WIN32-NEXT:    imull %ebp, %ecx
1715; WIN32-NEXT:    movl %ebx, %eax
1716; WIN32-NEXT:    mull %esi
1717; WIN32-NEXT:    movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
1718; WIN32-NEXT:    addl %ecx, %edx
1719; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1720; WIN32-NEXT:    imull %esi, %ebx
1721; WIN32-NEXT:    addl %edx, %ebx
1722; WIN32-NEXT:    movl %ebp, %ecx
1723; WIN32-NEXT:    movl %ebp, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
1724; WIN32-NEXT:    sarl $31, %ecx
1725; WIN32-NEXT:    movl %eax, %edi
1726; WIN32-NEXT:    imull %ecx, %edi
1727; WIN32-NEXT:    mull %ecx
1728; WIN32-NEXT:    addl %edi, %edx
1729; WIN32-NEXT:    imull {{[0-9]+}}(%esp), %ecx
1730; WIN32-NEXT:    addl %edx, %ecx
1731; WIN32-NEXT:    addl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Folded Reload
1732; WIN32-NEXT:    movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
1733; WIN32-NEXT:    adcl %ebx, %ecx
1734; WIN32-NEXT:    movl %esi, %eax
1735; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edi
1736; WIN32-NEXT:    mull %edi
1737; WIN32-NEXT:    movl %edx, %ebx
1738; WIN32-NEXT:    movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
1739; WIN32-NEXT:    movl %ebp, %eax
1740; WIN32-NEXT:    mull %edi
1741; WIN32-NEXT:    movl %edx, %ebp
1742; WIN32-NEXT:    movl %eax, %edi
1743; WIN32-NEXT:    addl %ebx, %edi
1744; WIN32-NEXT:    adcl $0, %ebp
1745; WIN32-NEXT:    movl %esi, %eax
1746; WIN32-NEXT:    mull {{[0-9]+}}(%esp)
1747; WIN32-NEXT:    movl %edx, %ebx
1748; WIN32-NEXT:    movl %eax, %esi
1749; WIN32-NEXT:    addl %edi, %esi
1750; WIN32-NEXT:    adcl %ebp, %ebx
1751; WIN32-NEXT:    setb {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Folded Spill
1752; WIN32-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Reload
1753; WIN32-NEXT:    mull {{[0-9]+}}(%esp)
1754; WIN32-NEXT:    addl %ebx, %eax
1755; WIN32-NEXT:    movzbl {{[-0-9]+}}(%e{{[sb]}}p), %edi # 1-byte Folded Reload
1756; WIN32-NEXT:    adcl %edi, %edx
1757; WIN32-NEXT:    addl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Folded Reload
1758; WIN32-NEXT:    adcl %ecx, %edx
1759; WIN32-NEXT:    movl %esi, %ecx
1760; WIN32-NEXT:    sarl $31, %ecx
1761; WIN32-NEXT:    xorl %ecx, %edx
1762; WIN32-NEXT:    xorl %eax, %ecx
1763; WIN32-NEXT:    orl %edx, %ecx
1764; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1765; WIN32-NEXT:    movl %esi, 4(%eax)
1766; WIN32-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
1767; WIN32-NEXT:    movl %ecx, (%eax)
1768; WIN32-NEXT:    setne %al
1769; WIN32-NEXT:    addl $16, %esp
1770; WIN32-NEXT:    popl %esi
1771; WIN32-NEXT:    popl %edi
1772; WIN32-NEXT:    popl %ebx
1773; WIN32-NEXT:    popl %ebp
1774; WIN32-NEXT:    retl
1775  %v1 = load i64, i64* %ptr1
1776  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
1777  %val = extractvalue {i64, i1} %t, 0
1778  %obit = extractvalue {i64, i1} %t, 1
1779  store i64 %val, i64* %res
1780  ret i1 %obit
1781}
1782
1783define zeroext i1 @smuloi64_load2(i64 %v1, i64* %ptr2, i64* %res) {
1784; SDAG-LABEL: smuloi64_load2:
1785; SDAG:       # %bb.0:
1786; SDAG-NEXT:    imulq (%rsi), %rdi
1787; SDAG-NEXT:    seto %al
1788; SDAG-NEXT:    movq %rdi, (%rdx)
1789; SDAG-NEXT:    retq
1790;
1791; FAST-LABEL: smuloi64_load2:
1792; FAST:       # %bb.0:
1793; FAST-NEXT:    imulq (%rsi), %rdi
1794; FAST-NEXT:    seto %al
1795; FAST-NEXT:    movq %rdi, (%rdx)
1796; FAST-NEXT:    andb $1, %al
1797; FAST-NEXT:    movzbl %al, %eax
1798; FAST-NEXT:    retq
1799;
1800; WIN64-LABEL: smuloi64_load2:
1801; WIN64:       # %bb.0:
1802; WIN64-NEXT:    imulq (%rdx), %rcx
1803; WIN64-NEXT:    seto %al
1804; WIN64-NEXT:    movq %rcx, (%r8)
1805; WIN64-NEXT:    retq
1806;
1807; WIN32-LABEL: smuloi64_load2:
1808; WIN32:       # %bb.0:
1809; WIN32-NEXT:    pushl %ebp
1810; WIN32-NEXT:    pushl %ebx
1811; WIN32-NEXT:    pushl %edi
1812; WIN32-NEXT:    pushl %esi
1813; WIN32-NEXT:    subl $12, %esp
1814; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1815; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1816; WIN32-NEXT:    movl (%eax), %ebp
1817; WIN32-NEXT:    movl 4(%eax), %ebx
1818; WIN32-NEXT:    movl %ecx, %edi
1819; WIN32-NEXT:    sarl $31, %edi
1820; WIN32-NEXT:    movl %ebp, %esi
1821; WIN32-NEXT:    imull %edi, %esi
1822; WIN32-NEXT:    movl %ebp, %eax
1823; WIN32-NEXT:    mull %edi
1824; WIN32-NEXT:    movl %eax, (%esp) # 4-byte Spill
1825; WIN32-NEXT:    addl %esi, %edx
1826; WIN32-NEXT:    movl %ebx, %esi
1827; WIN32-NEXT:    movl %ebx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
1828; WIN32-NEXT:    imull %ebx, %edi
1829; WIN32-NEXT:    addl %edx, %edi
1830; WIN32-NEXT:    sarl $31, %esi
1831; WIN32-NEXT:    movl %esi, %ebx
1832; WIN32-NEXT:    imull %ecx, %ebx
1833; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1834; WIN32-NEXT:    movl %esi, %eax
1835; WIN32-NEXT:    mull %ecx
1836; WIN32-NEXT:    addl %ebx, %edx
1837; WIN32-NEXT:    imull %ecx, %esi
1838; WIN32-NEXT:    addl %edx, %esi
1839; WIN32-NEXT:    addl (%esp), %eax # 4-byte Folded Reload
1840; WIN32-NEXT:    movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
1841; WIN32-NEXT:    adcl %edi, %esi
1842; WIN32-NEXT:    movl %ecx, %eax
1843; WIN32-NEXT:    mull %ebp
1844; WIN32-NEXT:    movl %edx, %edi
1845; WIN32-NEXT:    movl %eax, (%esp) # 4-byte Spill
1846; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1847; WIN32-NEXT:    mull %ebp
1848; WIN32-NEXT:    movl %edx, %ebx
1849; WIN32-NEXT:    movl %eax, %ecx
1850; WIN32-NEXT:    addl %edi, %ecx
1851; WIN32-NEXT:    adcl $0, %ebx
1852; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1853; WIN32-NEXT:    mull {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Reload
1854; WIN32-NEXT:    movl %edx, %edi
1855; WIN32-NEXT:    movl %eax, %ebp
1856; WIN32-NEXT:    addl %ecx, %ebp
1857; WIN32-NEXT:    adcl %ebx, %edi
1858; WIN32-NEXT:    setb %cl
1859; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1860; WIN32-NEXT:    mull {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Reload
1861; WIN32-NEXT:    addl %edi, %eax
1862; WIN32-NEXT:    movzbl %cl, %ecx
1863; WIN32-NEXT:    adcl %ecx, %edx
1864; WIN32-NEXT:    addl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Folded Reload
1865; WIN32-NEXT:    adcl %esi, %edx
1866; WIN32-NEXT:    movl %ebp, %ecx
1867; WIN32-NEXT:    sarl $31, %ecx
1868; WIN32-NEXT:    xorl %ecx, %edx
1869; WIN32-NEXT:    xorl %eax, %ecx
1870; WIN32-NEXT:    orl %edx, %ecx
1871; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1872; WIN32-NEXT:    movl %ebp, 4(%eax)
1873; WIN32-NEXT:    movl (%esp), %ecx # 4-byte Reload
1874; WIN32-NEXT:    movl %ecx, (%eax)
1875; WIN32-NEXT:    setne %al
1876; WIN32-NEXT:    addl $12, %esp
1877; WIN32-NEXT:    popl %esi
1878; WIN32-NEXT:    popl %edi
1879; WIN32-NEXT:    popl %ebx
1880; WIN32-NEXT:    popl %ebp
1881; WIN32-NEXT:    retl
1882  %v2 = load i64, i64* %ptr2
1883  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
1884  %val = extractvalue {i64, i1} %t, 0
1885  %obit = extractvalue {i64, i1} %t, 1
1886  store i64 %val, i64* %res
1887  ret i1 %obit
1888}
1889
1890define zeroext i1 @umuloi8_load(i8* %ptr1, i8 %v2, i8* %res) {
1891; SDAG-LABEL: umuloi8_load:
1892; SDAG:       # %bb.0:
1893; SDAG-NEXT:    movl %esi, %eax
1894; SDAG-NEXT:    # kill: def $al killed $al killed $eax
1895; SDAG-NEXT:    mulb (%rdi)
1896; SDAG-NEXT:    seto %cl
1897; SDAG-NEXT:    movb %al, (%rdx)
1898; SDAG-NEXT:    movl %ecx, %eax
1899; SDAG-NEXT:    retq
1900;
1901; FAST-LABEL: umuloi8_load:
1902; FAST:       # %bb.0:
1903; FAST-NEXT:    movb (%rdi), %al
1904; FAST-NEXT:    mulb %sil
1905; FAST-NEXT:    seto %cl
1906; FAST-NEXT:    movb %al, (%rdx)
1907; FAST-NEXT:    andb $1, %cl
1908; FAST-NEXT:    movzbl %cl, %eax
1909; FAST-NEXT:    retq
1910;
1911; WIN64-LABEL: umuloi8_load:
1912; WIN64:       # %bb.0:
1913; WIN64-NEXT:    movl %edx, %eax
1914; WIN64-NEXT:    mulb (%rcx)
1915; WIN64-NEXT:    seto %cl
1916; WIN64-NEXT:    movb %al, (%r8)
1917; WIN64-NEXT:    movl %ecx, %eax
1918; WIN64-NEXT:    retq
1919;
1920; WIN32-LABEL: umuloi8_load:
1921; WIN32:       # %bb.0:
1922; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edx
1923; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1924; WIN32-NEXT:    movb (%eax), %al
1925; WIN32-NEXT:    mulb {{[0-9]+}}(%esp)
1926; WIN32-NEXT:    seto %cl
1927; WIN32-NEXT:    movb %al, (%edx)
1928; WIN32-NEXT:    movl %ecx, %eax
1929; WIN32-NEXT:    retl
1930  %v1 = load i8, i8* %ptr1
1931  %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
1932  %val = extractvalue {i8, i1} %t, 0
1933  %obit = extractvalue {i8, i1} %t, 1
1934  store i8 %val, i8* %res
1935  ret i1 %obit
1936}
1937
1938define zeroext i1 @umuloi8_load2(i8 %v1, i8* %ptr2, i8* %res) {
1939; SDAG-LABEL: umuloi8_load2:
1940; SDAG:       # %bb.0:
1941; SDAG-NEXT:    movl %edi, %eax
1942; SDAG-NEXT:    # kill: def $al killed $al killed $eax
1943; SDAG-NEXT:    mulb (%rsi)
1944; SDAG-NEXT:    seto %cl
1945; SDAG-NEXT:    movb %al, (%rdx)
1946; SDAG-NEXT:    movl %ecx, %eax
1947; SDAG-NEXT:    retq
1948;
1949; FAST-LABEL: umuloi8_load2:
1950; FAST:       # %bb.0:
1951; FAST-NEXT:    movl %edi, %eax
1952; FAST-NEXT:    # kill: def $al killed $al killed $eax
1953; FAST-NEXT:    mulb (%rsi)
1954; FAST-NEXT:    seto %cl
1955; FAST-NEXT:    movb %al, (%rdx)
1956; FAST-NEXT:    andb $1, %cl
1957; FAST-NEXT:    movzbl %cl, %eax
1958; FAST-NEXT:    retq
1959;
1960; WIN64-LABEL: umuloi8_load2:
1961; WIN64:       # %bb.0:
1962; WIN64-NEXT:    movl %ecx, %eax
1963; WIN64-NEXT:    mulb (%rdx)
1964; WIN64-NEXT:    seto %cl
1965; WIN64-NEXT:    movb %al, (%r8)
1966; WIN64-NEXT:    movl %ecx, %eax
1967; WIN64-NEXT:    retq
1968;
1969; WIN32-LABEL: umuloi8_load2:
1970; WIN32:       # %bb.0:
1971; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edx
1972; WIN32-NEXT:    movb {{[0-9]+}}(%esp), %al
1973; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1974; WIN32-NEXT:    mulb (%ecx)
1975; WIN32-NEXT:    seto %cl
1976; WIN32-NEXT:    movb %al, (%edx)
1977; WIN32-NEXT:    movl %ecx, %eax
1978; WIN32-NEXT:    retl
1979  %v2 = load i8, i8* %ptr2
1980  %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
1981  %val = extractvalue {i8, i1} %t, 0
1982  %obit = extractvalue {i8, i1} %t, 1
1983  store i8 %val, i8* %res
1984  ret i1 %obit
1985}
1986
1987define zeroext i1 @umuloi16_load(i16* %ptr1, i16 %v2, i16* %res) {
1988; SDAG-LABEL: umuloi16_load:
1989; SDAG:       # %bb.0:
1990; SDAG-NEXT:    movq %rdx, %rcx
1991; SDAG-NEXT:    movl %esi, %eax
1992; SDAG-NEXT:    # kill: def $ax killed $ax killed $eax
1993; SDAG-NEXT:    mulw (%rdi)
1994; SDAG-NEXT:    seto %dl
1995; SDAG-NEXT:    movw %ax, (%rcx)
1996; SDAG-NEXT:    movl %edx, %eax
1997; SDAG-NEXT:    retq
1998;
1999; FAST-LABEL: umuloi16_load:
2000; FAST:       # %bb.0:
2001; FAST-NEXT:    movq %rdx, %rcx
2002; FAST-NEXT:    movzwl (%rdi), %eax
2003; FAST-NEXT:    mulw %si
2004; FAST-NEXT:    seto %dl
2005; FAST-NEXT:    movw %ax, (%rcx)
2006; FAST-NEXT:    andb $1, %dl
2007; FAST-NEXT:    movzbl %dl, %eax
2008; FAST-NEXT:    retq
2009;
2010; WIN64-LABEL: umuloi16_load:
2011; WIN64:       # %bb.0:
2012; WIN64-NEXT:    movl %edx, %eax
2013; WIN64-NEXT:    mulw (%rcx)
2014; WIN64-NEXT:    seto %cl
2015; WIN64-NEXT:    movw %ax, (%r8)
2016; WIN64-NEXT:    movl %ecx, %eax
2017; WIN64-NEXT:    retq
2018;
2019; WIN32-LABEL: umuloi16_load:
2020; WIN32:       # %bb.0:
2021; WIN32-NEXT:    pushl %esi
2022; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
2023; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
2024; WIN32-NEXT:    movzwl (%eax), %eax
2025; WIN32-NEXT:    mulw {{[0-9]+}}(%esp)
2026; WIN32-NEXT:    seto %cl
2027; WIN32-NEXT:    movw %ax, (%esi)
2028; WIN32-NEXT:    movl %ecx, %eax
2029; WIN32-NEXT:    popl %esi
2030; WIN32-NEXT:    retl
2031  %v1 = load i16, i16* %ptr1
2032  %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
2033  %val = extractvalue {i16, i1} %t, 0
2034  %obit = extractvalue {i16, i1} %t, 1
2035  store i16 %val, i16* %res
2036  ret i1 %obit
2037}
2038
2039define zeroext i1 @umuloi16_load2(i16 %v1, i16* %ptr2, i16* %res) {
2040; SDAG-LABEL: umuloi16_load2:
2041; SDAG:       # %bb.0:
2042; SDAG-NEXT:    movq %rdx, %rcx
2043; SDAG-NEXT:    movl %edi, %eax
2044; SDAG-NEXT:    # kill: def $ax killed $ax killed $eax
2045; SDAG-NEXT:    mulw (%rsi)
2046; SDAG-NEXT:    seto %dl
2047; SDAG-NEXT:    movw %ax, (%rcx)
2048; SDAG-NEXT:    movl %edx, %eax
2049; SDAG-NEXT:    retq
2050;
2051; FAST-LABEL: umuloi16_load2:
2052; FAST:       # %bb.0:
2053; FAST-NEXT:    movq %rdx, %rcx
2054; FAST-NEXT:    movl %edi, %eax
2055; FAST-NEXT:    # kill: def $ax killed $ax killed $eax
2056; FAST-NEXT:    mulw (%rsi)
2057; FAST-NEXT:    seto %dl
2058; FAST-NEXT:    movw %ax, (%rcx)
2059; FAST-NEXT:    andb $1, %dl
2060; FAST-NEXT:    movzbl %dl, %eax
2061; FAST-NEXT:    retq
2062;
2063; WIN64-LABEL: umuloi16_load2:
2064; WIN64:       # %bb.0:
2065; WIN64-NEXT:    movl %ecx, %eax
2066; WIN64-NEXT:    mulw (%rdx)
2067; WIN64-NEXT:    seto %cl
2068; WIN64-NEXT:    movw %ax, (%r8)
2069; WIN64-NEXT:    movl %ecx, %eax
2070; WIN64-NEXT:    retq
2071;
2072; WIN32-LABEL: umuloi16_load2:
2073; WIN32:       # %bb.0:
2074; WIN32-NEXT:    pushl %esi
2075; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
2076; WIN32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
2077; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
2078; WIN32-NEXT:    mulw (%ecx)
2079; WIN32-NEXT:    seto %cl
2080; WIN32-NEXT:    movw %ax, (%esi)
2081; WIN32-NEXT:    movl %ecx, %eax
2082; WIN32-NEXT:    popl %esi
2083; WIN32-NEXT:    retl
2084  %v2 = load i16, i16* %ptr2
2085  %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
2086  %val = extractvalue {i16, i1} %t, 0
2087  %obit = extractvalue {i16, i1} %t, 1
2088  store i16 %val, i16* %res
2089  ret i1 %obit
2090}
2091
2092define zeroext i1 @umuloi32_load(i32* %ptr1, i32 %v2, i32* %res) {
2093; SDAG-LABEL: umuloi32_load:
2094; SDAG:       # %bb.0:
2095; SDAG-NEXT:    movq %rdx, %rcx
2096; SDAG-NEXT:    movl %esi, %eax
2097; SDAG-NEXT:    mull (%rdi)
2098; SDAG-NEXT:    seto %dl
2099; SDAG-NEXT:    movl %eax, (%rcx)
2100; SDAG-NEXT:    movl %edx, %eax
2101; SDAG-NEXT:    retq
2102;
2103; FAST-LABEL: umuloi32_load:
2104; FAST:       # %bb.0:
2105; FAST-NEXT:    movq %rdx, %rcx
2106; FAST-NEXT:    movl (%rdi), %eax
2107; FAST-NEXT:    mull %esi
2108; FAST-NEXT:    seto %dl
2109; FAST-NEXT:    movl %eax, (%rcx)
2110; FAST-NEXT:    andb $1, %dl
2111; FAST-NEXT:    movzbl %dl, %eax
2112; FAST-NEXT:    retq
2113;
2114; WIN64-LABEL: umuloi32_load:
2115; WIN64:       # %bb.0:
2116; WIN64-NEXT:    movl %edx, %eax
2117; WIN64-NEXT:    mull (%rcx)
2118; WIN64-NEXT:    seto %cl
2119; WIN64-NEXT:    movl %eax, (%r8)
2120; WIN64-NEXT:    movl %ecx, %eax
2121; WIN64-NEXT:    retq
2122;
2123; WIN32-LABEL: umuloi32_load:
2124; WIN32:       # %bb.0:
2125; WIN32-NEXT:    pushl %esi
2126; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
2127; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
2128; WIN32-NEXT:    movl (%eax), %eax
2129; WIN32-NEXT:    mull {{[0-9]+}}(%esp)
2130; WIN32-NEXT:    seto %cl
2131; WIN32-NEXT:    movl %eax, (%esi)
2132; WIN32-NEXT:    movl %ecx, %eax
2133; WIN32-NEXT:    popl %esi
2134; WIN32-NEXT:    retl
2135  %v1 = load i32, i32* %ptr1
2136  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
2137  %val = extractvalue {i32, i1} %t, 0
2138  %obit = extractvalue {i32, i1} %t, 1
2139  store i32 %val, i32* %res
2140  ret i1 %obit
2141}
2142
2143define zeroext i1 @umuloi32_load2(i32 %v1, i32* %ptr2, i32* %res) {
2144; SDAG-LABEL: umuloi32_load2:
2145; SDAG:       # %bb.0:
2146; SDAG-NEXT:    movq %rdx, %rcx
2147; SDAG-NEXT:    movl %edi, %eax
2148; SDAG-NEXT:    mull (%rsi)
2149; SDAG-NEXT:    seto %dl
2150; SDAG-NEXT:    movl %eax, (%rcx)
2151; SDAG-NEXT:    movl %edx, %eax
2152; SDAG-NEXT:    retq
2153;
2154; FAST-LABEL: umuloi32_load2:
2155; FAST:       # %bb.0:
2156; FAST-NEXT:    movq %rdx, %rcx
2157; FAST-NEXT:    movl %edi, %eax
2158; FAST-NEXT:    mull (%rsi)
2159; FAST-NEXT:    seto %dl
2160; FAST-NEXT:    movl %eax, (%rcx)
2161; FAST-NEXT:    andb $1, %dl
2162; FAST-NEXT:    movzbl %dl, %eax
2163; FAST-NEXT:    retq
2164;
2165; WIN64-LABEL: umuloi32_load2:
2166; WIN64:       # %bb.0:
2167; WIN64-NEXT:    movl %ecx, %eax
2168; WIN64-NEXT:    mull (%rdx)
2169; WIN64-NEXT:    seto %cl
2170; WIN64-NEXT:    movl %eax, (%r8)
2171; WIN64-NEXT:    movl %ecx, %eax
2172; WIN64-NEXT:    retq
2173;
2174; WIN32-LABEL: umuloi32_load2:
2175; WIN32:       # %bb.0:
2176; WIN32-NEXT:    pushl %esi
2177; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
2178; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
2179; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
2180; WIN32-NEXT:    mull (%ecx)
2181; WIN32-NEXT:    seto %cl
2182; WIN32-NEXT:    movl %eax, (%esi)
2183; WIN32-NEXT:    movl %ecx, %eax
2184; WIN32-NEXT:    popl %esi
2185; WIN32-NEXT:    retl
2186  %v2 = load i32, i32* %ptr2
2187  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
2188  %val = extractvalue {i32, i1} %t, 0
2189  %obit = extractvalue {i32, i1} %t, 1
2190  store i32 %val, i32* %res
2191  ret i1 %obit
2192}
2193
2194define zeroext i1 @umuloi64_load(i64* %ptr1, i64 %v2, i64* %res) {
2195; SDAG-LABEL: umuloi64_load:
2196; SDAG:       # %bb.0:
2197; SDAG-NEXT:    movq %rdx, %rcx
2198; SDAG-NEXT:    movq %rsi, %rax
2199; SDAG-NEXT:    mulq (%rdi)
2200; SDAG-NEXT:    seto %dl
2201; SDAG-NEXT:    movq %rax, (%rcx)
2202; SDAG-NEXT:    movl %edx, %eax
2203; SDAG-NEXT:    retq
2204;
2205; FAST-LABEL: umuloi64_load:
2206; FAST:       # %bb.0:
2207; FAST-NEXT:    movq %rdx, %rcx
2208; FAST-NEXT:    movq (%rdi), %rax
2209; FAST-NEXT:    mulq %rsi
2210; FAST-NEXT:    seto %dl
2211; FAST-NEXT:    movq %rax, (%rcx)
2212; FAST-NEXT:    andb $1, %dl
2213; FAST-NEXT:    movzbl %dl, %eax
2214; FAST-NEXT:    retq
2215;
2216; WIN64-LABEL: umuloi64_load:
2217; WIN64:       # %bb.0:
2218; WIN64-NEXT:    movq %rdx, %rax
2219; WIN64-NEXT:    mulq (%rcx)
2220; WIN64-NEXT:    seto %cl
2221; WIN64-NEXT:    movq %rax, (%r8)
2222; WIN64-NEXT:    movl %ecx, %eax
2223; WIN64-NEXT:    retq
2224;
2225; WIN32-LABEL: umuloi64_load:
2226; WIN32:       # %bb.0:
2227; WIN32-NEXT:    pushl %ebp
2228; WIN32-NEXT:    pushl %ebx
2229; WIN32-NEXT:    pushl %edi
2230; WIN32-NEXT:    pushl %esi
2231; WIN32-NEXT:    pushl %eax
2232; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ebp
2233; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
2234; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
2235; WIN32-NEXT:    movl (%eax), %ecx
2236; WIN32-NEXT:    movl 4(%eax), %eax
2237; WIN32-NEXT:    testl %esi, %esi
2238; WIN32-NEXT:    setne %dl
2239; WIN32-NEXT:    testl %eax, %eax
2240; WIN32-NEXT:    setne %bl
2241; WIN32-NEXT:    andb %dl, %bl
2242; WIN32-NEXT:    mull %ebp
2243; WIN32-NEXT:    movl %eax, %edi
2244; WIN32-NEXT:    seto {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Folded Spill
2245; WIN32-NEXT:    movl %esi, %eax
2246; WIN32-NEXT:    mull %ecx
2247; WIN32-NEXT:    movl %eax, %esi
2248; WIN32-NEXT:    seto %bh
2249; WIN32-NEXT:    orb {{[-0-9]+}}(%e{{[sb]}}p), %bh # 1-byte Folded Reload
2250; WIN32-NEXT:    addl %edi, %esi
2251; WIN32-NEXT:    movl %ecx, %eax
2252; WIN32-NEXT:    mull %ebp
2253; WIN32-NEXT:    addl %esi, %edx
2254; WIN32-NEXT:    setb %cl
2255; WIN32-NEXT:    orb %bh, %cl
2256; WIN32-NEXT:    orb %bl, %cl
2257; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
2258; WIN32-NEXT:    movl %eax, (%esi)
2259; WIN32-NEXT:    movl %edx, 4(%esi)
2260; WIN32-NEXT:    movl %ecx, %eax
2261; WIN32-NEXT:    addl $4, %esp
2262; WIN32-NEXT:    popl %esi
2263; WIN32-NEXT:    popl %edi
2264; WIN32-NEXT:    popl %ebx
2265; WIN32-NEXT:    popl %ebp
2266; WIN32-NEXT:    retl
2267  %v1 = load i64, i64* %ptr1
2268  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
2269  %val = extractvalue {i64, i1} %t, 0
2270  %obit = extractvalue {i64, i1} %t, 1
2271  store i64 %val, i64* %res
2272  ret i1 %obit
2273}
2274
2275define zeroext i1 @umuloi64_load2(i64 %v1, i64* %ptr2, i64* %res) {
2276; SDAG-LABEL: umuloi64_load2:
2277; SDAG:       # %bb.0:
2278; SDAG-NEXT:    movq %rdx, %rcx
2279; SDAG-NEXT:    movq %rdi, %rax
2280; SDAG-NEXT:    mulq (%rsi)
2281; SDAG-NEXT:    seto %dl
2282; SDAG-NEXT:    movq %rax, (%rcx)
2283; SDAG-NEXT:    movl %edx, %eax
2284; SDAG-NEXT:    retq
2285;
2286; FAST-LABEL: umuloi64_load2:
2287; FAST:       # %bb.0:
2288; FAST-NEXT:    movq %rdx, %rcx
2289; FAST-NEXT:    movq %rdi, %rax
2290; FAST-NEXT:    mulq (%rsi)
2291; FAST-NEXT:    seto %dl
2292; FAST-NEXT:    movq %rax, (%rcx)
2293; FAST-NEXT:    andb $1, %dl
2294; FAST-NEXT:    movzbl %dl, %eax
2295; FAST-NEXT:    retq
2296;
2297; WIN64-LABEL: umuloi64_load2:
2298; WIN64:       # %bb.0:
2299; WIN64-NEXT:    movq %rcx, %rax
2300; WIN64-NEXT:    mulq (%rdx)
2301; WIN64-NEXT:    seto %cl
2302; WIN64-NEXT:    movq %rax, (%r8)
2303; WIN64-NEXT:    movl %ecx, %eax
2304; WIN64-NEXT:    retq
2305;
2306; WIN32-LABEL: umuloi64_load2:
2307; WIN32:       # %bb.0:
2308; WIN32-NEXT:    pushl %ebp
2309; WIN32-NEXT:    pushl %ebx
2310; WIN32-NEXT:    pushl %edi
2311; WIN32-NEXT:    pushl %esi
2312; WIN32-NEXT:    pushl %eax
2313; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ebp
2314; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
2315; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edx
2316; WIN32-NEXT:    movl (%edx), %ecx
2317; WIN32-NEXT:    movl 4(%edx), %esi
2318; WIN32-NEXT:    testl %eax, %eax
2319; WIN32-NEXT:    setne %dl
2320; WIN32-NEXT:    testl %esi, %esi
2321; WIN32-NEXT:    setne %bl
2322; WIN32-NEXT:    andb %dl, %bl
2323; WIN32-NEXT:    mull %ecx
2324; WIN32-NEXT:    movl %eax, %edi
2325; WIN32-NEXT:    seto {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Folded Spill
2326; WIN32-NEXT:    movl %esi, %eax
2327; WIN32-NEXT:    mull %ebp
2328; WIN32-NEXT:    movl %eax, %esi
2329; WIN32-NEXT:    seto %bh
2330; WIN32-NEXT:    orb {{[-0-9]+}}(%e{{[sb]}}p), %bh # 1-byte Folded Reload
2331; WIN32-NEXT:    addl %edi, %esi
2332; WIN32-NEXT:    movl %ebp, %eax
2333; WIN32-NEXT:    mull %ecx
2334; WIN32-NEXT:    addl %esi, %edx
2335; WIN32-NEXT:    setb %cl
2336; WIN32-NEXT:    orb %bh, %cl
2337; WIN32-NEXT:    orb %bl, %cl
2338; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
2339; WIN32-NEXT:    movl %eax, (%esi)
2340; WIN32-NEXT:    movl %edx, 4(%esi)
2341; WIN32-NEXT:    movl %ecx, %eax
2342; WIN32-NEXT:    addl $4, %esp
2343; WIN32-NEXT:    popl %esi
2344; WIN32-NEXT:    popl %edi
2345; WIN32-NEXT:    popl %ebx
2346; WIN32-NEXT:    popl %ebp
2347; WIN32-NEXT:    retl
2348  %v2 = load i64, i64* %ptr2
2349  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
2350  %val = extractvalue {i64, i1} %t, 0
2351  %obit = extractvalue {i64, i1} %t, 1
2352  store i64 %val, i64* %res
2353  ret i1 %obit
2354}
2355
2356declare {i8,  i1} @llvm.smul.with.overflow.i8 (i8,  i8 ) nounwind readnone
2357declare {i16, i1} @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone
2358declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
2359declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
2360declare {i8,  i1} @llvm.umul.with.overflow.i8 (i8,  i8 ) nounwind readnone
2361declare {i16, i1} @llvm.umul.with.overflow.i16(i16, i16) nounwind readnone
2362declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
2363declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone
2364
2365!0 = !{!"branch_weights", i32 0, i32 2147483647}
2366