xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGen/unsigned-promotion.c (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
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