xref: /llvm-project/clang/test/CodeGen/integer-overflow.c (revision 0f1c1be1968076d6f96f8a7bcc4a15cf195ecd97)
1 // RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck %s --check-prefix=DEFAULT
2 // RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fwrapv | FileCheck %s --check-prefix=WRAPV
3 // RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -ftrapv | FileCheck %s --check-prefix=TRAPV
4 // RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fsanitize=signed-integer-overflow | FileCheck %s --check-prefix=CATCH_UB
5 // RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -ftrapv -ftrapv-handler foo | FileCheck %s --check-prefix=TRAPV_HANDLER
6 
7 
8 // Tests for signed integer overflow stuff.
9 void test1(void) {
10   // DEFAULT-LABEL: define{{.*}} void @test1
11   // WRAPV-LABEL: define{{.*}} void @test1
12   // TRAPV-LABEL: define{{.*}} void @test1
13   extern volatile int f11G, a, b;
14 
15   // DEFAULT: add nsw i32
16   // WRAPV: add i32
17   // TRAPV: llvm.sadd.with.overflow.i32
18   // CATCH_UB: llvm.sadd.with.overflow.i32
19   // TRAPV_HANDLER: foo(
20   f11G = a + b;
21 
22   // DEFAULT: sub nsw i32
23   // WRAPV: sub i32
24   // TRAPV: llvm.ssub.with.overflow.i32
25   // CATCH_UB: llvm.ssub.with.overflow.i32
26   // TRAPV_HANDLER: foo(
27   f11G = a - b;
28 
29   // DEFAULT: mul nsw i32
30   // WRAPV: mul i32
31   // TRAPV: llvm.smul.with.overflow.i32
32   // CATCH_UB: llvm.smul.with.overflow.i32
33   // TRAPV_HANDLER: foo(
34   f11G = a * b;
35 
36   // DEFAULT: sub nsw i32 0,
37   // WRAPV: sub i32 0,
38   // TRAPV: llvm.ssub.with.overflow.i32(i32 0
39   // CATCH_UB: llvm.ssub.with.overflow.i32(i32 0
40   // TRAPV_HANDLER: foo(
41   f11G = -a;
42 
43   // PR7426 - Overflow checking for increments.
44 
45   // DEFAULT: add nsw i32 {{.*}}, 1
46   // WRAPV: add i32 {{.*}}, 1
47   // TRAPV: llvm.sadd.with.overflow.i32({{.*}}, i32 1)
48   // CATCH_UB: llvm.sadd.with.overflow.i32({{.*}}, i32 1)
49   // TRAPV_HANDLER: foo(
50   ++a;
51 
52   // DEFAULT: add nsw i32 {{.*}}, -1
53   // WRAPV: add i32 {{.*}}, -1
54   // TRAPV: llvm.ssub.with.overflow.i32({{.*}}, i32 1)
55   // CATCH_UB: llvm.ssub.with.overflow.i32({{.*}}, i32 1)
56   // TRAPV_HANDLER: foo(
57   --a;
58 
59   // -fwrapv should turn off inbounds for GEP's, PR9256
60   extern int* P;
61   ++P;
62   // DEFAULT: getelementptr inbounds i32, ptr
63   // WRAPV: getelementptr i32, ptr
64   // TRAPV: getelementptr inbounds i32, ptr
65   // CATCH_UB: getelementptr inbounds i32, ptr
66 
67   // PR9350: char pre-increment never overflows.
68   extern volatile signed char PR9350_char_inc;
69   // DEFAULT: add i8 {{.*}}, 1
70   // WRAPV: add i8 {{.*}}, 1
71   // TRAPV: add i8 {{.*}}, 1
72   // CATCH_UB: add i8 {{.*}}, 1
73   ++PR9350_char_inc;
74 
75   // PR9350: char pre-decrement never overflows.
76   extern volatile signed char PR9350_char_dec;
77   // DEFAULT: add i8 {{.*}}, -1
78   // WRAPV: add i8 {{.*}}, -1
79   // TRAPV: add i8 {{.*}}, -1
80   // CATCH_UB: add i8 {{.*}}, -1
81   --PR9350_char_dec;
82 
83   // PR9350: short pre-increment never overflows.
84   extern volatile signed short PR9350_short_inc;
85   // DEFAULT: add i16 {{.*}}, 1
86   // WRAPV: add i16 {{.*}}, 1
87   // TRAPV: add i16 {{.*}}, 1
88   // CATCH_UB: add i16 {{.*}}, 1
89   ++PR9350_short_inc;
90 
91   // PR9350: short pre-decrement never overflows.
92   extern volatile signed short PR9350_short_dec;
93   // DEFAULT: add i16 {{.*}}, -1
94   // WRAPV: add i16 {{.*}}, -1
95   // TRAPV: add i16 {{.*}}, -1
96   // CATCH_UB: add i16 {{.*}}, -1
97   --PR9350_short_dec;
98 
99   // PR24256: don't instrument __builtin_frame_address.
100   __builtin_frame_address(0 + 0);
101   // DEFAULT:  call ptr @llvm.frameaddress.p0(i32 0)
102   // WRAPV:    call ptr @llvm.frameaddress.p0(i32 0)
103   // TRAPV:    call ptr @llvm.frameaddress.p0(i32 0)
104   // CATCH_UB: call ptr @llvm.frameaddress.p0(i32 0)
105 }
106