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