1; RUN: llc < %s -mtriple=arm-linux -mcpu=generic | FileCheck %s
2
3define i32 @uadd_overflow(i32 %a, i32 %b) #0 {
4  %sadd = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)
5  %1 = extractvalue { i32, i1 } %sadd, 1
6  %2 = zext i1 %1 to i32
7  ret i32 %2
8
9  ; CHECK-LABEL: uadd_overflow:
10  ; CHECK: add r[[R2:[0-9]+]], r[[R0:[0-9]+]], r[[R1:[0-9]+]]
11  ; CHECK: mov r[[R1]], #1
12  ; CHECK: cmp r[[R2]], r[[R0]]
13  ; CHECK: movhs r[[R1]], #0
14}
15
16
17define i32 @sadd_overflow(i32 %a, i32 %b) #0 {
18  %sadd = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)
19  %1 = extractvalue { i32, i1 } %sadd, 1
20  %2 = zext i1 %1 to i32
21  ret i32 %2
22
23  ; CHECK-LABEL: sadd_overflow:
24  ; CHECK: add r[[R2:[0-9]+]], r[[R0:[0-9]+]], r[[R1:[0-9]+]]
25  ; CHECK: mov r[[R1]], #1
26  ; CHECK: cmp r[[R2]], r[[R0]]
27  ; CHECK: movvc r[[R1]], #0
28}
29
30define i32 @usub_overflow(i32 %a, i32 %b) #0 {
31  %sadd = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
32  %1 = extractvalue { i32, i1 } %sadd, 1
33  %2 = zext i1 %1 to i32
34  ret i32 %2
35
36  ; CHECK-LABEL: usub_overflow:
37  ; CHECK: mov r[[R2]], #1
38  ; CHECK: cmp r[[R0]], r[[R1]]
39  ; CHECK: movhs r[[R2]], #0
40}
41
42define i32 @ssub_overflow(i32 %a, i32 %b) #0 {
43  %sadd = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)
44  %1 = extractvalue { i32, i1 } %sadd, 1
45  %2 = zext i1 %1 to i32
46  ret i32 %2
47
48  ; CHECK-LABEL: ssub_overflow:
49  ; CHECK: mov r[[R2]], #1
50  ; CHECK: cmp r[[R0]], r[[R1]]
51  ; CHECK: movvc r[[R2]], #0
52}
53
54declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) #1
55declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) #2
56declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32) #3
57declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32) #4
58