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