xref: /aosp_15_r20/external/clang/test/CodeGen/builtins-overflow.c (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // Test CodeGen for Security Check Overflow Builtins.
2*67e74705SXin Li // rdar://13421498
3*67e74705SXin Li 
4*67e74705SXin Li // RUN: %clang_cc1 -triple "i686-unknown-unknown"   -emit-llvm -x c %s -o - | FileCheck %s
5*67e74705SXin Li // RUN: %clang_cc1 -triple "x86_64-unknown-unknown" -emit-llvm -x c %s -o - | FileCheck %s
6*67e74705SXin Li // RUN: %clang_cc1 -triple "x86_64-mingw32"         -emit-llvm -x c %s -o - | FileCheck %s
7*67e74705SXin Li 
8*67e74705SXin Li extern unsigned UnsignedErrorCode;
9*67e74705SXin Li extern unsigned long UnsignedLongErrorCode;
10*67e74705SXin Li extern unsigned long long UnsignedLongLongErrorCode;
11*67e74705SXin Li extern int IntErrorCode;
12*67e74705SXin Li extern long LongErrorCode;
13*67e74705SXin Li extern long long LongLongErrorCode;
14*67e74705SXin Li void overflowed(void);
15*67e74705SXin Li 
test_add_overflow_uint_uint_uint(unsigned x,unsigned y)16*67e74705SXin Li unsigned test_add_overflow_uint_uint_uint(unsigned x, unsigned y) {
17*67e74705SXin Li   // CHECK-LABEL: define i32 @test_add_overflow_uint_uint_uint
18*67e74705SXin Li   // CHECK-NOT: ext
19*67e74705SXin Li   // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
20*67e74705SXin Li   // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
21*67e74705SXin Li   // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
22*67e74705SXin Li   // CHECK: store i32 [[Q]], i32*
23*67e74705SXin Li   // CHECK: br i1 [[C]]
24*67e74705SXin Li   unsigned r;
25*67e74705SXin Li   if (__builtin_add_overflow(x, y, &r))
26*67e74705SXin Li     overflowed();
27*67e74705SXin Li   return r;
28*67e74705SXin Li }
29*67e74705SXin Li 
test_add_overflow_int_int_int(int x,int y)30*67e74705SXin Li int test_add_overflow_int_int_int(int x, int y) {
31*67e74705SXin Li   // CHECK-LABEL: define i32 @test_add_overflow_int_int_int
32*67e74705SXin Li   // CHECK-NOT: ext
33*67e74705SXin Li   // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
34*67e74705SXin Li   // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
35*67e74705SXin Li   // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
36*67e74705SXin Li   // CHECK: store i32 [[Q]], i32*
37*67e74705SXin Li   // CHECK: br i1 [[C]]
38*67e74705SXin Li   int r;
39*67e74705SXin Li   if (__builtin_add_overflow(x, y, &r))
40*67e74705SXin Li     overflowed();
41*67e74705SXin Li   return r;
42*67e74705SXin Li }
43*67e74705SXin Li 
test_sub_overflow_uint_uint_uint(unsigned x,unsigned y)44*67e74705SXin Li unsigned test_sub_overflow_uint_uint_uint(unsigned x, unsigned y) {
45*67e74705SXin Li   // CHECK-LABEL: define i32 @test_sub_overflow_uint_uint_uint
46*67e74705SXin Li   // CHECK-NOT: ext
47*67e74705SXin Li   // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
48*67e74705SXin Li   // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
49*67e74705SXin Li   // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
50*67e74705SXin Li   // CHECK: store i32 [[Q]], i32*
51*67e74705SXin Li   // CHECK: br i1 [[C]]
52*67e74705SXin Li   unsigned r;
53*67e74705SXin Li   if (__builtin_sub_overflow(x, y, &r))
54*67e74705SXin Li     overflowed();
55*67e74705SXin Li   return r;
56*67e74705SXin Li }
57*67e74705SXin Li 
test_sub_overflow_int_int_int(int x,int y)58*67e74705SXin Li int test_sub_overflow_int_int_int(int x, int y) {
59*67e74705SXin Li   // CHECK-LABEL: define i32 @test_sub_overflow_int_int_int
60*67e74705SXin Li   // CHECK-NOT: ext
61*67e74705SXin Li   // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
62*67e74705SXin Li   // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
63*67e74705SXin Li   // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
64*67e74705SXin Li   // CHECK: store i32 [[Q]], i32*
65*67e74705SXin Li   // CHECK: br i1 [[C]]
66*67e74705SXin Li   int r;
67*67e74705SXin Li   if (__builtin_sub_overflow(x, y, &r))
68*67e74705SXin Li     overflowed();
69*67e74705SXin Li   return r;
70*67e74705SXin Li }
71*67e74705SXin Li 
test_mul_overflow_uint_uint_uint(unsigned x,unsigned y)72*67e74705SXin Li unsigned test_mul_overflow_uint_uint_uint(unsigned x, unsigned y) {
73*67e74705SXin Li   // CHECK-LABEL: define i32 @test_mul_overflow_uint_uint_uint
74*67e74705SXin Li   // CHECK-NOT: ext
75*67e74705SXin Li   // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
76*67e74705SXin Li   // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
77*67e74705SXin Li   // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
78*67e74705SXin Li   // CHECK: store i32 [[Q]], i32*
79*67e74705SXin Li   // CHECK: br i1 [[C]]
80*67e74705SXin Li   unsigned r;
81*67e74705SXin Li   if (__builtin_mul_overflow(x, y, &r))
82*67e74705SXin Li     overflowed();
83*67e74705SXin Li   return r;
84*67e74705SXin Li }
85*67e74705SXin Li 
test_mul_overflow_int_int_int(int x,int y)86*67e74705SXin Li int test_mul_overflow_int_int_int(int x, int y) {
87*67e74705SXin Li   // CHECK-LABEL: define i32 @test_mul_overflow_int_int_int
88*67e74705SXin Li   // CHECK-NOT: ext
89*67e74705SXin Li   // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
90*67e74705SXin Li   // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
91*67e74705SXin Li   // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
92*67e74705SXin Li   // CHECK: store i32 [[Q]], i32*
93*67e74705SXin Li   // CHECK: br i1 [[C]]
94*67e74705SXin Li   int r;
95*67e74705SXin Li   if (__builtin_mul_overflow(x, y, &r))
96*67e74705SXin Li     overflowed();
97*67e74705SXin Li   return r;
98*67e74705SXin Li }
99*67e74705SXin Li 
test_add_overflow_uint_int_int(unsigned x,int y)100*67e74705SXin Li int test_add_overflow_uint_int_int(unsigned x, int y) {
101*67e74705SXin Li   // CHECK-LABEL: define i32 @test_add_overflow_uint_int_int
102*67e74705SXin Li   // CHECK: [[XE:%.+]] = zext i32 %{{.+}} to i33
103*67e74705SXin Li   // CHECK: [[YE:%.+]] = sext i32 %{{.+}} to i33
104*67e74705SXin Li   // CHECK: [[S:%.+]] = call { i33, i1 } @llvm.sadd.with.overflow.i33(i33 [[XE]], i33 [[YE]])
105*67e74705SXin Li   // CHECK-DAG: [[Q:%.+]] = extractvalue { i33, i1 } [[S]], 0
106*67e74705SXin Li   // CHECK-DAG: [[C1:%.+]] = extractvalue { i33, i1 } [[S]], 1
107*67e74705SXin Li   // CHECK: [[QT:%.+]] = trunc i33 [[Q]] to i32
108*67e74705SXin Li   // CHECK: [[QTE:%.+]] = sext i32 [[QT]] to i33
109*67e74705SXin Li   // CHECK: [[C2:%.+]] = icmp ne i33 [[Q]], [[QTE]]
110*67e74705SXin Li   // CHECK: [[C3:%.+]] = or i1 [[C1]], [[C2]]
111*67e74705SXin Li   // CHECK: store i32 [[QT]], i32*
112*67e74705SXin Li   // CHECK: br i1 [[C3]]
113*67e74705SXin Li   int r;
114*67e74705SXin Li   if (__builtin_add_overflow(x, y, &r))
115*67e74705SXin Li     overflowed();
116*67e74705SXin Li   return r;
117*67e74705SXin Li }
118*67e74705SXin Li 
test_add_overflow_uint_uint_bool(unsigned x,unsigned y)119*67e74705SXin Li _Bool test_add_overflow_uint_uint_bool(unsigned x, unsigned y) {
120*67e74705SXin Li   // CHECK-LABEL: define {{.*}} i1 @test_add_overflow_uint_uint_bool
121*67e74705SXin Li   // CHECK-NOT: ext
122*67e74705SXin Li   // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
123*67e74705SXin Li   // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
124*67e74705SXin Li   // CHECK-DAG: [[C1:%.+]] = extractvalue { i32, i1 } [[S]], 1
125*67e74705SXin Li   // CHECK: [[QT:%.+]] = trunc i32 [[Q]] to i1
126*67e74705SXin Li   // CHECK: [[QTE:%.+]] = zext i1 [[QT]] to i32
127*67e74705SXin Li   // CHECK: [[C2:%.+]] = icmp ne i32 [[Q]], [[QTE]]
128*67e74705SXin Li   // CHECK: [[C3:%.+]] = or i1 [[C1]], [[C2]]
129*67e74705SXin Li   // CHECK: [[QT2:%.+]] = zext i1 [[QT]] to i8
130*67e74705SXin Li   // CHECK: store i8 [[QT2]], i8*
131*67e74705SXin Li   // CHECK: br i1 [[C3]]
132*67e74705SXin Li   _Bool r;
133*67e74705SXin Li   if (__builtin_add_overflow(x, y, &r))
134*67e74705SXin Li     overflowed();
135*67e74705SXin Li   return r;
136*67e74705SXin Li }
137*67e74705SXin Li 
test_add_overflow_bool_bool_uint(_Bool x,_Bool y)138*67e74705SXin Li unsigned test_add_overflow_bool_bool_uint(_Bool x, _Bool y) {
139*67e74705SXin Li   // CHECK-LABEL: define i32 @test_add_overflow_bool_bool_uint
140*67e74705SXin Li   // CHECK: [[XE:%.+]] = zext i1 %{{.+}} to i32
141*67e74705SXin Li   // CHECK: [[YE:%.+]] = zext i1 %{{.+}} to i32
142*67e74705SXin Li   // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[XE]], i32 [[YE]])
143*67e74705SXin Li   // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
144*67e74705SXin Li   // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
145*67e74705SXin Li   // CHECK: store i32 [[Q]], i32*
146*67e74705SXin Li   // CHECK: br i1 [[C]]
147*67e74705SXin Li   unsigned r;
148*67e74705SXin Li   if (__builtin_add_overflow(x, y, &r))
149*67e74705SXin Li     overflowed();
150*67e74705SXin Li   return r;
151*67e74705SXin Li }
152*67e74705SXin Li 
test_add_overflow_bool_bool_bool(_Bool x,_Bool y)153*67e74705SXin Li _Bool test_add_overflow_bool_bool_bool(_Bool x, _Bool y) {
154*67e74705SXin Li   // CHECK-LABEL: define {{.*}} i1 @test_add_overflow_bool_bool_bool
155*67e74705SXin Li   // CHECK: [[S:%.+]] = call { i1, i1 } @llvm.uadd.with.overflow.i1(i1 %{{.+}}, i1 %{{.+}})
156*67e74705SXin Li   // CHECK-DAG: [[Q:%.+]] = extractvalue { i1, i1 } [[S]], 0
157*67e74705SXin Li   // CHECK-DAG: [[C:%.+]] = extractvalue { i1, i1 } [[S]], 1
158*67e74705SXin Li   // CHECK: [[QT2:%.+]] = zext i1 [[Q]] to i8
159*67e74705SXin Li   // CHECK: store i8 [[QT2]], i8*
160*67e74705SXin Li   // CHECK: br i1 [[C]]
161*67e74705SXin Li   _Bool r;
162*67e74705SXin Li   if (__builtin_add_overflow(x, y, &r))
163*67e74705SXin Li     overflowed();
164*67e74705SXin Li   return r;
165*67e74705SXin Li }
166*67e74705SXin Li 
test_add_overflow_volatile(int x,int y)167*67e74705SXin Li int test_add_overflow_volatile(int x, int y) {
168*67e74705SXin Li   // CHECK-LABEL: define i32 @test_add_overflow_volatile
169*67e74705SXin Li   // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
170*67e74705SXin Li   // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
171*67e74705SXin Li   // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
172*67e74705SXin Li   // CHECK: store volatile i32 [[Q]], i32*
173*67e74705SXin Li   // CHECK: br i1 [[C]]
174*67e74705SXin Li   volatile int result;
175*67e74705SXin Li   if (__builtin_add_overflow(x, y, &result))
176*67e74705SXin Li     overflowed();
177*67e74705SXin Li   return result;
178*67e74705SXin Li }
179*67e74705SXin Li 
test_uadd_overflow(unsigned x,unsigned y)180*67e74705SXin Li unsigned test_uadd_overflow(unsigned x, unsigned y) {
181*67e74705SXin Li // CHECK: @test_uadd_overflow
182*67e74705SXin Li // CHECK: %{{.+}} = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
183*67e74705SXin Li   unsigned result;
184*67e74705SXin Li   if (__builtin_uadd_overflow(x, y, &result))
185*67e74705SXin Li     return UnsignedErrorCode;
186*67e74705SXin Li   return result;
187*67e74705SXin Li }
188*67e74705SXin Li 
test_uaddl_overflow(unsigned long x,unsigned long y)189*67e74705SXin Li unsigned long test_uaddl_overflow(unsigned long x, unsigned long y) {
190*67e74705SXin Li // CHECK: @test_uaddl_overflow([[UL:i32|i64]] %x
191*67e74705SXin Li // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.uadd.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})
192*67e74705SXin Li   unsigned long result;
193*67e74705SXin Li   if (__builtin_uaddl_overflow(x, y, &result))
194*67e74705SXin Li     return UnsignedLongErrorCode;
195*67e74705SXin Li   return result;
196*67e74705SXin Li }
197*67e74705SXin Li 
test_uaddll_overflow(unsigned long long x,unsigned long long y)198*67e74705SXin Li unsigned long long test_uaddll_overflow(unsigned long long x, unsigned long long y) {
199*67e74705SXin Li // CHECK: @test_uaddll_overflow
200*67e74705SXin Li // CHECK: %{{.+}} = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})
201*67e74705SXin Li   unsigned long long result;
202*67e74705SXin Li   if (__builtin_uaddll_overflow(x, y, &result))
203*67e74705SXin Li     return UnsignedLongLongErrorCode;
204*67e74705SXin Li   return result;
205*67e74705SXin Li }
206*67e74705SXin Li 
test_usub_overflow(unsigned x,unsigned y)207*67e74705SXin Li unsigned test_usub_overflow(unsigned x, unsigned y) {
208*67e74705SXin Li // CHECK: @test_usub_overflow
209*67e74705SXin Li // CHECK: %{{.+}} = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
210*67e74705SXin Li   unsigned result;
211*67e74705SXin Li   if (__builtin_usub_overflow(x, y, &result))
212*67e74705SXin Li     return UnsignedErrorCode;
213*67e74705SXin Li   return result;
214*67e74705SXin Li }
215*67e74705SXin Li 
test_usubl_overflow(unsigned long x,unsigned long y)216*67e74705SXin Li unsigned long test_usubl_overflow(unsigned long x, unsigned long y) {
217*67e74705SXin Li // CHECK: @test_usubl_overflow([[UL:i32|i64]] %x
218*67e74705SXin Li // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.usub.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})
219*67e74705SXin Li   unsigned long result;
220*67e74705SXin Li   if (__builtin_usubl_overflow(x, y, &result))
221*67e74705SXin Li     return UnsignedLongErrorCode;
222*67e74705SXin Li   return result;
223*67e74705SXin Li }
224*67e74705SXin Li 
test_usubll_overflow(unsigned long long x,unsigned long long y)225*67e74705SXin Li unsigned long long test_usubll_overflow(unsigned long long x, unsigned long long y) {
226*67e74705SXin Li // CHECK: @test_usubll_overflow
227*67e74705SXin Li // CHECK: %{{.+}} = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})
228*67e74705SXin Li   unsigned long long result;
229*67e74705SXin Li   if (__builtin_usubll_overflow(x, y, &result))
230*67e74705SXin Li     return UnsignedLongLongErrorCode;
231*67e74705SXin Li   return result;
232*67e74705SXin Li }
233*67e74705SXin Li 
test_umul_overflow(unsigned x,unsigned y)234*67e74705SXin Li unsigned test_umul_overflow(unsigned x, unsigned y) {
235*67e74705SXin Li // CHECK: @test_umul_overflow
236*67e74705SXin Li // CHECK: %{{.+}} = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
237*67e74705SXin Li   unsigned result;
238*67e74705SXin Li   if (__builtin_umul_overflow(x, y, &result))
239*67e74705SXin Li     return UnsignedErrorCode;
240*67e74705SXin Li   return result;
241*67e74705SXin Li }
242*67e74705SXin Li 
test_umull_overflow(unsigned long x,unsigned long y)243*67e74705SXin Li unsigned long test_umull_overflow(unsigned long x, unsigned long y) {
244*67e74705SXin Li // CHECK: @test_umull_overflow([[UL:i32|i64]] %x
245*67e74705SXin Li // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.umul.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})
246*67e74705SXin Li   unsigned long result;
247*67e74705SXin Li   if (__builtin_umull_overflow(x, y, &result))
248*67e74705SXin Li     return UnsignedLongErrorCode;
249*67e74705SXin Li   return result;
250*67e74705SXin Li }
251*67e74705SXin Li 
test_umulll_overflow(unsigned long long x,unsigned long long y)252*67e74705SXin Li unsigned long long test_umulll_overflow(unsigned long long x, unsigned long long y) {
253*67e74705SXin Li // CHECK: @test_umulll_overflow
254*67e74705SXin Li // CHECK: %{{.+}} = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})
255*67e74705SXin Li   unsigned long long result;
256*67e74705SXin Li   if (__builtin_umulll_overflow(x, y, &result))
257*67e74705SXin Li     return UnsignedLongLongErrorCode;
258*67e74705SXin Li   return result;
259*67e74705SXin Li }
260*67e74705SXin Li 
test_sadd_overflow(int x,int y)261*67e74705SXin Li int test_sadd_overflow(int x, int y) {
262*67e74705SXin Li // CHECK: @test_sadd_overflow
263*67e74705SXin Li // CHECK: %{{.+}} = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
264*67e74705SXin Li   int result;
265*67e74705SXin Li   if (__builtin_sadd_overflow(x, y, &result))
266*67e74705SXin Li     return IntErrorCode;
267*67e74705SXin Li   return result;
268*67e74705SXin Li }
269*67e74705SXin Li 
test_saddl_overflow(long x,long y)270*67e74705SXin Li long test_saddl_overflow(long x, long y) {
271*67e74705SXin Li // CHECK: @test_saddl_overflow([[UL:i32|i64]] %x
272*67e74705SXin Li // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.sadd.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})
273*67e74705SXin Li   long result;
274*67e74705SXin Li   if (__builtin_saddl_overflow(x, y, &result))
275*67e74705SXin Li     return LongErrorCode;
276*67e74705SXin Li   return result;
277*67e74705SXin Li }
278*67e74705SXin Li 
test_saddll_overflow(long long x,long long y)279*67e74705SXin Li long long test_saddll_overflow(long long x, long long y) {
280*67e74705SXin Li // CHECK: @test_saddll_overflow
281*67e74705SXin Li // CHECK: %{{.+}} = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})
282*67e74705SXin Li   long long result;
283*67e74705SXin Li   if (__builtin_saddll_overflow(x, y, &result))
284*67e74705SXin Li     return LongLongErrorCode;
285*67e74705SXin Li   return result;
286*67e74705SXin Li }
287*67e74705SXin Li 
test_ssub_overflow(int x,int y)288*67e74705SXin Li int test_ssub_overflow(int x, int y) {
289*67e74705SXin Li // CHECK: @test_ssub_overflow
290*67e74705SXin Li // CHECK: %{{.+}} = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
291*67e74705SXin Li   int result;
292*67e74705SXin Li   if (__builtin_ssub_overflow(x, y, &result))
293*67e74705SXin Li     return IntErrorCode;
294*67e74705SXin Li   return result;
295*67e74705SXin Li }
296*67e74705SXin Li 
test_ssubl_overflow(long x,long y)297*67e74705SXin Li long test_ssubl_overflow(long x, long y) {
298*67e74705SXin Li // CHECK: @test_ssubl_overflow([[UL:i32|i64]] %x
299*67e74705SXin Li // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.ssub.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})
300*67e74705SXin Li   long result;
301*67e74705SXin Li   if (__builtin_ssubl_overflow(x, y, &result))
302*67e74705SXin Li     return LongErrorCode;
303*67e74705SXin Li   return result;
304*67e74705SXin Li }
305*67e74705SXin Li 
test_ssubll_overflow(long long x,long long y)306*67e74705SXin Li long long test_ssubll_overflow(long long x, long long y) {
307*67e74705SXin Li // CHECK: @test_ssubll_overflow
308*67e74705SXin Li // CHECK: %{{.+}} = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})
309*67e74705SXin Li   long long result;
310*67e74705SXin Li   if (__builtin_ssubll_overflow(x, y, &result))
311*67e74705SXin Li     return LongLongErrorCode;
312*67e74705SXin Li   return result;
313*67e74705SXin Li }
314*67e74705SXin Li 
test_smul_overflow(int x,int y)315*67e74705SXin Li int test_smul_overflow(int x, int y) {
316*67e74705SXin Li // CHECK: @test_smul_overflow
317*67e74705SXin Li // CHECK: %{{.+}} = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
318*67e74705SXin Li   int result;
319*67e74705SXin Li   if (__builtin_smul_overflow(x, y, &result))
320*67e74705SXin Li     return IntErrorCode;
321*67e74705SXin Li   return result;
322*67e74705SXin Li }
323*67e74705SXin Li 
test_smull_overflow(long x,long y)324*67e74705SXin Li long test_smull_overflow(long x, long y) {
325*67e74705SXin Li // CHECK: @test_smull_overflow([[UL:i32|i64]] %x
326*67e74705SXin Li // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.smul.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})
327*67e74705SXin Li   long result;
328*67e74705SXin Li   if (__builtin_smull_overflow(x, y, &result))
329*67e74705SXin Li     return LongErrorCode;
330*67e74705SXin Li   return result;
331*67e74705SXin Li }
332*67e74705SXin Li 
test_smulll_overflow(long long x,long long y)333*67e74705SXin Li long long test_smulll_overflow(long long x, long long y) {
334*67e74705SXin Li // CHECK: @test_smulll_overflow
335*67e74705SXin Li // CHECK: %{{.+}} = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})
336*67e74705SXin Li   long long result;
337*67e74705SXin Li   if (__builtin_smulll_overflow(x, y, &result))
338*67e74705SXin Li     return LongLongErrorCode;
339*67e74705SXin Li   return result;
340*67e74705SXin Li }
341