blob: c263c0c946b0ce0ee0f7b19c985f51f397596b30 [file] [log] [blame]
Will Dietzb8540362012-11-27 15:01:55 +00001// Check -fsanitize=signed-integer-overflow and
2// -fsanitize=unsigned-integer-overflow with promoted unsigned types
3//
4// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s \
5// RUN: -fsanitize=signed-integer-overflow | FileCheck %s --check-prefix=CHECKS
6// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s \
7// RUN: -fsanitize=unsigned-integer-overflow | FileCheck %s --check-prefix=CHECKU
8
9unsigned short si, sj, sk;
10unsigned char ci, cj, ck;
11
12extern void opaqueshort(unsigned short);
13extern void opaquechar(unsigned char);
14
15// CHECKS: define void @testshortadd()
16// CHECKU: define void @testshortadd()
17void testshortadd() {
18 // CHECKS: load i16* @sj
19 // CHECKS: load i16* @sk
20 // CHECKS: [[T1:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
21 // CHECKS-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
22 // CHECKS-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
23 // CHECKS: call void @__ubsan_handle_add_overflow
24 //
25 // CHECKU: [[T1:%.*]] = load i16* @sj
26 // CHECKU: [[T2:%.*]] = zext i16 [[T1]]
27 // CHECKU: [[T3:%.*]] = load i16* @sk
28 // CHECKU: [[T4:%.*]] = zext i16 [[T3]]
29 // CHECKU-NOT: llvm.sadd
30 // CHECKU-NOT: llvm.uadd
31 // CHECKU: [[T5:%.*]] = add nsw i32 [[T2]], [[T4]]
32
33 si = sj + sk;
34}
35
36// CHECKS: define void @testshortsub()
37// CHECKU: define void @testshortsub()
38void testshortsub() {
39
40 // CHECKS: load i16* @sj
41 // CHECKS: load i16* @sk
42 // CHECKS: [[T1:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
43 // CHECKS-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
44 // CHECKS-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
45 // CHECKS: call void @__ubsan_handle_sub_overflow
46 //
47 // CHECKU: [[T1:%.*]] = load i16* @sj
48 // CHECKU: [[T2:%.*]] = zext i16 [[T1]]
49 // CHECKU: [[T3:%.*]] = load i16* @sk
50 // CHECKU: [[T4:%.*]] = zext i16 [[T3]]
51 // CHECKU-NOT: llvm.ssub
52 // CHECKU-NOT: llvm.usub
53 // CHECKU: [[T5:%.*]] = sub nsw i32 [[T2]], [[T4]]
54
55 si = sj - sk;
56}
57
58// CHECKS: define void @testshortmul()
59// CHECKU: define void @testshortmul()
60void testshortmul() {
61
62 // CHECKS: load i16* @sj
63 // CHECKS: load i16* @sk
64 // CHECKS: [[T1:%.*]] = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
65 // CHECKS-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
66 // CHECKS-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
67 // CHECKS: call void @__ubsan_handle_mul_overflow
68 //
69 // CHECKU: [[T1:%.*]] = load i16* @sj
70 // CHECKU: [[T2:%.*]] = zext i16 [[T1]]
71 // CHECKU: [[T3:%.*]] = load i16* @sk
72 // CHECKU: [[T4:%.*]] = zext i16 [[T3]]
73 // CHECKU-NOT: llvm.smul
74 // CHECKU-NOT: llvm.umul
75 // CHECKU: [[T5:%.*]] = mul nsw i32 [[T2]], [[T4]]
76 si = sj * sk;
77}
78
79// CHECKS: define void @testcharadd()
80// CHECKU: define void @testcharadd()
81void testcharadd() {
82
83 // CHECKS: load i8* @cj
84 // CHECKS: load i8* @ck
85 // CHECKS: [[T1:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
86 // CHECKS-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
87 // CHECKS-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
88 // CHECKS: call void @__ubsan_handle_add_overflow
89 //
90 // CHECKU: [[T1:%.*]] = load i8* @cj
91 // CHECKU: [[T2:%.*]] = zext i8 [[T1]]
92 // CHECKU: [[T3:%.*]] = load i8* @ck
93 // CHECKU: [[T4:%.*]] = zext i8 [[T3]]
94 // CHECKU-NOT: llvm.sadd
95 // CHECKU-NOT: llvm.uadd
96 // CHECKU: [[T5:%.*]] = add nsw i32 [[T2]], [[T4]]
97
98 ci = cj + ck;
99}
100
101// CHECKS: define void @testcharsub()
102// CHECKU: define void @testcharsub()
103void testcharsub() {
104
105 // CHECKS: load i8* @cj
106 // CHECKS: load i8* @ck
107 // CHECKS: [[T1:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
108 // CHECKS-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
109 // CHECKS-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
110 // CHECKS: call void @__ubsan_handle_sub_overflow
111 //
112 // CHECKU: [[T1:%.*]] = load i8* @cj
113 // CHECKU: [[T2:%.*]] = zext i8 [[T1]]
114 // CHECKU: [[T3:%.*]] = load i8* @ck
115 // CHECKU: [[T4:%.*]] = zext i8 [[T3]]
116 // CHECKU-NOT: llvm.ssub
117 // CHECKU-NOT: llvm.usub
118 // CHECKU: [[T5:%.*]] = sub nsw i32 [[T2]], [[T4]]
119
120 ci = cj - ck;
121}
122
123// CHECKS: define void @testcharmul()
124// CHECKU: define void @testcharmul()
125void testcharmul() {
126
127 // CHECKS: load i8* @cj
128 // CHECKS: load i8* @ck
129 // CHECKS: [[T1:%.*]] = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
130 // CHECKS-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
131 // CHECKS-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
132 // CHECKS: call void @__ubsan_handle_mul_overflow
133 //
134 // CHECKU: [[T1:%.*]] = load i8* @cj
135 // CHECKU: [[T2:%.*]] = zext i8 [[T1]]
136 // CHECKU: [[T3:%.*]] = load i8* @ck
137 // CHECKU: [[T4:%.*]] = zext i8 [[T3]]
138 // CHECKU-NOT: llvm.smul
139 // CHECKU-NOT: llvm.umul
140 // CHECKU: [[T5:%.*]] = mul nsw i32 [[T2]], [[T4]]
141
142 ci = cj * ck;
143}