blob: 5e6cd25adedea307db314697341b65ec0427197f [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
234; SSUBO
235define zeroext i1 @ssubo.i32(i32 %v1, i32 %v2, i32* %res) {
236entry:
237; DAG-LABEL: ssubo.i32
238; DAG: subl %esi, %edi
239; DAG-NEXT: seto %al
240; FAST-LABEL: ssubo.i32
241; FAST: subl %esi, %edi
242; FAST-NEXT: seto %al
243 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
244 %val = extractvalue {i32, i1} %t, 0
245 %obit = extractvalue {i32, i1} %t, 1
246 store i32 %val, i32* %res
247 ret i1 %obit
248}
249
250define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, i64* %res) {
251entry:
252; DAG-LABEL: ssubo.i64
253; DAG: subq %rsi, %rdi
254; DAG-NEXT: seto %al
255; FAST-LABEL: ssubo.i64
256; FAST: subq %rsi, %rdi
257; FAST-NEXT: seto %al
258 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
259 %val = extractvalue {i64, i1} %t, 0
260 %obit = extractvalue {i64, i1} %t, 1
261 store i64 %val, i64* %res
262 ret i1 %obit
263}
264
265; USUBO
266define zeroext i1 @usubo.i32(i32 %v1, i32 %v2, i32* %res) {
267entry:
268; DAG-LABEL: usubo.i32
269; DAG: subl %esi, %edi
270; DAG-NEXT: setb %al
271; FAST-LABEL: usubo.i32
272; FAST: subl %esi, %edi
273; FAST-NEXT: setb %al
274 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
275 %val = extractvalue {i32, i1} %t, 0
276 %obit = extractvalue {i32, i1} %t, 1
277 store i32 %val, i32* %res
278 ret i1 %obit
279}
280
281define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, i64* %res) {
282entry:
283; DAG-LABEL: usubo.i64
284; DAG: subq %rsi, %rdi
285; DAG-NEXT: setb %al
286; FAST-LABEL: usubo.i64
287; FAST: subq %rsi, %rdi
288; FAST-NEXT: setb %al
289 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
290 %val = extractvalue {i64, i1} %t, 0
291 %obit = extractvalue {i64, i1} %t, 1
292 store i64 %val, i64* %res
293 ret i1 %obit
294}
295
296; SMULO
Juergen Ributzka665ea712014-07-07 21:52:21 +0000297define zeroext i1 @smulo.i8(i8 %v1, i8 %v2, i8* %res) {
298entry:
299; FAST-LABEL: smulo.i8
300; FAST: movb %dil, %al
301; FAST-NEXT: imulb %sil
302; FAST-NEXT: seto %cl
303 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)
304 %val = extractvalue {i8, i1} %t, 0
305 %obit = extractvalue {i8, i1} %t, 1
306 store i8 %val, i8* %res
307 ret i1 %obit
308}
309
310define zeroext i1 @smulo.i16(i16 %v1, i16 %v2, i16* %res) {
311entry:
312; DAG-LABEL: smulo.i16
313; DAG: imulw %si, %di
314; DAG-NEXT: seto %al
315; FAST-LABEL: smulo.i16
316; FAST: imulw %si, %di
317; FAST-NEXT: seto %al
318 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
319 %val = extractvalue {i16, i1} %t, 0
320 %obit = extractvalue {i16, i1} %t, 1
321 store i16 %val, i16* %res
322 ret i1 %obit
323}
324
Juergen Ributzka2dace6e2014-06-10 23:52:44 +0000325define zeroext i1 @smulo.i32(i32 %v1, i32 %v2, i32* %res) {
326entry:
327; DAG-LABEL: smulo.i32
328; DAG: imull %esi, %edi
329; DAG-NEXT: seto %al
330; FAST-LABEL: smulo.i32
331; FAST: imull %esi, %edi
332; FAST-NEXT: seto %al
333 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
334 %val = extractvalue {i32, i1} %t, 0
335 %obit = extractvalue {i32, i1} %t, 1
336 store i32 %val, i32* %res
337 ret i1 %obit
338}
339
340define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, i64* %res) {
341entry:
342; DAG-LABEL: smulo.i64
343; DAG: imulq %rsi, %rdi
344; DAG-NEXT: seto %al
345; FAST-LABEL: smulo.i64
346; FAST: imulq %rsi, %rdi
347; FAST-NEXT: seto %al
348 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
349 %val = extractvalue {i64, i1} %t, 0
350 %obit = extractvalue {i64, i1} %t, 1
351 store i64 %val, i64* %res
352 ret i1 %obit
353}
354
355; UMULO
Juergen Ributzka665ea712014-07-07 21:52:21 +0000356define zeroext i1 @umulo.i8(i8 %v1, i8 %v2, i8* %res) {
357entry:
358; FAST-LABEL: umulo.i8
359; FAST: movb %dil, %al
360; FAST-NEXT: mulb %sil
361; FAST-NEXT: seto %cl
362 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)
363 %val = extractvalue {i8, i1} %t, 0
364 %obit = extractvalue {i8, i1} %t, 1
365 store i8 %val, i8* %res
366 ret i1 %obit
367}
368
369define zeroext i1 @umulo.i16(i16 %v1, i16 %v2, i16* %res) {
370entry:
371; DAG-LABEL: umulo.i16
372; DAG: mulw %si
373; DAG-NEXT: seto
374; FAST-LABEL: umulo.i16
375; FAST: mulw %si
376; FAST-NEXT: seto
377 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
378 %val = extractvalue {i16, i1} %t, 0
379 %obit = extractvalue {i16, i1} %t, 1
380 store i16 %val, i16* %res
381 ret i1 %obit
382}
383
Juergen Ributzka2dace6e2014-06-10 23:52:44 +0000384define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, i32* %res) {
385entry:
386; DAG-LABEL: umulo.i32
387; DAG: mull %esi
388; DAG-NEXT: seto
389; FAST-LABEL: umulo.i32
390; FAST: mull %esi
391; FAST-NEXT: seto
392 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
393 %val = extractvalue {i32, i1} %t, 0
394 %obit = extractvalue {i32, i1} %t, 1
395 store i32 %val, i32* %res
396 ret i1 %obit
397}
398
399define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, i64* %res) {
400entry:
401; DAG-LABEL: umulo.i64
402; DAG: mulq %rsi
403; DAG-NEXT: seto
404; FAST-LABEL: umulo.i64
405; FAST: mulq %rsi
406; FAST-NEXT: seto
407 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
408 %val = extractvalue {i64, i1} %t, 0
409 %obit = extractvalue {i64, i1} %t, 1
410 store i64 %val, i64* %res
411 ret i1 %obit
412}
413
Juergen Ributzka2bce27e2014-06-24 23:51:21 +0000414;
415; Check the use of the overflow bit in combination with a select instruction.
416;
417define i32 @saddo.select.i32(i32 %v1, i32 %v2) {
418entry:
419; CHECK-LABEL: saddo.select.i32
420; CHECK: addl %esi, %eax
421; CHECK-NEXT: cmovol %edi, %esi
422 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
423 %obit = extractvalue {i32, i1} %t, 1
424 %ret = select i1 %obit, i32 %v1, i32 %v2
425 ret i32 %ret
426}
427
428define i64 @saddo.select.i64(i64 %v1, i64 %v2) {
429entry:
430; CHECK-LABEL: saddo.select.i64
431; CHECK: addq %rsi, %rax
432; CHECK-NEXT: cmovoq %rdi, %rsi
433 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
434 %obit = extractvalue {i64, i1} %t, 1
435 %ret = select i1 %obit, i64 %v1, i64 %v2
436 ret i64 %ret
437}
438
439define i32 @uaddo.select.i32(i32 %v1, i32 %v2) {
440entry:
441; CHECK-LABEL: uaddo.select.i32
442; CHECK: addl %esi, %eax
443; CHECK-NEXT: cmovbl %edi, %esi
444 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
445 %obit = extractvalue {i32, i1} %t, 1
446 %ret = select i1 %obit, i32 %v1, i32 %v2
447 ret i32 %ret
448}
449
450define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {
451entry:
452; CHECK-LABEL: uaddo.select.i64
453; CHECK: addq %rsi, %rax
454; CHECK-NEXT: cmovbq %rdi, %rsi
455 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
456 %obit = extractvalue {i64, i1} %t, 1
457 %ret = select i1 %obit, i64 %v1, i64 %v2
458 ret i64 %ret
459}
460
461define i32 @ssubo.select.i32(i32 %v1, i32 %v2) {
462entry:
463; CHECK-LABEL: ssubo.select.i32
464; CHECK: cmpl %esi, %edi
465; CHECK-NEXT: cmovol %edi, %esi
466 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
467 %obit = extractvalue {i32, i1} %t, 1
468 %ret = select i1 %obit, i32 %v1, i32 %v2
469 ret i32 %ret
470}
471
472define i64 @ssubo.select.i64(i64 %v1, i64 %v2) {
473entry:
474; CHECK-LABEL: ssubo.select.i64
475; CHECK: cmpq %rsi, %rdi
476; CHECK-NEXT: cmovoq %rdi, %rsi
477 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
478 %obit = extractvalue {i64, i1} %t, 1
479 %ret = select i1 %obit, i64 %v1, i64 %v2
480 ret i64 %ret
481}
482
483define i32 @usubo.select.i32(i32 %v1, i32 %v2) {
484entry:
485; CHECK-LABEL: usubo.select.i32
486; CHECK: cmpl %esi, %edi
487; CHECK-NEXT: cmovbl %edi, %esi
488 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
489 %obit = extractvalue {i32, i1} %t, 1
490 %ret = select i1 %obit, i32 %v1, i32 %v2
491 ret i32 %ret
492}
493
494define i64 @usubo.select.i64(i64 %v1, i64 %v2) {
495entry:
496; CHECK-LABEL: usubo.select.i64
497; CHECK: cmpq %rsi, %rdi
498; CHECK-NEXT: cmovbq %rdi, %rsi
499 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
500 %obit = extractvalue {i64, i1} %t, 1
501 %ret = select i1 %obit, i64 %v1, i64 %v2
502 ret i64 %ret
503}
504
505define i32 @smulo.select.i32(i32 %v1, i32 %v2) {
506entry:
507; CHECK-LABEL: smulo.select.i32
508; CHECK: imull %esi, %eax
509; CHECK-NEXT: cmovol %edi, %esi
510 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
511 %obit = extractvalue {i32, i1} %t, 1
512 %ret = select i1 %obit, i32 %v1, i32 %v2
513 ret i32 %ret
514}
515
516define i64 @smulo.select.i64(i64 %v1, i64 %v2) {
517entry:
518; CHECK-LABEL: smulo.select.i64
519; CHECK: imulq %rsi, %rax
520; CHECK-NEXT: cmovoq %rdi, %rsi
521 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
522 %obit = extractvalue {i64, i1} %t, 1
523 %ret = select i1 %obit, i64 %v1, i64 %v2
524 ret i64 %ret
525}
526
527define i32 @umulo.select.i32(i32 %v1, i32 %v2) {
528entry:
529; CHECK-LABEL: umulo.select.i32
530; CHECK: mull %esi
531; CHECK-NEXT: cmovol %edi, %esi
532 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
533 %obit = extractvalue {i32, i1} %t, 1
534 %ret = select i1 %obit, i32 %v1, i32 %v2
535 ret i32 %ret
536}
537
538define i64 @umulo.select.i64(i64 %v1, i64 %v2) {
539entry:
540; CHECK-LABEL: umulo.select.i64
541; CHECK: mulq %rsi
542; CHECK-NEXT: cmovoq %rdi, %rsi
543 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
544 %obit = extractvalue {i64, i1} %t, 1
545 %ret = select i1 %obit, i64 %v1, i64 %v2
546 ret i64 %ret
547}
548
549
550;
551; Check the use of the overflow bit in combination with a branch instruction.
552;
553define zeroext i1 @saddo.br.i32(i32 %v1, i32 %v2) {
554entry:
555; CHECK-LABEL: saddo.br.i32
556; CHECK: addl %esi, %edi
557; CHECK-NEXT: jo
558 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
559 %val = extractvalue {i32, i1} %t, 0
560 %obit = extractvalue {i32, i1} %t, 1
561 br i1 %obit, label %overflow, label %continue, !prof !0
562
563overflow:
564 ret i1 false
565
566continue:
567 ret i1 true
568}
569
570define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) {
571entry:
572; CHECK-LABEL: saddo.br.i64
573; CHECK: addq %rsi, %rdi
574; CHECK-NEXT: jo
575 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
576 %val = extractvalue {i64, i1} %t, 0
577 %obit = extractvalue {i64, i1} %t, 1
578 br i1 %obit, label %overflow, label %continue, !prof !0
579
580overflow:
581 ret i1 false
582
583continue:
584 ret i1 true
585}
586
587define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) {
588entry:
589; CHECK-LABEL: uaddo.br.i32
590; CHECK: addl %esi, %edi
591; CHECK-NEXT: jb
592 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
593 %val = extractvalue {i32, i1} %t, 0
594 %obit = extractvalue {i32, i1} %t, 1
595 br i1 %obit, label %overflow, label %continue, !prof !0
596
597overflow:
598 ret i1 false
599
600continue:
601 ret i1 true
602}
603
604define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) {
605entry:
606; CHECK-LABEL: uaddo.br.i64
607; CHECK: addq %rsi, %rdi
608; CHECK-NEXT: jb
609 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
610 %val = extractvalue {i64, i1} %t, 0
611 %obit = extractvalue {i64, i1} %t, 1
612 br i1 %obit, label %overflow, label %continue, !prof !0
613
614overflow:
615 ret i1 false
616
617continue:
618 ret i1 true
619}
620
621define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) {
622entry:
623; CHECK-LABEL: ssubo.br.i32
624; CHECK: cmpl %esi, %edi
625; CHECK-NEXT: jo
626 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
627 %val = extractvalue {i32, i1} %t, 0
628 %obit = extractvalue {i32, i1} %t, 1
629 br i1 %obit, label %overflow, label %continue, !prof !0
630
631overflow:
632 ret i1 false
633
634continue:
635 ret i1 true
636}
637
638define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) {
639entry:
640; CHECK-LABEL: ssubo.br.i64
641; CHECK: cmpq %rsi, %rdi
642; CHECK-NEXT: jo
643 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
644 %val = extractvalue {i64, i1} %t, 0
645 %obit = extractvalue {i64, i1} %t, 1
646 br i1 %obit, label %overflow, label %continue, !prof !0
647
648overflow:
649 ret i1 false
650
651continue:
652 ret i1 true
653}
654
655define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) {
656entry:
657; CHECK-LABEL: usubo.br.i32
658; CHECK: cmpl %esi, %edi
659; CHECK-NEXT: jb
660 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
661 %val = extractvalue {i32, i1} %t, 0
662 %obit = extractvalue {i32, i1} %t, 1
663 br i1 %obit, label %overflow, label %continue, !prof !0
664
665overflow:
666 ret i1 false
667
668continue:
669 ret i1 true
670}
671
672define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) {
673entry:
674; CHECK-LABEL: usubo.br.i64
675; CHECK: cmpq %rsi, %rdi
676; CHECK-NEXT: jb
677 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
678 %val = extractvalue {i64, i1} %t, 0
679 %obit = extractvalue {i64, i1} %t, 1
680 br i1 %obit, label %overflow, label %continue, !prof !0
681
682overflow:
683 ret i1 false
684
685continue:
686 ret i1 true
687}
688
689define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) {
690entry:
691; CHECK-LABEL: smulo.br.i32
692; CHECK: imull %esi, %edi
693; CHECK-NEXT: jo
694 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
695 %val = extractvalue {i32, i1} %t, 0
696 %obit = extractvalue {i32, i1} %t, 1
697 br i1 %obit, label %overflow, label %continue, !prof !0
698
699overflow:
700 ret i1 false
701
702continue:
703 ret i1 true
704}
705
706define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) {
707entry:
708; CHECK-LABEL: smulo.br.i64
709; CHECK: imulq %rsi, %rdi
710; CHECK-NEXT: jo
711 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
712 %val = extractvalue {i64, i1} %t, 0
713 %obit = extractvalue {i64, i1} %t, 1
714 br i1 %obit, label %overflow, label %continue, !prof !0
715
716overflow:
717 ret i1 false
718
719continue:
720 ret i1 true
721}
722
723define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) {
724entry:
725; CHECK-LABEL: umulo.br.i32
726; CHECK: mull %esi
727; CHECK-NEXT: jo
728 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
729 %val = extractvalue {i32, i1} %t, 0
730 %obit = extractvalue {i32, i1} %t, 1
731 br i1 %obit, label %overflow, label %continue, !prof !0
732
733overflow:
734 ret i1 false
735
736continue:
737 ret i1 true
738}
739
740define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) {
741entry:
742; CHECK-LABEL: umulo.br.i64
743; CHECK: mulq %rsi
744; CHECK-NEXT: jo
745 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
746 %val = extractvalue {i64, i1} %t, 0
747 %obit = extractvalue {i64, i1} %t, 1
748 br i1 %obit, label %overflow, label %continue, !prof !0
749
750overflow:
751 ret i1 false
752
753continue:
754 ret i1 true
755}
756
Juergen Ributzka665ea712014-07-07 21:52:21 +0000757declare {i8, i1} @llvm.sadd.with.overflow.i8 (i8, i8 ) nounwind readnone
Juergen Ributzka2dace6e2014-06-10 23:52:44 +0000758declare {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 {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
762declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
763declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
764declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone
765declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
766declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
Juergen Ributzka665ea712014-07-07 21:52:21 +0000767declare {i8, i1} @llvm.smul.with.overflow.i8 (i8, i8 ) nounwind readnone
768declare {i16, i1} @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone
Juergen Ributzka2dace6e2014-06-10 23:52:44 +0000769declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
770declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
Juergen Ributzka665ea712014-07-07 21:52:21 +0000771declare {i8, i1} @llvm.umul.with.overflow.i8 (i8, i8 ) nounwind readnone
772declare {i16, i1} @llvm.umul.with.overflow.i16(i16, i16) nounwind readnone
Juergen Ributzka2dace6e2014-06-10 23:52:44 +0000773declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
774declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone
775
Juergen Ributzka2bce27e2014-06-24 23:51:21 +0000776!0 = metadata !{metadata !"branch_weights", i32 0, i32 2147483647}