1*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsanitize=unsigned-integer-overflow %s -emit-llvm -o - | FileCheck %s
2*67e74705SXin Li // Verify checked operations are emitted for integers and longs.
3*67e74705SXin Li // unsigned short/char's tested in unsigned-promotion.c
4*67e74705SXin Li
5*67e74705SXin Li unsigned long li, lj, lk;
6*67e74705SXin Li unsigned int ii, ij, ik;
7*67e74705SXin Li
8*67e74705SXin Li extern void opaquelong(unsigned long);
9*67e74705SXin Li extern void opaqueint(unsigned int);
10*67e74705SXin Li
11*67e74705SXin Li // CHECK-LABEL: define void @testlongadd()
testlongadd()12*67e74705SXin Li void testlongadd() {
13*67e74705SXin Li
14*67e74705SXin Li // CHECK: [[T1:%.*]] = load i64, i64* @lj
15*67e74705SXin Li // CHECK-NEXT: [[T2:%.*]] = load i64, i64* @lk
16*67e74705SXin Li // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 [[T2]])
17*67e74705SXin Li // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0
18*67e74705SXin Li // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1
19*67e74705SXin Li // CHECK: call void @__ubsan_handle_add_overflow
20*67e74705SXin Li li = lj + lk;
21*67e74705SXin Li }
22*67e74705SXin Li
23*67e74705SXin Li // CHECK-LABEL: define void @testlongsub()
testlongsub()24*67e74705SXin Li void testlongsub() {
25*67e74705SXin Li
26*67e74705SXin Li // CHECK: [[T1:%.*]] = load i64, i64* @lj
27*67e74705SXin Li // CHECK-NEXT: [[T2:%.*]] = load i64, i64* @lk
28*67e74705SXin Li // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[T1]], i64 [[T2]])
29*67e74705SXin Li // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0
30*67e74705SXin Li // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1
31*67e74705SXin Li // CHECK: call void @__ubsan_handle_sub_overflow
32*67e74705SXin Li li = lj - lk;
33*67e74705SXin Li }
34*67e74705SXin Li
35*67e74705SXin Li // CHECK-LABEL: define void @testlongmul()
testlongmul()36*67e74705SXin Li void testlongmul() {
37*67e74705SXin Li
38*67e74705SXin Li // CHECK: [[T1:%.*]] = load i64, i64* @lj
39*67e74705SXin Li // CHECK-NEXT: [[T2:%.*]] = load i64, i64* @lk
40*67e74705SXin Li // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[T1]], i64 [[T2]])
41*67e74705SXin Li // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0
42*67e74705SXin Li // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1
43*67e74705SXin Li // CHECK: call void @__ubsan_handle_mul_overflow
44*67e74705SXin Li li = lj * lk;
45*67e74705SXin Li }
46*67e74705SXin Li
47*67e74705SXin Li // CHECK-LABEL: define void @testlongpostinc()
testlongpostinc()48*67e74705SXin Li void testlongpostinc() {
49*67e74705SXin Li opaquelong(li++);
50*67e74705SXin Li
51*67e74705SXin Li // CHECK: [[T1:%.*]] = load i64, i64* @li
52*67e74705SXin Li // CHECK-NEXT: [[T2:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 1)
53*67e74705SXin Li // CHECK-NEXT: [[T3:%.*]] = extractvalue { i64, i1 } [[T2]], 0
54*67e74705SXin Li // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T2]], 1
55*67e74705SXin Li // CHECK: call void @__ubsan_handle_add_overflow
56*67e74705SXin Li }
57*67e74705SXin Li
58*67e74705SXin Li // CHECK-LABEL: define void @testlongpreinc()
testlongpreinc()59*67e74705SXin Li void testlongpreinc() {
60*67e74705SXin Li opaquelong(++li);
61*67e74705SXin Li
62*67e74705SXin Li // CHECK: [[T1:%.*]] = load i64, i64* @li
63*67e74705SXin Li // CHECK-NEXT: [[T2:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 1)
64*67e74705SXin Li // CHECK-NEXT: [[T3:%.*]] = extractvalue { i64, i1 } [[T2]], 0
65*67e74705SXin Li // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T2]], 1
66*67e74705SXin Li // CHECK: call void @__ubsan_handle_add_overflow
67*67e74705SXin Li }
68*67e74705SXin Li
69*67e74705SXin Li // CHECK-LABEL: define void @testintadd()
testintadd()70*67e74705SXin Li void testintadd() {
71*67e74705SXin Li
72*67e74705SXin Li // CHECK: [[T1:%.*]] = load i32, i32* @ij
73*67e74705SXin Li // CHECK-NEXT: [[T2:%.*]] = load i32, i32* @ik
74*67e74705SXin Li // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 [[T2]])
75*67e74705SXin Li // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0
76*67e74705SXin Li // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1
77*67e74705SXin Li // CHECK: call void @__ubsan_handle_add_overflow
78*67e74705SXin Li ii = ij + ik;
79*67e74705SXin Li }
80*67e74705SXin Li
81*67e74705SXin Li // CHECK-LABEL: define void @testintsub()
testintsub()82*67e74705SXin Li void testintsub() {
83*67e74705SXin Li
84*67e74705SXin Li // CHECK: [[T1:%.*]] = load i32, i32* @ij
85*67e74705SXin Li // CHECK-NEXT: [[T2:%.*]] = load i32, i32* @ik
86*67e74705SXin Li // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[T1]], i32 [[T2]])
87*67e74705SXin Li // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0
88*67e74705SXin Li // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1
89*67e74705SXin Li // CHECK: call void @__ubsan_handle_sub_overflow
90*67e74705SXin Li ii = ij - ik;
91*67e74705SXin Li }
92*67e74705SXin Li
93*67e74705SXin Li // CHECK-LABEL: define void @testintmul()
testintmul()94*67e74705SXin Li void testintmul() {
95*67e74705SXin Li
96*67e74705SXin Li // CHECK: [[T1:%.*]] = load i32, i32* @ij
97*67e74705SXin Li // CHECK-NEXT: [[T2:%.*]] = load i32, i32* @ik
98*67e74705SXin Li // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 [[T2]])
99*67e74705SXin Li // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0
100*67e74705SXin Li // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1
101*67e74705SXin Li // CHECK: call void @__ubsan_handle_mul_overflow
102*67e74705SXin Li ii = ij * ik;
103*67e74705SXin Li }
104*67e74705SXin Li
105*67e74705SXin Li // CHECK-LABEL: define void @testintpostinc()
testintpostinc()106*67e74705SXin Li void testintpostinc() {
107*67e74705SXin Li opaqueint(ii++);
108*67e74705SXin Li
109*67e74705SXin Li // CHECK: [[T1:%.*]] = load i32, i32* @ii
110*67e74705SXin Li // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 1)
111*67e74705SXin Li // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0
112*67e74705SXin Li // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1
113*67e74705SXin Li // CHECK: call void @__ubsan_handle_add_overflow
114*67e74705SXin Li }
115*67e74705SXin Li
116*67e74705SXin Li // CHECK-LABEL: define void @testintpreinc()
testintpreinc()117*67e74705SXin Li void testintpreinc() {
118*67e74705SXin Li opaqueint(++ii);
119*67e74705SXin Li
120*67e74705SXin Li // CHECK: [[T1:%.*]] = load i32, i32* @ii
121*67e74705SXin Li // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 1)
122*67e74705SXin Li // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0
123*67e74705SXin Li // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1
124*67e74705SXin Li // CHECK: call void @__ubsan_handle_add_overflow
125*67e74705SXin Li }
126