1 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsanitize=unsigned-integer-overflow %s -emit-llvm -o - | FileCheck %s
2 // Verify checked operations are emitted for integers and longs.
3 // unsigned short/char's tested in unsigned-promotion.c
5 unsigned long li
, lj
, lk
;
6 unsigned int ii
, ij
, ik
;
8 extern void opaquelong(unsigned long);
9 extern void opaqueint(unsigned int);
11 // CHECK-LABEL: define{{.*}} void @testlongadd()
12 void testlongadd(void) {
14 // CHECK: [[T1:%.*]] = load i64, ptr @lj
15 // CHECK-NEXT: [[T2:%.*]] = load i64, ptr @lk
16 // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 [[T2]])
17 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0
18 // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1
19 // CHECK: call void @__ubsan_handle_add_overflow
23 // CHECK-LABEL: define{{.*}} void @testlongsub()
24 void testlongsub(void) {
26 // CHECK: [[T1:%.*]] = load i64, ptr @lj
27 // CHECK-NEXT: [[T2:%.*]] = load i64, ptr @lk
28 // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[T1]], i64 [[T2]])
29 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0
30 // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1
31 // CHECK: call void @__ubsan_handle_sub_overflow
35 // CHECK-LABEL: define{{.*}} void @testlongmul()
36 void testlongmul(void) {
38 // CHECK: [[T1:%.*]] = load i64, ptr @lj
39 // CHECK-NEXT: [[T2:%.*]] = load i64, ptr @lk
40 // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[T1]], i64 [[T2]])
41 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0
42 // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1
43 // CHECK: call void @__ubsan_handle_mul_overflow
47 // CHECK-LABEL: define{{.*}} void @testlongpostinc()
48 void testlongpostinc(void) {
51 // CHECK: [[T1:%.*]] = load i64, ptr @li
52 // CHECK-NEXT: [[T2:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 1)
53 // CHECK-NEXT: [[T3:%.*]] = extractvalue { i64, i1 } [[T2]], 0
54 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T2]], 1
55 // CHECK: call void @__ubsan_handle_add_overflow
58 // CHECK-LABEL: define{{.*}} void @testlongpreinc()
59 void testlongpreinc(void) {
62 // CHECK: [[T1:%.*]] = load i64, ptr @li
63 // CHECK-NEXT: [[T2:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 1)
64 // CHECK-NEXT: [[T3:%.*]] = extractvalue { i64, i1 } [[T2]], 0
65 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T2]], 1
66 // CHECK: call void @__ubsan_handle_add_overflow
69 // CHECK-LABEL: define{{.*}} void @testintadd()
70 void testintadd(void) {
72 // CHECK: [[T1:%.*]] = load i32, ptr @ij
73 // CHECK-NEXT: [[T2:%.*]] = load i32, ptr @ik
74 // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 [[T2]])
75 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0
76 // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1
77 // CHECK: call void @__ubsan_handle_add_overflow
81 // CHECK-LABEL: define{{.*}} void @testintsub()
82 void testintsub(void) {
84 // CHECK: [[T1:%.*]] = load i32, ptr @ij
85 // CHECK-NEXT: [[T2:%.*]] = load i32, ptr @ik
86 // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[T1]], i32 [[T2]])
87 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0
88 // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1
89 // CHECK: call void @__ubsan_handle_sub_overflow
93 // CHECK-LABEL: define{{.*}} void @testintmul()
94 void testintmul(void) {
96 // CHECK: [[T1:%.*]] = load i32, ptr @ij
97 // CHECK-NEXT: [[T2:%.*]] = load i32, ptr @ik
98 // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 [[T2]])
99 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0
100 // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1
101 // CHECK: call void @__ubsan_handle_mul_overflow
105 // CHECK-LABEL: define{{.*}} void @testintpostinc()
106 void testintpostinc(void) {
109 // CHECK: [[T1:%.*]] = load i32, ptr @ii
110 // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 1)
111 // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0
112 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1
113 // CHECK: call void @__ubsan_handle_add_overflow
116 // CHECK-LABEL: define{{.*}} void @testintpreinc()
117 void testintpreinc(void) {
120 // CHECK: [[T1:%.*]] = load i32, ptr @ii
121 // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 1)
122 // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0
123 // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1
124 // CHECK: call void @__ubsan_handle_add_overflow