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