• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -disable-peephole -mtriple=x86_64-darwin-unknown < %s | FileCheck %s --check-prefixes=CHECK,SDAG
3; RUN: llc -disable-peephole -mtriple=x86_64-darwin-unknown -fast-isel -fast-isel-abort=1 < %s | FileCheck %s --check-prefixes=CHECK,FAST
4; RUN: llc -disable-peephole -mtriple=x86_64-darwin-unknown -mcpu=knl < %s | FileCheck %s --check-prefixes=CHECK,SDAG
5
6define {i64, i1} @t1() nounwind {
7; CHECK-LABEL: t1:
8; CHECK:       ## %bb.0:
9; CHECK-NEXT:    movl $8, %ecx
10; CHECK-NEXT:    movl $9, %eax
11; CHECK-NEXT:    mulq %rcx
12; CHECK-NEXT:    seto %dl
13; CHECK-NEXT:    retq
14  %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 8)
15  ret {i64, i1} %1
16}
17
18define {i64, i1} @t2() nounwind {
19; CHECK-LABEL: t2:
20; CHECK:       ## %bb.0:
21; CHECK-NEXT:    xorl %eax, %eax
22; CHECK-NEXT:    xorl %edx, %edx
23; CHECK-NEXT:    retq
24  %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 0)
25  ret {i64, i1} %1
26}
27
28define {i64, i1} @t3() nounwind {
29; CHECK-LABEL: t3:
30; CHECK:       ## %bb.0:
31; CHECK-NEXT:    movq $-1, %rcx
32; CHECK-NEXT:    movl $9, %eax
33; CHECK-NEXT:    mulq %rcx
34; CHECK-NEXT:    seto %dl
35; CHECK-NEXT:    retq
36  %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 -1)
37  ret {i64, i1} %1
38}
39
40; SMULO
41define zeroext i1 @smuloi8(i8 %v1, i8 %v2, i8* %res) {
42; SDAG-LABEL: smuloi8:
43; SDAG:       ## %bb.0:
44; SDAG-NEXT:    movl %edi, %eax
45; SDAG-NEXT:    ## kill: def $al killed $al killed $eax
46; SDAG-NEXT:    imulb %sil
47; SDAG-NEXT:    seto %cl
48; SDAG-NEXT:    movb %al, (%rdx)
49; SDAG-NEXT:    movl %ecx, %eax
50; SDAG-NEXT:    retq
51;
52; FAST-LABEL: smuloi8:
53; FAST:       ## %bb.0:
54; FAST-NEXT:    movl %edi, %eax
55; FAST-NEXT:    ## kill: def $al killed $al killed $eax
56; FAST-NEXT:    imulb %sil
57; FAST-NEXT:    seto %cl
58; FAST-NEXT:    movb %al, (%rdx)
59; FAST-NEXT:    andb $1, %cl
60; FAST-NEXT:    movzbl %cl, %eax
61; FAST-NEXT:    retq
62  %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
63  %val = extractvalue {i8, i1} %t, 0
64  %obit = extractvalue {i8, i1} %t, 1
65  store i8 %val, i8* %res
66  ret i1 %obit
67}
68
69define zeroext i1 @smuloi16(i16 %v1, i16 %v2, i16* %res) {
70; SDAG-LABEL: smuloi16:
71; SDAG:       ## %bb.0:
72; SDAG-NEXT:    imulw %si, %di
73; SDAG-NEXT:    seto %al
74; SDAG-NEXT:    movw %di, (%rdx)
75; SDAG-NEXT:    retq
76;
77; FAST-LABEL: smuloi16:
78; FAST:       ## %bb.0:
79; FAST-NEXT:    imulw %si, %di
80; FAST-NEXT:    seto %al
81; FAST-NEXT:    movw %di, (%rdx)
82; FAST-NEXT:    andb $1, %al
83; FAST-NEXT:    movzbl %al, %eax
84; FAST-NEXT:    retq
85  %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
86  %val = extractvalue {i16, i1} %t, 0
87  %obit = extractvalue {i16, i1} %t, 1
88  store i16 %val, i16* %res
89  ret i1 %obit
90}
91
92define zeroext i1 @smuloi32(i32 %v1, i32 %v2, i32* %res) {
93; SDAG-LABEL: smuloi32:
94; SDAG:       ## %bb.0:
95; SDAG-NEXT:    imull %esi, %edi
96; SDAG-NEXT:    seto %al
97; SDAG-NEXT:    movl %edi, (%rdx)
98; SDAG-NEXT:    retq
99;
100; FAST-LABEL: smuloi32:
101; FAST:       ## %bb.0:
102; FAST-NEXT:    imull %esi, %edi
103; FAST-NEXT:    seto %al
104; FAST-NEXT:    movl %edi, (%rdx)
105; FAST-NEXT:    andb $1, %al
106; FAST-NEXT:    movzbl %al, %eax
107; FAST-NEXT:    retq
108  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
109  %val = extractvalue {i32, i1} %t, 0
110  %obit = extractvalue {i32, i1} %t, 1
111  store i32 %val, i32* %res
112  ret i1 %obit
113}
114
115define zeroext i1 @smuloi64(i64 %v1, i64 %v2, i64* %res) {
116; SDAG-LABEL: smuloi64:
117; SDAG:       ## %bb.0:
118; SDAG-NEXT:    imulq %rsi, %rdi
119; SDAG-NEXT:    seto %al
120; SDAG-NEXT:    movq %rdi, (%rdx)
121; SDAG-NEXT:    retq
122;
123; FAST-LABEL: smuloi64:
124; FAST:       ## %bb.0:
125; FAST-NEXT:    imulq %rsi, %rdi
126; FAST-NEXT:    seto %al
127; FAST-NEXT:    movq %rdi, (%rdx)
128; FAST-NEXT:    andb $1, %al
129; FAST-NEXT:    movzbl %al, %eax
130; FAST-NEXT:    retq
131  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
132  %val = extractvalue {i64, i1} %t, 0
133  %obit = extractvalue {i64, i1} %t, 1
134  store i64 %val, i64* %res
135  ret i1 %obit
136}
137
138; UMULO
139define zeroext i1 @umuloi8(i8 %v1, i8 %v2, i8* %res) {
140; SDAG-LABEL: umuloi8:
141; SDAG:       ## %bb.0:
142; SDAG-NEXT:    movl %edi, %eax
143; SDAG-NEXT:    ## kill: def $al killed $al killed $eax
144; SDAG-NEXT:    mulb %sil
145; SDAG-NEXT:    seto %cl
146; SDAG-NEXT:    movb %al, (%rdx)
147; SDAG-NEXT:    movl %ecx, %eax
148; SDAG-NEXT:    retq
149;
150; FAST-LABEL: umuloi8:
151; FAST:       ## %bb.0:
152; FAST-NEXT:    movl %edi, %eax
153; FAST-NEXT:    ## kill: def $al killed $al killed $eax
154; FAST-NEXT:    mulb %sil
155; FAST-NEXT:    seto %cl
156; FAST-NEXT:    movb %al, (%rdx)
157; FAST-NEXT:    andb $1, %cl
158; FAST-NEXT:    movzbl %cl, %eax
159; FAST-NEXT:    retq
160  %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
161  %val = extractvalue {i8, i1} %t, 0
162  %obit = extractvalue {i8, i1} %t, 1
163  store i8 %val, i8* %res
164  ret i1 %obit
165}
166
167define zeroext i1 @umuloi16(i16 %v1, i16 %v2, i16* %res) {
168; SDAG-LABEL: umuloi16:
169; SDAG:       ## %bb.0:
170; SDAG-NEXT:    movq %rdx, %rcx
171; SDAG-NEXT:    movl %edi, %eax
172; SDAG-NEXT:    ## kill: def $ax killed $ax killed $eax
173; SDAG-NEXT:    mulw %si
174; SDAG-NEXT:    seto %dl
175; SDAG-NEXT:    movw %ax, (%rcx)
176; SDAG-NEXT:    movl %edx, %eax
177; SDAG-NEXT:    retq
178;
179; FAST-LABEL: umuloi16:
180; FAST:       ## %bb.0:
181; FAST-NEXT:    movq %rdx, %rcx
182; FAST-NEXT:    movl %edi, %eax
183; FAST-NEXT:    ## kill: def $ax killed $ax killed $eax
184; FAST-NEXT:    mulw %si
185; FAST-NEXT:    seto %dl
186; FAST-NEXT:    movw %ax, (%rcx)
187; FAST-NEXT:    andb $1, %dl
188; FAST-NEXT:    movzbl %dl, %eax
189; FAST-NEXT:    retq
190  %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
191  %val = extractvalue {i16, i1} %t, 0
192  %obit = extractvalue {i16, i1} %t, 1
193  store i16 %val, i16* %res
194  ret i1 %obit
195}
196
197define zeroext i1 @umuloi32(i32 %v1, i32 %v2, i32* %res) {
198; SDAG-LABEL: umuloi32:
199; SDAG:       ## %bb.0:
200; SDAG-NEXT:    movq %rdx, %rcx
201; SDAG-NEXT:    movl %edi, %eax
202; SDAG-NEXT:    mull %esi
203; SDAG-NEXT:    seto %dl
204; SDAG-NEXT:    movl %eax, (%rcx)
205; SDAG-NEXT:    movl %edx, %eax
206; SDAG-NEXT:    retq
207;
208; FAST-LABEL: umuloi32:
209; FAST:       ## %bb.0:
210; FAST-NEXT:    movq %rdx, %rcx
211; FAST-NEXT:    movl %edi, %eax
212; FAST-NEXT:    mull %esi
213; FAST-NEXT:    seto %dl
214; FAST-NEXT:    movl %eax, (%rcx)
215; FAST-NEXT:    andb $1, %dl
216; FAST-NEXT:    movzbl %dl, %eax
217; FAST-NEXT:    retq
218  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
219  %val = extractvalue {i32, i1} %t, 0
220  %obit = extractvalue {i32, i1} %t, 1
221  store i32 %val, i32* %res
222  ret i1 %obit
223}
224
225define zeroext i1 @umuloi64(i64 %v1, i64 %v2, i64* %res) {
226; SDAG-LABEL: umuloi64:
227; SDAG:       ## %bb.0:
228; SDAG-NEXT:    movq %rdx, %rcx
229; SDAG-NEXT:    movq %rdi, %rax
230; SDAG-NEXT:    mulq %rsi
231; SDAG-NEXT:    seto %dl
232; SDAG-NEXT:    movq %rax, (%rcx)
233; SDAG-NEXT:    movl %edx, %eax
234; SDAG-NEXT:    retq
235;
236; FAST-LABEL: umuloi64:
237; FAST:       ## %bb.0:
238; FAST-NEXT:    movq %rdx, %rcx
239; FAST-NEXT:    movq %rdi, %rax
240; FAST-NEXT:    mulq %rsi
241; FAST-NEXT:    seto %dl
242; FAST-NEXT:    movq %rax, (%rcx)
243; FAST-NEXT:    andb $1, %dl
244; FAST-NEXT:    movzbl %dl, %eax
245; FAST-NEXT:    retq
246  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
247  %val = extractvalue {i64, i1} %t, 0
248  %obit = extractvalue {i64, i1} %t, 1
249  store i64 %val, i64* %res
250  ret i1 %obit
251}
252
253;
254; Check the use of the overflow bit in combination with a select instruction.
255;
256define i32 @smuloselecti32(i32 %v1, i32 %v2) {
257; CHECK-LABEL: smuloselecti32:
258; CHECK:       ## %bb.0:
259; CHECK-NEXT:    movl %esi, %eax
260; CHECK-NEXT:    movl %edi, %ecx
261; CHECK-NEXT:    imull %esi, %ecx
262; CHECK-NEXT:    cmovol %edi, %eax
263; CHECK-NEXT:    retq
264  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
265  %obit = extractvalue {i32, i1} %t, 1
266  %ret = select i1 %obit, i32 %v1, i32 %v2
267  ret i32 %ret
268}
269
270define i64 @smuloselecti64(i64 %v1, i64 %v2) {
271; CHECK-LABEL: smuloselecti64:
272; CHECK:       ## %bb.0:
273; CHECK-NEXT:    movq %rsi, %rax
274; CHECK-NEXT:    movq %rdi, %rcx
275; CHECK-NEXT:    imulq %rsi, %rcx
276; CHECK-NEXT:    cmovoq %rdi, %rax
277; CHECK-NEXT:    retq
278  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
279  %obit = extractvalue {i64, i1} %t, 1
280  %ret = select i1 %obit, i64 %v1, i64 %v2
281  ret i64 %ret
282}
283
284define i32 @umuloselecti32(i32 %v1, i32 %v2) {
285; CHECK-LABEL: umuloselecti32:
286; CHECK:       ## %bb.0:
287; CHECK-NEXT:    movl %edi, %eax
288; CHECK-NEXT:    mull %esi
289; CHECK-NEXT:    cmovol %edi, %esi
290; CHECK-NEXT:    movl %esi, %eax
291; CHECK-NEXT:    retq
292  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
293  %obit = extractvalue {i32, i1} %t, 1
294  %ret = select i1 %obit, i32 %v1, i32 %v2
295  ret i32 %ret
296}
297
298define i64 @umuloselecti64(i64 %v1, i64 %v2) {
299; CHECK-LABEL: umuloselecti64:
300; CHECK:       ## %bb.0:
301; CHECK-NEXT:    movq %rdi, %rax
302; CHECK-NEXT:    mulq %rsi
303; CHECK-NEXT:    cmovoq %rdi, %rsi
304; CHECK-NEXT:    movq %rsi, %rax
305; CHECK-NEXT:    retq
306  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
307  %obit = extractvalue {i64, i1} %t, 1
308  %ret = select i1 %obit, i64 %v1, i64 %v2
309  ret i64 %ret
310}
311
312;
313; Check the use of the overflow bit in combination with a branch instruction.
314;
315define zeroext i1 @smulobri8(i8 %v1, i8 %v2) {
316; SDAG-LABEL: smulobri8:
317; SDAG:       ## %bb.0:
318; SDAG-NEXT:    movl %edi, %eax
319; SDAG-NEXT:    ## kill: def $al killed $al killed $eax
320; SDAG-NEXT:    imulb %sil
321; SDAG-NEXT:    jo LBB15_1
322; SDAG-NEXT:  ## %bb.2: ## %continue
323; SDAG-NEXT:    movb $1, %al
324; SDAG-NEXT:    retq
325; SDAG-NEXT:  LBB15_1: ## %overflow
326; SDAG-NEXT:    xorl %eax, %eax
327; SDAG-NEXT:    retq
328;
329; FAST-LABEL: smulobri8:
330; FAST:       ## %bb.0:
331; FAST-NEXT:    movl %edi, %eax
332; FAST-NEXT:    ## kill: def $al killed $al killed $eax
333; FAST-NEXT:    imulb %sil
334; FAST-NEXT:    seto %al
335; FAST-NEXT:    testb $1, %al
336; FAST-NEXT:    jne LBB15_1
337; FAST-NEXT:  ## %bb.2: ## %continue
338; FAST-NEXT:    movb $1, %al
339; FAST-NEXT:    andb $1, %al
340; FAST-NEXT:    movzbl %al, %eax
341; FAST-NEXT:    retq
342; FAST-NEXT:  LBB15_1: ## %overflow
343; FAST-NEXT:    xorl %eax, %eax
344; FAST-NEXT:    andb $1, %al
345; FAST-NEXT:    movzbl %al, %eax
346; FAST-NEXT:    retq
347  %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
348  %val = extractvalue {i8, i1} %t, 0
349  %obit = extractvalue {i8, i1} %t, 1
350  br i1 %obit, label %overflow, label %continue, !prof !0
351
352overflow:
353  ret i1 false
354
355continue:
356  ret i1 true
357}
358
359define zeroext i1 @smulobri16(i16 %v1, i16 %v2) {
360; SDAG-LABEL: smulobri16:
361; SDAG:       ## %bb.0:
362; SDAG-NEXT:    imulw %si, %di
363; SDAG-NEXT:    jo LBB16_1
364; SDAG-NEXT:  ## %bb.2: ## %continue
365; SDAG-NEXT:    movb $1, %al
366; SDAG-NEXT:    retq
367; SDAG-NEXT:  LBB16_1: ## %overflow
368; SDAG-NEXT:    xorl %eax, %eax
369; SDAG-NEXT:    retq
370;
371; FAST-LABEL: smulobri16:
372; FAST:       ## %bb.0:
373; FAST-NEXT:    imulw %si, %di
374; FAST-NEXT:    seto %al
375; FAST-NEXT:    testb $1, %al
376; FAST-NEXT:    jne LBB16_1
377; FAST-NEXT:  ## %bb.2: ## %continue
378; FAST-NEXT:    movb $1, %al
379; FAST-NEXT:    andb $1, %al
380; FAST-NEXT:    movzbl %al, %eax
381; FAST-NEXT:    retq
382; FAST-NEXT:  LBB16_1: ## %overflow
383; FAST-NEXT:    xorl %eax, %eax
384; FAST-NEXT:    andb $1, %al
385; FAST-NEXT:    movzbl %al, %eax
386; FAST-NEXT:    retq
387  %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
388  %val = extractvalue {i16, i1} %t, 0
389  %obit = extractvalue {i16, i1} %t, 1
390  br i1 %obit, label %overflow, label %continue, !prof !0
391
392overflow:
393  ret i1 false
394
395continue:
396  ret i1 true
397}
398
399define zeroext i1 @smulobri32(i32 %v1, i32 %v2) {
400; SDAG-LABEL: smulobri32:
401; SDAG:       ## %bb.0:
402; SDAG-NEXT:    imull %esi, %edi
403; SDAG-NEXT:    jo LBB17_1
404; SDAG-NEXT:  ## %bb.2: ## %continue
405; SDAG-NEXT:    movb $1, %al
406; SDAG-NEXT:    retq
407; SDAG-NEXT:  LBB17_1: ## %overflow
408; SDAG-NEXT:    xorl %eax, %eax
409; SDAG-NEXT:    retq
410;
411; FAST-LABEL: smulobri32:
412; FAST:       ## %bb.0:
413; FAST-NEXT:    imull %esi, %edi
414; FAST-NEXT:    jo LBB17_1
415; FAST-NEXT:  ## %bb.2: ## %continue
416; FAST-NEXT:    movb $1, %al
417; FAST-NEXT:    andb $1, %al
418; FAST-NEXT:    movzbl %al, %eax
419; FAST-NEXT:    retq
420; FAST-NEXT:  LBB17_1: ## %overflow
421; FAST-NEXT:    xorl %eax, %eax
422; FAST-NEXT:    andb $1, %al
423; FAST-NEXT:    movzbl %al, %eax
424; FAST-NEXT:    retq
425  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
426  %val = extractvalue {i32, i1} %t, 0
427  %obit = extractvalue {i32, i1} %t, 1
428  br i1 %obit, label %overflow, label %continue, !prof !0
429
430overflow:
431  ret i1 false
432
433continue:
434  ret i1 true
435}
436
437define zeroext i1 @smulobri64(i64 %v1, i64 %v2) {
438; SDAG-LABEL: smulobri64:
439; SDAG:       ## %bb.0:
440; SDAG-NEXT:    imulq %rsi, %rdi
441; SDAG-NEXT:    jo LBB18_1
442; SDAG-NEXT:  ## %bb.2: ## %continue
443; SDAG-NEXT:    movb $1, %al
444; SDAG-NEXT:    retq
445; SDAG-NEXT:  LBB18_1: ## %overflow
446; SDAG-NEXT:    xorl %eax, %eax
447; SDAG-NEXT:    retq
448;
449; FAST-LABEL: smulobri64:
450; FAST:       ## %bb.0:
451; FAST-NEXT:    imulq %rsi, %rdi
452; FAST-NEXT:    jo LBB18_1
453; FAST-NEXT:  ## %bb.2: ## %continue
454; FAST-NEXT:    movb $1, %al
455; FAST-NEXT:    andb $1, %al
456; FAST-NEXT:    movzbl %al, %eax
457; FAST-NEXT:    retq
458; FAST-NEXT:  LBB18_1: ## %overflow
459; FAST-NEXT:    xorl %eax, %eax
460; FAST-NEXT:    andb $1, %al
461; FAST-NEXT:    movzbl %al, %eax
462; FAST-NEXT:    retq
463  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
464  %val = extractvalue {i64, i1} %t, 0
465  %obit = extractvalue {i64, i1} %t, 1
466  br i1 %obit, label %overflow, label %continue, !prof !0
467
468overflow:
469  ret i1 false
470
471continue:
472  ret i1 true
473}
474
475define zeroext i1 @umulobri8(i8 %v1, i8 %v2) {
476; SDAG-LABEL: umulobri8:
477; SDAG:       ## %bb.0:
478; SDAG-NEXT:    movl %edi, %eax
479; SDAG-NEXT:    ## kill: def $al killed $al killed $eax
480; SDAG-NEXT:    mulb %sil
481; SDAG-NEXT:    jo LBB19_1
482; SDAG-NEXT:  ## %bb.2: ## %continue
483; SDAG-NEXT:    movb $1, %al
484; SDAG-NEXT:    retq
485; SDAG-NEXT:  LBB19_1: ## %overflow
486; SDAG-NEXT:    xorl %eax, %eax
487; SDAG-NEXT:    retq
488;
489; FAST-LABEL: umulobri8:
490; FAST:       ## %bb.0:
491; FAST-NEXT:    movl %edi, %eax
492; FAST-NEXT:    ## kill: def $al killed $al killed $eax
493; FAST-NEXT:    mulb %sil
494; FAST-NEXT:    seto %al
495; FAST-NEXT:    testb $1, %al
496; FAST-NEXT:    jne LBB19_1
497; FAST-NEXT:  ## %bb.2: ## %continue
498; FAST-NEXT:    movb $1, %al
499; FAST-NEXT:    andb $1, %al
500; FAST-NEXT:    movzbl %al, %eax
501; FAST-NEXT:    retq
502; FAST-NEXT:  LBB19_1: ## %overflow
503; FAST-NEXT:    xorl %eax, %eax
504; FAST-NEXT:    andb $1, %al
505; FAST-NEXT:    movzbl %al, %eax
506; FAST-NEXT:    retq
507  %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
508  %val = extractvalue {i8, i1} %t, 0
509  %obit = extractvalue {i8, i1} %t, 1
510  br i1 %obit, label %overflow, label %continue, !prof !0
511
512overflow:
513  ret i1 false
514
515continue:
516  ret i1 true
517}
518
519define zeroext i1 @umulobri16(i16 %v1, i16 %v2) {
520; SDAG-LABEL: umulobri16:
521; SDAG:       ## %bb.0:
522; SDAG-NEXT:    movl %edi, %eax
523; SDAG-NEXT:    ## kill: def $ax killed $ax killed $eax
524; SDAG-NEXT:    mulw %si
525; SDAG-NEXT:    jo LBB20_1
526; SDAG-NEXT:  ## %bb.2: ## %continue
527; SDAG-NEXT:    movb $1, %al
528; SDAG-NEXT:    retq
529; SDAG-NEXT:  LBB20_1: ## %overflow
530; SDAG-NEXT:    xorl %eax, %eax
531; SDAG-NEXT:    retq
532;
533; FAST-LABEL: umulobri16:
534; FAST:       ## %bb.0:
535; FAST-NEXT:    movl %edi, %eax
536; FAST-NEXT:    ## kill: def $ax killed $ax killed $eax
537; FAST-NEXT:    mulw %si
538; FAST-NEXT:    seto %al
539; FAST-NEXT:    testb $1, %al
540; FAST-NEXT:    jne LBB20_1
541; FAST-NEXT:  ## %bb.2: ## %continue
542; FAST-NEXT:    movb $1, %al
543; FAST-NEXT:    andb $1, %al
544; FAST-NEXT:    movzbl %al, %eax
545; FAST-NEXT:    retq
546; FAST-NEXT:  LBB20_1: ## %overflow
547; FAST-NEXT:    xorl %eax, %eax
548; FAST-NEXT:    andb $1, %al
549; FAST-NEXT:    movzbl %al, %eax
550; FAST-NEXT:    retq
551  %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
552  %val = extractvalue {i16, i1} %t, 0
553  %obit = extractvalue {i16, i1} %t, 1
554  br i1 %obit, label %overflow, label %continue, !prof !0
555
556overflow:
557  ret i1 false
558
559continue:
560  ret i1 true
561}
562
563define zeroext i1 @umulobri32(i32 %v1, i32 %v2) {
564; SDAG-LABEL: umulobri32:
565; SDAG:       ## %bb.0:
566; SDAG-NEXT:    movl %edi, %eax
567; SDAG-NEXT:    mull %esi
568; SDAG-NEXT:    jo LBB21_1
569; SDAG-NEXT:  ## %bb.2: ## %continue
570; SDAG-NEXT:    movb $1, %al
571; SDAG-NEXT:    retq
572; SDAG-NEXT:  LBB21_1: ## %overflow
573; SDAG-NEXT:    xorl %eax, %eax
574; SDAG-NEXT:    retq
575;
576; FAST-LABEL: umulobri32:
577; FAST:       ## %bb.0:
578; FAST-NEXT:    movl %edi, %eax
579; FAST-NEXT:    mull %esi
580; FAST-NEXT:    jo LBB21_1
581; FAST-NEXT:  ## %bb.2: ## %continue
582; FAST-NEXT:    movb $1, %al
583; FAST-NEXT:    andb $1, %al
584; FAST-NEXT:    movzbl %al, %eax
585; FAST-NEXT:    retq
586; FAST-NEXT:  LBB21_1: ## %overflow
587; FAST-NEXT:    xorl %eax, %eax
588; FAST-NEXT:    andb $1, %al
589; FAST-NEXT:    movzbl %al, %eax
590; FAST-NEXT:    retq
591  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
592  %val = extractvalue {i32, i1} %t, 0
593  %obit = extractvalue {i32, i1} %t, 1
594  br i1 %obit, label %overflow, label %continue, !prof !0
595
596overflow:
597  ret i1 false
598
599continue:
600  ret i1 true
601}
602
603define zeroext i1 @umulobri64(i64 %v1, i64 %v2) {
604; SDAG-LABEL: umulobri64:
605; SDAG:       ## %bb.0:
606; SDAG-NEXT:    movq %rdi, %rax
607; SDAG-NEXT:    mulq %rsi
608; SDAG-NEXT:    jo LBB22_1
609; SDAG-NEXT:  ## %bb.2: ## %continue
610; SDAG-NEXT:    movb $1, %al
611; SDAG-NEXT:    retq
612; SDAG-NEXT:  LBB22_1: ## %overflow
613; SDAG-NEXT:    xorl %eax, %eax
614; SDAG-NEXT:    retq
615;
616; FAST-LABEL: umulobri64:
617; FAST:       ## %bb.0:
618; FAST-NEXT:    movq %rdi, %rax
619; FAST-NEXT:    mulq %rsi
620; FAST-NEXT:    jo LBB22_1
621; FAST-NEXT:  ## %bb.2: ## %continue
622; FAST-NEXT:    movb $1, %al
623; FAST-NEXT:    andb $1, %al
624; FAST-NEXT:    movzbl %al, %eax
625; FAST-NEXT:    retq
626; FAST-NEXT:  LBB22_1: ## %overflow
627; FAST-NEXT:    xorl %eax, %eax
628; FAST-NEXT:    andb $1, %al
629; FAST-NEXT:    movzbl %al, %eax
630; FAST-NEXT:    retq
631  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
632  %val = extractvalue {i64, i1} %t, 0
633  %obit = extractvalue {i64, i1} %t, 1
634  br i1 %obit, label %overflow, label %continue, !prof !0
635
636overflow:
637  ret i1 false
638
639continue:
640  ret i1 true
641}
642
643define i1 @bug27873(i64 %c1, i1 %c2) {
644; CHECK-LABEL: bug27873:
645; CHECK:       ## %bb.0:
646; CHECK-NEXT:    movq %rdi, %rax
647; CHECK-NEXT:    movl $160, %ecx
648; CHECK-NEXT:    mulq %rcx
649; CHECK-NEXT:    seto %al
650; CHECK-NEXT:    orb %sil, %al
651; CHECK-NEXT:    retq
652  %mul = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %c1, i64 160)
653  %mul.overflow = extractvalue { i64, i1 } %mul, 1
654  %x1 = or i1 %c2, %mul.overflow
655  ret i1 %x1
656}
657
658define zeroext i1 @smuloi8_load(i8* %ptr1, i8 %v2, i8* %res) {
659; SDAG-LABEL: smuloi8_load:
660; SDAG:       ## %bb.0:
661; SDAG-NEXT:    movl %esi, %eax
662; SDAG-NEXT:    ## kill: def $al killed $al killed $eax
663; SDAG-NEXT:    imulb (%rdi)
664; SDAG-NEXT:    seto %cl
665; SDAG-NEXT:    movb %al, (%rdx)
666; SDAG-NEXT:    movl %ecx, %eax
667; SDAG-NEXT:    retq
668;
669; FAST-LABEL: smuloi8_load:
670; FAST:       ## %bb.0:
671; FAST-NEXT:    movb (%rdi), %al
672; FAST-NEXT:    imulb %sil
673; FAST-NEXT:    seto %cl
674; FAST-NEXT:    movb %al, (%rdx)
675; FAST-NEXT:    andb $1, %cl
676; FAST-NEXT:    movzbl %cl, %eax
677; FAST-NEXT:    retq
678  %v1 = load i8, i8* %ptr1
679  %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
680  %val = extractvalue {i8, i1} %t, 0
681  %obit = extractvalue {i8, i1} %t, 1
682  store i8 %val, i8* %res
683  ret i1 %obit
684}
685
686define zeroext i1 @smuloi8_load2(i8 %v1, i8* %ptr2, i8* %res) {
687; SDAG-LABEL: smuloi8_load2:
688; SDAG:       ## %bb.0:
689; SDAG-NEXT:    movl %edi, %eax
690; SDAG-NEXT:    ## kill: def $al killed $al killed $eax
691; SDAG-NEXT:    imulb (%rsi)
692; SDAG-NEXT:    seto %cl
693; SDAG-NEXT:    movb %al, (%rdx)
694; SDAG-NEXT:    movl %ecx, %eax
695; SDAG-NEXT:    retq
696;
697; FAST-LABEL: smuloi8_load2:
698; FAST:       ## %bb.0:
699; FAST-NEXT:    movl %edi, %eax
700; FAST-NEXT:    ## kill: def $al killed $al killed $eax
701; FAST-NEXT:    imulb (%rsi)
702; FAST-NEXT:    seto %cl
703; FAST-NEXT:    movb %al, (%rdx)
704; FAST-NEXT:    andb $1, %cl
705; FAST-NEXT:    movzbl %cl, %eax
706; FAST-NEXT:    retq
707  %v2 = load i8, i8* %ptr2
708  %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
709  %val = extractvalue {i8, i1} %t, 0
710  %obit = extractvalue {i8, i1} %t, 1
711  store i8 %val, i8* %res
712  ret i1 %obit
713}
714
715define zeroext i1 @smuloi16_load(i16* %ptr1, i16 %v2, i16* %res) {
716; SDAG-LABEL: smuloi16_load:
717; SDAG:       ## %bb.0:
718; SDAG-NEXT:    imulw (%rdi), %si
719; SDAG-NEXT:    seto %al
720; SDAG-NEXT:    movw %si, (%rdx)
721; SDAG-NEXT:    retq
722;
723; FAST-LABEL: smuloi16_load:
724; FAST:       ## %bb.0:
725; FAST-NEXT:    imulw (%rdi), %si
726; FAST-NEXT:    seto %al
727; FAST-NEXT:    movw %si, (%rdx)
728; FAST-NEXT:    andb $1, %al
729; FAST-NEXT:    movzbl %al, %eax
730; FAST-NEXT:    retq
731  %v1 = load i16, i16* %ptr1
732  %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
733  %val = extractvalue {i16, i1} %t, 0
734  %obit = extractvalue {i16, i1} %t, 1
735  store i16 %val, i16* %res
736  ret i1 %obit
737}
738
739define zeroext i1 @smuloi16_load2(i16 %v1, i16* %ptr2, i16* %res) {
740; SDAG-LABEL: smuloi16_load2:
741; SDAG:       ## %bb.0:
742; SDAG-NEXT:    imulw (%rsi), %di
743; SDAG-NEXT:    seto %al
744; SDAG-NEXT:    movw %di, (%rdx)
745; SDAG-NEXT:    retq
746;
747; FAST-LABEL: smuloi16_load2:
748; FAST:       ## %bb.0:
749; FAST-NEXT:    imulw (%rsi), %di
750; FAST-NEXT:    seto %al
751; FAST-NEXT:    movw %di, (%rdx)
752; FAST-NEXT:    andb $1, %al
753; FAST-NEXT:    movzbl %al, %eax
754; FAST-NEXT:    retq
755  %v2 = load i16, i16* %ptr2
756  %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
757  %val = extractvalue {i16, i1} %t, 0
758  %obit = extractvalue {i16, i1} %t, 1
759  store i16 %val, i16* %res
760  ret i1 %obit
761}
762
763define zeroext i1 @smuloi32_load(i32* %ptr1, i32 %v2, i32* %res) {
764; SDAG-LABEL: smuloi32_load:
765; SDAG:       ## %bb.0:
766; SDAG-NEXT:    imull (%rdi), %esi
767; SDAG-NEXT:    seto %al
768; SDAG-NEXT:    movl %esi, (%rdx)
769; SDAG-NEXT:    retq
770;
771; FAST-LABEL: smuloi32_load:
772; FAST:       ## %bb.0:
773; FAST-NEXT:    imull (%rdi), %esi
774; FAST-NEXT:    seto %al
775; FAST-NEXT:    movl %esi, (%rdx)
776; FAST-NEXT:    andb $1, %al
777; FAST-NEXT:    movzbl %al, %eax
778; FAST-NEXT:    retq
779  %v1 = load i32, i32* %ptr1
780  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
781  %val = extractvalue {i32, i1} %t, 0
782  %obit = extractvalue {i32, i1} %t, 1
783  store i32 %val, i32* %res
784  ret i1 %obit
785}
786
787define zeroext i1 @smuloi32_load2(i32 %v1, i32* %ptr2, i32* %res) {
788; SDAG-LABEL: smuloi32_load2:
789; SDAG:       ## %bb.0:
790; SDAG-NEXT:    imull (%rsi), %edi
791; SDAG-NEXT:    seto %al
792; SDAG-NEXT:    movl %edi, (%rdx)
793; SDAG-NEXT:    retq
794;
795; FAST-LABEL: smuloi32_load2:
796; FAST:       ## %bb.0:
797; FAST-NEXT:    imull (%rsi), %edi
798; FAST-NEXT:    seto %al
799; FAST-NEXT:    movl %edi, (%rdx)
800; FAST-NEXT:    andb $1, %al
801; FAST-NEXT:    movzbl %al, %eax
802; FAST-NEXT:    retq
803  %v2 = load i32, i32* %ptr2
804  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
805  %val = extractvalue {i32, i1} %t, 0
806  %obit = extractvalue {i32, i1} %t, 1
807  store i32 %val, i32* %res
808  ret i1 %obit
809}
810
811define zeroext i1 @smuloi64_load(i64* %ptr1, i64 %v2, i64* %res) {
812; SDAG-LABEL: smuloi64_load:
813; SDAG:       ## %bb.0:
814; SDAG-NEXT:    imulq (%rdi), %rsi
815; SDAG-NEXT:    seto %al
816; SDAG-NEXT:    movq %rsi, (%rdx)
817; SDAG-NEXT:    retq
818;
819; FAST-LABEL: smuloi64_load:
820; FAST:       ## %bb.0:
821; FAST-NEXT:    imulq (%rdi), %rsi
822; FAST-NEXT:    seto %al
823; FAST-NEXT:    movq %rsi, (%rdx)
824; FAST-NEXT:    andb $1, %al
825; FAST-NEXT:    movzbl %al, %eax
826; FAST-NEXT:    retq
827  %v1 = load i64, i64* %ptr1
828  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
829  %val = extractvalue {i64, i1} %t, 0
830  %obit = extractvalue {i64, i1} %t, 1
831  store i64 %val, i64* %res
832  ret i1 %obit
833}
834
835define zeroext i1 @smuloi64_load2(i64 %v1, i64* %ptr2, i64* %res) {
836; SDAG-LABEL: smuloi64_load2:
837; SDAG:       ## %bb.0:
838; SDAG-NEXT:    imulq (%rsi), %rdi
839; SDAG-NEXT:    seto %al
840; SDAG-NEXT:    movq %rdi, (%rdx)
841; SDAG-NEXT:    retq
842;
843; FAST-LABEL: smuloi64_load2:
844; FAST:       ## %bb.0:
845; FAST-NEXT:    imulq (%rsi), %rdi
846; FAST-NEXT:    seto %al
847; FAST-NEXT:    movq %rdi, (%rdx)
848; FAST-NEXT:    andb $1, %al
849; FAST-NEXT:    movzbl %al, %eax
850; FAST-NEXT:    retq
851  %v2 = load i64, i64* %ptr2
852  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
853  %val = extractvalue {i64, i1} %t, 0
854  %obit = extractvalue {i64, i1} %t, 1
855  store i64 %val, i64* %res
856  ret i1 %obit
857}
858
859define zeroext i1 @umuloi8_load(i8* %ptr1, i8 %v2, i8* %res) {
860; SDAG-LABEL: umuloi8_load:
861; SDAG:       ## %bb.0:
862; SDAG-NEXT:    movl %esi, %eax
863; SDAG-NEXT:    ## kill: def $al killed $al killed $eax
864; SDAG-NEXT:    mulb (%rdi)
865; SDAG-NEXT:    seto %cl
866; SDAG-NEXT:    movb %al, (%rdx)
867; SDAG-NEXT:    movl %ecx, %eax
868; SDAG-NEXT:    retq
869;
870; FAST-LABEL: umuloi8_load:
871; FAST:       ## %bb.0:
872; FAST-NEXT:    movb (%rdi), %al
873; FAST-NEXT:    mulb %sil
874; FAST-NEXT:    seto %cl
875; FAST-NEXT:    movb %al, (%rdx)
876; FAST-NEXT:    andb $1, %cl
877; FAST-NEXT:    movzbl %cl, %eax
878; FAST-NEXT:    retq
879  %v1 = load i8, i8* %ptr1
880  %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
881  %val = extractvalue {i8, i1} %t, 0
882  %obit = extractvalue {i8, i1} %t, 1
883  store i8 %val, i8* %res
884  ret i1 %obit
885}
886
887define zeroext i1 @umuloi8_load2(i8 %v1, i8* %ptr2, i8* %res) {
888; SDAG-LABEL: umuloi8_load2:
889; SDAG:       ## %bb.0:
890; SDAG-NEXT:    movl %edi, %eax
891; SDAG-NEXT:    ## kill: def $al killed $al killed $eax
892; SDAG-NEXT:    mulb (%rsi)
893; SDAG-NEXT:    seto %cl
894; SDAG-NEXT:    movb %al, (%rdx)
895; SDAG-NEXT:    movl %ecx, %eax
896; SDAG-NEXT:    retq
897;
898; FAST-LABEL: umuloi8_load2:
899; FAST:       ## %bb.0:
900; FAST-NEXT:    movl %edi, %eax
901; FAST-NEXT:    ## kill: def $al killed $al killed $eax
902; FAST-NEXT:    mulb (%rsi)
903; FAST-NEXT:    seto %cl
904; FAST-NEXT:    movb %al, (%rdx)
905; FAST-NEXT:    andb $1, %cl
906; FAST-NEXT:    movzbl %cl, %eax
907; FAST-NEXT:    retq
908  %v2 = load i8, i8* %ptr2
909  %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
910  %val = extractvalue {i8, i1} %t, 0
911  %obit = extractvalue {i8, i1} %t, 1
912  store i8 %val, i8* %res
913  ret i1 %obit
914}
915
916define zeroext i1 @umuloi16_load(i16* %ptr1, i16 %v2, i16* %res) {
917; SDAG-LABEL: umuloi16_load:
918; SDAG:       ## %bb.0:
919; SDAG-NEXT:    movq %rdx, %rcx
920; SDAG-NEXT:    movl %esi, %eax
921; SDAG-NEXT:    ## kill: def $ax killed $ax killed $eax
922; SDAG-NEXT:    mulw (%rdi)
923; SDAG-NEXT:    seto %dl
924; SDAG-NEXT:    movw %ax, (%rcx)
925; SDAG-NEXT:    movl %edx, %eax
926; SDAG-NEXT:    retq
927;
928; FAST-LABEL: umuloi16_load:
929; FAST:       ## %bb.0:
930; FAST-NEXT:    movq %rdx, %rcx
931; FAST-NEXT:    movzwl (%rdi), %eax
932; FAST-NEXT:    mulw %si
933; FAST-NEXT:    seto %dl
934; FAST-NEXT:    movw %ax, (%rcx)
935; FAST-NEXT:    andb $1, %dl
936; FAST-NEXT:    movzbl %dl, %eax
937; FAST-NEXT:    retq
938  %v1 = load i16, i16* %ptr1
939  %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
940  %val = extractvalue {i16, i1} %t, 0
941  %obit = extractvalue {i16, i1} %t, 1
942  store i16 %val, i16* %res
943  ret i1 %obit
944}
945
946define zeroext i1 @umuloi16_load2(i16 %v1, i16* %ptr2, i16* %res) {
947; SDAG-LABEL: umuloi16_load2:
948; SDAG:       ## %bb.0:
949; SDAG-NEXT:    movq %rdx, %rcx
950; SDAG-NEXT:    movl %edi, %eax
951; SDAG-NEXT:    ## kill: def $ax killed $ax killed $eax
952; SDAG-NEXT:    mulw (%rsi)
953; SDAG-NEXT:    seto %dl
954; SDAG-NEXT:    movw %ax, (%rcx)
955; SDAG-NEXT:    movl %edx, %eax
956; SDAG-NEXT:    retq
957;
958; FAST-LABEL: umuloi16_load2:
959; FAST:       ## %bb.0:
960; FAST-NEXT:    movq %rdx, %rcx
961; FAST-NEXT:    movl %edi, %eax
962; FAST-NEXT:    ## kill: def $ax killed $ax killed $eax
963; FAST-NEXT:    mulw (%rsi)
964; FAST-NEXT:    seto %dl
965; FAST-NEXT:    movw %ax, (%rcx)
966; FAST-NEXT:    andb $1, %dl
967; FAST-NEXT:    movzbl %dl, %eax
968; FAST-NEXT:    retq
969  %v2 = load i16, i16* %ptr2
970  %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
971  %val = extractvalue {i16, i1} %t, 0
972  %obit = extractvalue {i16, i1} %t, 1
973  store i16 %val, i16* %res
974  ret i1 %obit
975}
976
977define zeroext i1 @umuloi32_load(i32* %ptr1, i32 %v2, i32* %res) {
978; SDAG-LABEL: umuloi32_load:
979; SDAG:       ## %bb.0:
980; SDAG-NEXT:    movq %rdx, %rcx
981; SDAG-NEXT:    movl %esi, %eax
982; SDAG-NEXT:    mull (%rdi)
983; SDAG-NEXT:    seto %dl
984; SDAG-NEXT:    movl %eax, (%rcx)
985; SDAG-NEXT:    movl %edx, %eax
986; SDAG-NEXT:    retq
987;
988; FAST-LABEL: umuloi32_load:
989; FAST:       ## %bb.0:
990; FAST-NEXT:    movq %rdx, %rcx
991; FAST-NEXT:    movl (%rdi), %eax
992; FAST-NEXT:    mull %esi
993; FAST-NEXT:    seto %dl
994; FAST-NEXT:    movl %eax, (%rcx)
995; FAST-NEXT:    andb $1, %dl
996; FAST-NEXT:    movzbl %dl, %eax
997; FAST-NEXT:    retq
998  %v1 = load i32, i32* %ptr1
999  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
1000  %val = extractvalue {i32, i1} %t, 0
1001  %obit = extractvalue {i32, i1} %t, 1
1002  store i32 %val, i32* %res
1003  ret i1 %obit
1004}
1005
1006define zeroext i1 @umuloi32_load2(i32 %v1, i32* %ptr2, i32* %res) {
1007; SDAG-LABEL: umuloi32_load2:
1008; SDAG:       ## %bb.0:
1009; SDAG-NEXT:    movq %rdx, %rcx
1010; SDAG-NEXT:    movl %edi, %eax
1011; SDAG-NEXT:    mull (%rsi)
1012; SDAG-NEXT:    seto %dl
1013; SDAG-NEXT:    movl %eax, (%rcx)
1014; SDAG-NEXT:    movl %edx, %eax
1015; SDAG-NEXT:    retq
1016;
1017; FAST-LABEL: umuloi32_load2:
1018; FAST:       ## %bb.0:
1019; FAST-NEXT:    movq %rdx, %rcx
1020; FAST-NEXT:    movl %edi, %eax
1021; FAST-NEXT:    mull (%rsi)
1022; FAST-NEXT:    seto %dl
1023; FAST-NEXT:    movl %eax, (%rcx)
1024; FAST-NEXT:    andb $1, %dl
1025; FAST-NEXT:    movzbl %dl, %eax
1026; FAST-NEXT:    retq
1027  %v2 = load i32, i32* %ptr2
1028  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
1029  %val = extractvalue {i32, i1} %t, 0
1030  %obit = extractvalue {i32, i1} %t, 1
1031  store i32 %val, i32* %res
1032  ret i1 %obit
1033}
1034
1035define zeroext i1 @umuloi64_load(i64* %ptr1, i64 %v2, i64* %res) {
1036; SDAG-LABEL: umuloi64_load:
1037; SDAG:       ## %bb.0:
1038; SDAG-NEXT:    movq %rdx, %rcx
1039; SDAG-NEXT:    movq %rsi, %rax
1040; SDAG-NEXT:    mulq (%rdi)
1041; SDAG-NEXT:    seto %dl
1042; SDAG-NEXT:    movq %rax, (%rcx)
1043; SDAG-NEXT:    movl %edx, %eax
1044; SDAG-NEXT:    retq
1045;
1046; FAST-LABEL: umuloi64_load:
1047; FAST:       ## %bb.0:
1048; FAST-NEXT:    movq %rdx, %rcx
1049; FAST-NEXT:    movq (%rdi), %rax
1050; FAST-NEXT:    mulq %rsi
1051; FAST-NEXT:    seto %dl
1052; FAST-NEXT:    movq %rax, (%rcx)
1053; FAST-NEXT:    andb $1, %dl
1054; FAST-NEXT:    movzbl %dl, %eax
1055; FAST-NEXT:    retq
1056  %v1 = load i64, i64* %ptr1
1057  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
1058  %val = extractvalue {i64, i1} %t, 0
1059  %obit = extractvalue {i64, i1} %t, 1
1060  store i64 %val, i64* %res
1061  ret i1 %obit
1062}
1063
1064define zeroext i1 @umuloi64_load2(i64 %v1, i64* %ptr2, i64* %res) {
1065; SDAG-LABEL: umuloi64_load2:
1066; SDAG:       ## %bb.0:
1067; SDAG-NEXT:    movq %rdx, %rcx
1068; SDAG-NEXT:    movq %rdi, %rax
1069; SDAG-NEXT:    mulq (%rsi)
1070; SDAG-NEXT:    seto %dl
1071; SDAG-NEXT:    movq %rax, (%rcx)
1072; SDAG-NEXT:    movl %edx, %eax
1073; SDAG-NEXT:    retq
1074;
1075; FAST-LABEL: umuloi64_load2:
1076; FAST:       ## %bb.0:
1077; FAST-NEXT:    movq %rdx, %rcx
1078; FAST-NEXT:    movq %rdi, %rax
1079; FAST-NEXT:    mulq (%rsi)
1080; FAST-NEXT:    seto %dl
1081; FAST-NEXT:    movq %rax, (%rcx)
1082; FAST-NEXT:    andb $1, %dl
1083; FAST-NEXT:    movzbl %dl, %eax
1084; FAST-NEXT:    retq
1085  %v2 = load i64, i64* %ptr2
1086  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
1087  %val = extractvalue {i64, i1} %t, 0
1088  %obit = extractvalue {i64, i1} %t, 1
1089  store i64 %val, i64* %res
1090  ret i1 %obit
1091}
1092
1093declare {i8,  i1} @llvm.smul.with.overflow.i8 (i8,  i8 ) nounwind readnone
1094declare {i16, i1} @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone
1095declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
1096declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
1097declare {i8,  i1} @llvm.umul.with.overflow.i8 (i8,  i8 ) nounwind readnone
1098declare {i16, i1} @llvm.umul.with.overflow.i16(i16, i16) nounwind readnone
1099declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
1100declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone
1101
1102!0 = !{!"branch_weights", i32 0, i32 2147483647}
1103