xref: /llvm-project/clang/test/CodeGen/builtins-overflow.c (revision f193bcc701de8311e9f40730f2187d6df2e8667c)
1 // Test CodeGen for Security Check Overflow Builtins.
2 // rdar://13421498
3 
4 // RUN: %clang_cc1 -triple "i686-unknown-unknown"   -emit-llvm -x c %s -o - | FileCheck -DLONG_TYPE=i32 -DLONG_MAX=2147483647 %s
5 // RUN: %clang_cc1 -triple "x86_64-unknown-unknown" -emit-llvm -x c %s -o - | FileCheck -DLONG_TYPE=i64 -DLONG_MAX=9223372036854775807 %s
6 // RUN: %clang_cc1 -triple "x86_64-mingw32"         -emit-llvm -x c %s -o - | FileCheck -DLONG_TYPE=i32 -DLONG_MAX=2147483647 %s
7 
8 extern unsigned UnsignedErrorCode;
9 extern unsigned long UnsignedLongErrorCode;
10 extern unsigned long long UnsignedLongLongErrorCode;
11 extern int IntErrorCode;
12 extern long LongErrorCode;
13 extern long long LongLongErrorCode;
14 void overflowed(void);
15 
16 unsigned test_add_overflow_uint_uint_uint(unsigned x, unsigned y) {
17   // CHECK-LABEL: define {{(dso_local )?}}i32 @test_add_overflow_uint_uint_uint
18   // CHECK-NOT: ext
19   // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
20   // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
21   // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
22   // CHECK: store i32 [[Q]], i32*
23   // CHECK: br i1 [[C]]
24   unsigned r;
25   if (__builtin_add_overflow(x, y, &r))
26     overflowed();
27   return r;
28 }
29 
30 int test_add_overflow_int_int_int(int x, int y) {
31   // CHECK-LABEL: define {{(dso_local )?}}i32 @test_add_overflow_int_int_int
32   // CHECK-NOT: ext
33   // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
34   // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
35   // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
36   // CHECK: store i32 [[Q]], i32*
37   // CHECK: br i1 [[C]]
38   int r;
39   if (__builtin_add_overflow(x, y, &r))
40     overflowed();
41   return r;
42 }
43 
44 int test_add_overflow_xint31_xint31_xint31(_ExtInt(31) x, _ExtInt(31) y) {
45   // CHECK-LABEL: define {{(dso_local )?}}i32 @test_add_overflow_xint31_xint31_xint31({{.+}})
46   // CHECK-NOT: ext
47   // CHECK: [[S:%.+]] = call { i31, i1 } @llvm.sadd.with.overflow.i31(i31 %{{.+}}, i31 %{{.+}})
48   // CHECK-DAG: [[C:%.+]] = extractvalue { i31, i1 } [[S]], 1
49   // CHECK-DAG: [[Q:%.+]] = extractvalue { i31, i1 } [[S]], 0
50   // CHECK: store i31 [[Q]], i31*
51   // CHECK: br i1 [[C]]
52   _ExtInt(31) r;
53   if (__builtin_add_overflow(x, y, &r))
54     overflowed();
55   return r;
56 }
57 
58 unsigned test_sub_overflow_uint_uint_uint(unsigned x, unsigned y) {
59   // CHECK-LABEL: define {{(dso_local )?}}i32 @test_sub_overflow_uint_uint_uint
60   // CHECK-NOT: ext
61   // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
62   // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
63   // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
64   // CHECK: store i32 [[Q]], i32*
65   // CHECK: br i1 [[C]]
66   unsigned r;
67   if (__builtin_sub_overflow(x, y, &r))
68     overflowed();
69   return r;
70 }
71 
72 int test_sub_overflow_int_int_int(int x, int y) {
73   // CHECK-LABEL: define {{(dso_local )?}}i32 @test_sub_overflow_int_int_int
74   // CHECK-NOT: ext
75   // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
76   // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
77   // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
78   // CHECK: store i32 [[Q]], i32*
79   // CHECK: br i1 [[C]]
80   int r;
81   if (__builtin_sub_overflow(x, y, &r))
82     overflowed();
83   return r;
84 }
85 
86 int test_sub_overflow_xint31_xint31_xint31(_ExtInt(31) x, _ExtInt(31) y) {
87   // CHECK-LABEL: define {{(dso_local )?}}i32 @test_sub_overflow_xint31_xint31_xint31({{.+}})
88   // CHECK-NOT: ext
89   // CHECK: [[S:%.+]] = call { i31, i1 } @llvm.ssub.with.overflow.i31(i31 %{{.+}}, i31 %{{.+}})
90   // CHECK-DAG: [[C:%.+]] = extractvalue { i31, i1 } [[S]], 1
91   // CHECK-DAG: [[Q:%.+]] = extractvalue { i31, i1 } [[S]], 0
92   // CHECK: store i31 [[Q]], i31*
93   // CHECK: br i1 [[C]]
94   _ExtInt(31) r;
95   if (__builtin_sub_overflow(x, y, &r))
96     overflowed();
97   return r;
98 }
99 
100 unsigned test_mul_overflow_uint_uint_uint(unsigned x, unsigned y) {
101   // CHECK-LABEL: define {{(dso_local )?}}i32 @test_mul_overflow_uint_uint_uint
102   // CHECK-NOT: ext
103   // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
104   // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
105   // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
106   // CHECK: store i32 [[Q]], i32*
107   // CHECK: br i1 [[C]]
108   unsigned r;
109   if (__builtin_mul_overflow(x, y, &r))
110     overflowed();
111   return r;
112 }
113 
114 int test_mul_overflow_uint_uint_int(unsigned x, unsigned y) {
115   // CHECK-LABEL: define {{(dso_local )?}}i32 @test_mul_overflow_uint_uint_int
116   // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
117   // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
118   // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
119   // CHECK: [[C1:%.+]] = icmp ugt i32 [[Q]], 2147483647
120   // CHECK: [[C2:%.+]] = or i1 [[C]], [[C1]]
121   // CHECK: store i32 [[Q]], i32*
122   // CHECK: br i1 [[C2]]
123   int r;
124   if (__builtin_mul_overflow(x, y, &r))
125     overflowed();
126   return r;
127 }
128 
129 int test_mul_overflow_uint_uint_int_volatile(unsigned x, unsigned y) {
130   // CHECK-LABEL: define {{(dso_local )?}}i32 @test_mul_overflow_uint_uint_int_volatile
131   // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
132   // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
133   // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
134   // CHECK: [[C1:%.+]] = icmp ugt i32 [[Q]], 2147483647
135   // CHECK: [[C2:%.+]] = or i1 [[C]], [[C1]]
136   // CHECK: store volatile i32 [[Q]], i32*
137   // CHECK: br i1 [[C2]]
138   volatile int r;
139   if (__builtin_mul_overflow(x, y, &r))
140     overflowed();
141   return r;
142 }
143 
144 long test_mul_overflow_ulong_ulong_long(unsigned long x, unsigned long y) {
145   // CHECK-LABEL: @test_mul_overflow_ulong_ulong_long
146   // CHECK: [[S:%.+]] =  call { [[LONG_TYPE]], i1 } @llvm.umul.with.overflow.[[LONG_TYPE]]([[LONG_TYPE]] %{{.+}}, [[LONG_TYPE]] %{{.+}})
147   // CHECK-DAG: [[Q:%.+]] = extractvalue { [[LONG_TYPE]], i1 } [[S]], 0
148   // CHECK-DAG: [[C:%.+]] = extractvalue { [[LONG_TYPE]], i1 } [[S]], 1
149   // CHECK: [[C1:%.+]] = icmp ugt [[LONG_TYPE]] [[Q]], [[LONG_MAX]]
150   // CHECK: [[C2:%.+]] = or i1 [[C]], [[C1]]
151   // LONG64: store [[LONG_TYPE]] [[Q]], [[LONG_TYPE]]*
152   // LONG64: br i1 [[C2]]
153   long r;
154   if (__builtin_mul_overflow(x, y, &r))
155     overflowed();
156   return r;
157 }
158 
159 int test_mul_overflow_int_int_int(int x, int y) {
160   // CHECK-LABEL: define {{(dso_local )?}}i32 @test_mul_overflow_int_int_int
161   // CHECK-NOT: ext
162   // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
163   // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
164   // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
165   // CHECK: store i32 [[Q]], i32*
166   // CHECK: br i1 [[C]]
167   int r;
168   if (__builtin_mul_overflow(x, y, &r))
169     overflowed();
170   return r;
171 }
172 
173 int test_mul_overflow_xint31_xint31_xint31(_ExtInt(31) x, _ExtInt(31) y) {
174   // CHECK-LABEL: define {{(dso_local )?}}i32 @test_mul_overflow_xint31_xint31_xint31({{.+}})
175   // CHECK-NOT: ext
176   // CHECK: [[S:%.+]] = call { i31, i1 } @llvm.smul.with.overflow.i31(i31 %{{.+}}, i31 %{{.+}})
177   // CHECK-DAG: [[C:%.+]] = extractvalue { i31, i1 } [[S]], 1
178   // CHECK-DAG: [[Q:%.+]] = extractvalue { i31, i1 } [[S]], 0
179   // CHECK: store i31 [[Q]], i31*
180   // CHECK: br i1 [[C]]
181   _ExtInt(31) r;
182   if (__builtin_mul_overflow(x, y, &r))
183     overflowed();
184   return r;
185 }
186 
187 int test_mul_overflow_xint127_xint127_xint127(_ExtInt(127) x, _ExtInt(127) y) {
188   // CHECK-LABEL: define {{(dso_local )?}}i32 @test_mul_overflow_xint127_xint127_xint127({{.+}})
189   // CHECK-NOT: ext
190   // CHECK: [[S:%.+]] = call { i127, i1 } @llvm.smul.with.overflow.i127(i127 %{{.+}}, i127 %{{.+}})
191   // CHECK-DAG: [[C:%.+]] = extractvalue { i127, i1 } [[S]], 1
192   // CHECK-DAG: [[Q:%.+]] = extractvalue { i127, i1 } [[S]], 0
193   // CHECK: store i127 [[Q]], i127*
194   // CHECK: br i1 [[C]]
195   _ExtInt(127) r;
196   if (__builtin_mul_overflow(x, y, &r))
197     overflowed();
198   return r;
199 }
200 
201 int test_mul_overflow_xint128_xint128_xint128(_ExtInt(128) x, _ExtInt(128) y) {
202   // CHECK-LABEL: define {{(dso_local )?}}i32 @test_mul_overflow_xint128_xint128_xint128({{.+}})
203   // CHECK-NOT: ext
204   // CHECK: [[S:%.+]] = call { i128, i1 } @llvm.smul.with.overflow.i128(i128 %{{.+}}, i128 %{{.+}})
205   // CHECK-DAG: [[C:%.+]] = extractvalue { i128, i1 } [[S]], 1
206   // CHECK-DAG: [[Q:%.+]] = extractvalue { i128, i1 } [[S]], 0
207   // CHECK: store i128 [[Q]], i128*
208   // CHECK: br i1 [[C]]
209   _ExtInt(128) r;
210   if (__builtin_mul_overflow(x, y, &r))
211     overflowed();
212   return r;
213 }
214 
215 int test_add_overflow_uint_int_int(unsigned x, int y) {
216   // CHECK-LABEL: define {{(dso_local )?}}i32 @test_add_overflow_uint_int_int
217   // CHECK: [[XE:%.+]] = zext i32 %{{.+}} to i33
218   // CHECK: [[YE:%.+]] = sext i32 %{{.+}} to i33
219   // CHECK: [[S:%.+]] = call { i33, i1 } @llvm.sadd.with.overflow.i33(i33 [[XE]], i33 [[YE]])
220   // CHECK-DAG: [[Q:%.+]] = extractvalue { i33, i1 } [[S]], 0
221   // CHECK-DAG: [[C1:%.+]] = extractvalue { i33, i1 } [[S]], 1
222   // CHECK: [[QT:%.+]] = trunc i33 [[Q]] to i32
223   // CHECK: [[QTE:%.+]] = sext i32 [[QT]] to i33
224   // CHECK: [[C2:%.+]] = icmp ne i33 [[Q]], [[QTE]]
225   // CHECK: [[C3:%.+]] = or i1 [[C1]], [[C2]]
226   // CHECK: store i32 [[QT]], i32*
227   // CHECK: br i1 [[C3]]
228   int r;
229   if (__builtin_add_overflow(x, y, &r))
230     overflowed();
231   return r;
232 }
233 
234 _Bool test_add_overflow_uint_uint_bool(unsigned x, unsigned y) {
235   // CHECK-LABEL: define {{.*}} i1 @test_add_overflow_uint_uint_bool
236   // CHECK-NOT: ext
237   // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
238   // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
239   // CHECK-DAG: [[C1:%.+]] = extractvalue { i32, i1 } [[S]], 1
240   // CHECK: [[QT:%.+]] = trunc i32 [[Q]] to i1
241   // CHECK: [[QTE:%.+]] = zext i1 [[QT]] to i32
242   // CHECK: [[C2:%.+]] = icmp ne i32 [[Q]], [[QTE]]
243   // CHECK: [[C3:%.+]] = or i1 [[C1]], [[C2]]
244   // CHECK: [[QT2:%.+]] = zext i1 [[QT]] to i8
245   // CHECK: store i8 [[QT2]], i8*
246   // CHECK: br i1 [[C3]]
247   _Bool r;
248   if (__builtin_add_overflow(x, y, &r))
249     overflowed();
250   return r;
251 }
252 
253 unsigned test_add_overflow_bool_bool_uint(_Bool x, _Bool y) {
254   // CHECK-LABEL: define {{(dso_local )?}}i32 @test_add_overflow_bool_bool_uint
255   // CHECK: [[XE:%.+]] = zext i1 %{{.+}} to i32
256   // CHECK: [[YE:%.+]] = zext i1 %{{.+}} to i32
257   // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[XE]], i32 [[YE]])
258   // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
259   // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
260   // CHECK: store i32 [[Q]], i32*
261   // CHECK: br i1 [[C]]
262   unsigned r;
263   if (__builtin_add_overflow(x, y, &r))
264     overflowed();
265   return r;
266 }
267 
268 _Bool test_add_overflow_bool_bool_bool(_Bool x, _Bool y) {
269   // CHECK-LABEL: define {{.*}} i1 @test_add_overflow_bool_bool_bool
270   // CHECK: [[S:%.+]] = call { i1, i1 } @llvm.uadd.with.overflow.i1(i1 %{{.+}}, i1 %{{.+}})
271   // CHECK-DAG: [[Q:%.+]] = extractvalue { i1, i1 } [[S]], 0
272   // CHECK-DAG: [[C:%.+]] = extractvalue { i1, i1 } [[S]], 1
273   // CHECK: [[QT2:%.+]] = zext i1 [[Q]] to i8
274   // CHECK: store i8 [[QT2]], i8*
275   // CHECK: br i1 [[C]]
276   _Bool r;
277   if (__builtin_add_overflow(x, y, &r))
278     overflowed();
279   return r;
280 }
281 
282 int test_add_overflow_volatile(int x, int y) {
283   // CHECK-LABEL: define {{(dso_local )?}}i32 @test_add_overflow_volatile
284   // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
285   // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
286   // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
287   // CHECK: store volatile i32 [[Q]], i32*
288   // CHECK: br i1 [[C]]
289   volatile int result;
290   if (__builtin_add_overflow(x, y, &result))
291     overflowed();
292   return result;
293 }
294 
295 unsigned test_uadd_overflow(unsigned x, unsigned y) {
296 // CHECK: @test_uadd_overflow
297 // CHECK: %{{.+}} = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
298   unsigned result;
299   if (__builtin_uadd_overflow(x, y, &result))
300     return UnsignedErrorCode;
301   return result;
302 }
303 
304 unsigned long test_uaddl_overflow(unsigned long x, unsigned long y) {
305 // CHECK: @test_uaddl_overflow([[UL:i32|i64]] %x
306 // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.uadd.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})
307   unsigned long result;
308   if (__builtin_uaddl_overflow(x, y, &result))
309     return UnsignedLongErrorCode;
310   return result;
311 }
312 
313 unsigned long long test_uaddll_overflow(unsigned long long x, unsigned long long y) {
314 // CHECK: @test_uaddll_overflow
315 // CHECK: %{{.+}} = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})
316   unsigned long long result;
317   if (__builtin_uaddll_overflow(x, y, &result))
318     return UnsignedLongLongErrorCode;
319   return result;
320 }
321 
322 unsigned test_usub_overflow(unsigned x, unsigned y) {
323 // CHECK: @test_usub_overflow
324 // CHECK: %{{.+}} = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
325   unsigned result;
326   if (__builtin_usub_overflow(x, y, &result))
327     return UnsignedErrorCode;
328   return result;
329 }
330 
331 unsigned long test_usubl_overflow(unsigned long x, unsigned long y) {
332 // CHECK: @test_usubl_overflow([[UL:i32|i64]] %x
333 // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.usub.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})
334   unsigned long result;
335   if (__builtin_usubl_overflow(x, y, &result))
336     return UnsignedLongErrorCode;
337   return result;
338 }
339 
340 unsigned long long test_usubll_overflow(unsigned long long x, unsigned long long y) {
341 // CHECK: @test_usubll_overflow
342 // CHECK: %{{.+}} = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})
343   unsigned long long result;
344   if (__builtin_usubll_overflow(x, y, &result))
345     return UnsignedLongLongErrorCode;
346   return result;
347 }
348 
349 unsigned test_umul_overflow(unsigned x, unsigned y) {
350 // CHECK: @test_umul_overflow
351 // CHECK: %{{.+}} = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
352   unsigned result;
353   if (__builtin_umul_overflow(x, y, &result))
354     return UnsignedErrorCode;
355   return result;
356 }
357 
358 unsigned long test_umull_overflow(unsigned long x, unsigned long y) {
359 // CHECK: @test_umull_overflow([[UL:i32|i64]] %x
360 // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.umul.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})
361   unsigned long result;
362   if (__builtin_umull_overflow(x, y, &result))
363     return UnsignedLongErrorCode;
364   return result;
365 }
366 
367 unsigned long long test_umulll_overflow(unsigned long long x, unsigned long long y) {
368 // CHECK: @test_umulll_overflow
369 // CHECK: %{{.+}} = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})
370   unsigned long long result;
371   if (__builtin_umulll_overflow(x, y, &result))
372     return UnsignedLongLongErrorCode;
373   return result;
374 }
375 
376 int test_sadd_overflow(int x, int y) {
377 // CHECK: @test_sadd_overflow
378 // CHECK: %{{.+}} = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
379   int result;
380   if (__builtin_sadd_overflow(x, y, &result))
381     return IntErrorCode;
382   return result;
383 }
384 
385 long test_saddl_overflow(long x, long y) {
386 // CHECK: @test_saddl_overflow([[UL:i32|i64]] %x
387 // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.sadd.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})
388   long result;
389   if (__builtin_saddl_overflow(x, y, &result))
390     return LongErrorCode;
391   return result;
392 }
393 
394 long long test_saddll_overflow(long long x, long long y) {
395 // CHECK: @test_saddll_overflow
396 // CHECK: %{{.+}} = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})
397   long long result;
398   if (__builtin_saddll_overflow(x, y, &result))
399     return LongLongErrorCode;
400   return result;
401 }
402 
403 int test_ssub_overflow(int x, int y) {
404 // CHECK: @test_ssub_overflow
405 // CHECK: %{{.+}} = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
406   int result;
407   if (__builtin_ssub_overflow(x, y, &result))
408     return IntErrorCode;
409   return result;
410 }
411 
412 long test_ssubl_overflow(long x, long y) {
413 // CHECK: @test_ssubl_overflow([[UL:i32|i64]] %x
414 // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.ssub.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})
415   long result;
416   if (__builtin_ssubl_overflow(x, y, &result))
417     return LongErrorCode;
418   return result;
419 }
420 
421 long long test_ssubll_overflow(long long x, long long y) {
422 // CHECK: @test_ssubll_overflow
423 // CHECK: %{{.+}} = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})
424   long long result;
425   if (__builtin_ssubll_overflow(x, y, &result))
426     return LongLongErrorCode;
427   return result;
428 }
429 
430 int test_smul_overflow(int x, int y) {
431 // CHECK: @test_smul_overflow
432 // CHECK: %{{.+}} = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
433   int result;
434   if (__builtin_smul_overflow(x, y, &result))
435     return IntErrorCode;
436   return result;
437 }
438 
439 long test_smull_overflow(long x, long y) {
440 // CHECK: @test_smull_overflow([[UL:i32|i64]] %x
441 // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.smul.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})
442   long result;
443   if (__builtin_smull_overflow(x, y, &result))
444     return LongErrorCode;
445   return result;
446 }
447 
448 long long test_smulll_overflow(long long x, long long y) {
449 // CHECK: @test_smulll_overflow
450 // CHECK: %{{.+}} = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})
451   long long result;
452   if (__builtin_smulll_overflow(x, y, &result))
453     return LongLongErrorCode;
454   return result;
455 }
456 
457 int test_mixed_sign_mul_overflow_sext_signed_op(int x, unsigned long long y) {
458 // CHECK: @test_mixed_sign_mul_overflow_sext_signed_op
459 // CHECK: [[SignedOp:%.*]] = sext i32 %0 to i64
460 // CHECK: [[IsNeg:%.*]] = icmp slt i64 [[SignedOp]], 0
461   int result;
462   if (__builtin_mul_overflow(x, y, &result))
463     return LongErrorCode;
464   return result;
465 }
466 
467 int test_mixed_sign_mul_overflow_zext_unsigned_op(long long x, unsigned y) {
468 // CHECK: @test_mixed_sign_mul_overflow_zext_unsigned_op
469 // CHECK: [[UnsignedOp:%.*]] = zext i32 %1 to i64
470 // CHECK: [[IsNeg:%.*]] = icmp slt i64 %0, 0
471 // CHECK: @llvm.umul.with.overflow.i64({{.*}}, i64 [[UnsignedOp]])
472   int result;
473   if (__builtin_mul_overflow(x, y, &result))
474     return LongErrorCode;
475   return result;
476 }
477 
478 int test_mixed_sign_mull_overflow(int x, unsigned y) {
479 // CHECK: @test_mixed_sign_mull_overflow
480 // CHECK:       [[IsNeg:%.*]] = icmp slt i32 [[Op1:%.*]], 0
481 // CHECK-NEXT:  [[Signed:%.*]] = sub i32 0, [[Op1]]
482 // CHECK-NEXT:  [[AbsSigned:%.*]] = select i1 [[IsNeg]], i32 [[Signed]], i32 [[Op1]]
483 // CHECK-NEXT:  call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[AbsSigned]], i32 %{{.*}})
484 // CHECK-NEXT:  [[UnsignedOFlow:%.*]] = extractvalue { i32, i1 } %{{.*}}, 1
485 // CHECK-NEXT:  [[UnsignedResult:%.*]] = extractvalue { i32, i1 } %{{.*}}, 0
486 // CHECK-NEXT:  [[IsNegZext:%.*]] = zext i1 [[IsNeg]] to i32
487 // CHECK-NEXT:  [[MaxResult:%.*]] = add i32 2147483647, [[IsNegZext]]
488 // CHECK-NEXT:  [[SignedOFlow:%.*]] = icmp ugt i32 [[UnsignedResult]], [[MaxResult]]
489 // CHECK-NEXT:  [[OFlow:%.*]] = or i1 [[UnsignedOFlow]], [[SignedOFlow]]
490 // CHECK-NEXT:  [[NegativeResult:%.*]] = sub i32 0, [[UnsignedResult]]
491 // CHECK-NEXT:  [[Result:%.*]] = select i1 [[IsNeg]], i32 [[NegativeResult]], i32 [[UnsignedResult]]
492 // CHECK-NEXT:  store i32 [[Result]], i32* %{{.*}}, align 4
493 // CHECK:       br i1 [[OFlow]]
494 
495   int result;
496   if (__builtin_mul_overflow(x, y, &result))
497     return LongErrorCode;
498   return result;
499 }
500 
501 int test_mixed_sign_mull_overflow_unsigned(int x, unsigned y) {
502 // CHECK: @test_mixed_sign_mull_overflow_unsigned
503 // CHECK:       [[IsNeg:%.*]] = icmp slt i32 [[Op1:%.*]], 0
504 // CHECK-NEXT:  [[Signed:%.*]] = sub i32 0, [[Op1]]
505 // CHECK-NEXT:  [[AbsSigned:%.*]] = select i1 [[IsNeg]], i32 [[Signed]], i32 [[Op1]]
506 // CHECK-NEXT:  call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[AbsSigned]], i32 %{{.*}})
507 // CHECK-NEXT:  [[UnsignedOFlow:%.*]] = extractvalue { i32, i1 } %{{.*}}, 1
508 // CHECK-NEXT:  [[UnsignedResult:%.*]] = extractvalue { i32, i1 } %{{.*}}, 0
509 // CHECK-NEXT:  [[NotNull:%.*]] = icmp ne i32 [[UnsignedResult]], 0
510 // CHECK-NEXT:  [[Underflow:%.*]] = and i1 [[IsNeg]], [[NotNull]]
511 // CHECK-NEXT:  [[OFlow:%.*]] = or i1 [[UnsignedOFlow]], [[Underflow]]
512 // CHECK-NEXT:  [[NegatedResult:%.*]] = sub i32 0, [[UnsignedResult]]
513 // CHECK-NEXT:  [[Result:%.*]] = select i1 [[IsNeg]], i32 [[NegatedResult]], i32 [[UnsignedResult]]
514 // CHECK-NEXT:  store i32 [[Result]], i32* %{{.*}}, align 4
515 // CHECK:       br i1 [[OFlow]]
516 
517   unsigned result;
518   if (__builtin_mul_overflow(x, y, &result))
519     return LongErrorCode;
520   return result;
521 }
522 
523 int test_mixed_sign_mull_overflow_swapped(int x, unsigned y) {
524 // CHECK: @test_mixed_sign_mull_overflow_swapped
525 // CHECK:  call { i32, i1 } @llvm.umul.with.overflow.i32
526 // CHECK:  add i32 2147483647
527   int result;
528   if (__builtin_mul_overflow(y, x, &result))
529     return LongErrorCode;
530   return result;
531 }
532 
533 long long test_mixed_sign_mulll_overflow(long long x, unsigned long long y) {
534 // CHECK: @test_mixed_sign_mulll_overflow
535 // CHECK:  call { i64, i1 } @llvm.umul.with.overflow.i64
536 // CHECK:  add i64 92233720368547
537   long long result;
538   if (__builtin_mul_overflow(x, y, &result))
539     return LongLongErrorCode;
540   return result;
541 }
542 
543 long long test_mixed_sign_mulll_overflow_swapped(long long x, unsigned long long y) {
544 // CHECK: @test_mixed_sign_mulll_overflow_swapped
545 // CHECK:  call { i64, i1 } @llvm.umul.with.overflow.i64
546 // CHECK:  add i64 92233720368547
547   long long result;
548   if (__builtin_mul_overflow(y, x, &result))
549     return LongLongErrorCode;
550   return result;
551 }
552 
553 long long test_mixed_sign_mulll_overflow_trunc_signed(long long x, unsigned long long y) {
554 // CHECK: @test_mixed_sign_mulll_overflow_trunc_signed
555 // CHECK:  call { i64, i1 } @llvm.umul.with.overflow.i64
556 // CHECK:  add i64 2147483647
557 // CHECK:  trunc
558 // CHECK:  store
559   int result;
560   if (__builtin_mul_overflow(y, x, &result))
561     return LongLongErrorCode;
562   return result;
563 }
564 
565 long long test_mixed_sign_mulll_overflow_trunc_unsigned(long long x, unsigned long long y) {
566 // CHECK: @test_mixed_sign_mulll_overflow_trunc_unsigned
567 // CHECK:       call { i64, i1 } @llvm.umul.with.overflow.i64
568 // CHECK:       [[NON_ZERO:%.*]] = icmp ne i64 [[UNSIGNED_RESULT:%.*]], 0
569 // CHECK-NEXT:  [[UNDERFLOW:%.*]] = and i1 {{.*}}, [[NON_ZERO]]
570 // CHECK-NEXT:  [[OVERFLOW_PRE_TRUNC:%.*]] = or i1 {{.*}}, [[UNDERFLOW]]
571 // CHECK-NEXT:  [[TRUNC_OVERFLOW:%.*]] = icmp ugt i64 [[UNSIGNED_RESULT]], 4294967295
572 // CHECK-NEXT:  [[OVERFLOW:%.*]] = or i1 [[OVERFLOW_PRE_TRUNC]], [[TRUNC_OVERFLOW]]
573 // CHECK-NEXT:  [[NEGATED:%.*]] = sub i64 0, [[UNSIGNED_RESULT]]
574 // CHECK-NEXT:  [[RESULT:%.*]] = select i1 {{.*}}, i64 [[NEGATED]], i64 [[UNSIGNED_RESULT]]
575 // CHECK-NEXT:  trunc i64 [[RESULT]] to i32
576 // CHECK-NEXT:  store
577   unsigned result;
578   if (__builtin_mul_overflow(y, x, &result))
579     return LongLongErrorCode;
580   return result;
581 }
582 
583 long long test_mixed_sign_mul_overflow_extend_signed(int x, unsigned y) {
584 // CHECK: @test_mixed_sign_mul_overflow_extend_signed
585 // CHECK:  call { i64, i1 } @llvm.smul.with.overflow.i64
586   long long result;
587   if (__builtin_mul_overflow(y, x, &result))
588     return LongLongErrorCode;
589   return result;
590 }
591 
592 long long test_mixed_sign_mul_overflow_extend_unsigned(int x, unsigned y) {
593 // CHECK: @test_mixed_sign_mul_overflow_extend_unsigned
594 // CHECK:  call { i65, i1 } @llvm.smul.with.overflow.i65
595   unsigned long long result;
596   if (__builtin_mul_overflow(y, x, &result))
597     return LongLongErrorCode;
598   return result;
599 }
600