xref: /llvm-project/clang/test/CodeGenCXX/new-overflow.cpp (revision 0f1c1be1968076d6f96f8a7bcc4a15cf195ecd97)
1 // RUN: %clang_cc1 -std=c++14 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
2 
3 // Basic test.
4 namespace test0 {
5   struct A {
6     A();
7     int x;
8   };
9 
10   typedef A elt;
11 
12   // CHECK:    define{{.*}} ptr @_ZN5test04testEs(i16 noundef signext
13   // CHECK:      [[N:%.*]] = sext i16 {{%.*}} to i32
14   // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
15   // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
16   // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
17   // CHECK-NEXT: [[T3:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
18   // CHECK-NEXT: call noalias noundef nonnull ptr @_Znaj(i32 noundef [[T3]])
19   // CHECK:      getelementptr inbounds {{.*}}, i32 [[N]]
test(short s)20   elt *test(short s) {
21     return new elt[s];
22   }
23 }
24 
25 // test0 with a nested array.
26 namespace test1 {
27   struct A {
28     A();
29     int x;
30   };
31 
32   typedef A elt[100];
33 
34   // CHECK:    define{{.*}} ptr @_ZN5test14testEs(i16 noundef signext
35   // CHECK:      [[N:%.*]] = sext i16 {{%.*}} to i32
36   // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 400)
37   // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
38   // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
39   // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
40   // CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
41   // CHECK-NEXT: call noalias noundef nonnull ptr @_Znaj(i32 noundef [[T4]])
42   // CHECK:      getelementptr inbounds {{.*}}, i32 [[T3]]
test(short s)43   elt *test(short s) {
44     return new elt[s];
45   }
46 }
47 
48 // test1 with an array cookie.
49 namespace test2 {
50   struct A {
51     A();
52     ~A();
53     int x;
54   };
55 
56   typedef A elt[100];
57 
58   // CHECK:    define{{.*}} ptr @_ZN5test24testEs(i16 noundef signext
59   // CHECK:      [[N:%.*]] = sext i16 {{%.*}} to i32
60   // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 400)
61   // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
62   // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
63   // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
64   // CHECK-NEXT: [[T4:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T2]], i32 4)
65   // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T4]], 1
66   // CHECK-NEXT: [[T6:%.*]] = or i1 [[T1]], [[T5]]
67   // CHECK-NEXT: [[T7:%.*]] = extractvalue { i32, i1 } [[T4]], 0
68   // CHECK-NEXT: [[T8:%.*]] = select i1 [[T6]], i32 -1, i32 [[T7]]
69   // CHECK-NEXT: call noalias noundef nonnull ptr @_Znaj(i32 noundef [[T8]])
70   // CHECK:      getelementptr inbounds {{.*}}, i32 [[T3]]
test(short s)71   elt *test(short s) {
72     return new elt[s];
73   }
74 }
75 
76 // test0 with a 1-byte element.
77 namespace test4 {
78   struct A {
79     A();
80   };
81 
82   typedef A elt;
83 
84   // CHECK:    define{{.*}} ptr @_ZN5test44testEs(i16 noundef signext
85   // CHECK:      [[N:%.*]] = sext i16 {{%.*}} to i32
86   // CHECK-NEXT: call noalias noundef nonnull ptr @_Znaj(i32 noundef [[N]])
87   // CHECK:      getelementptr inbounds {{.*}}, i32 [[N]]
test(short s)88   elt *test(short s) {
89     return new elt[s];
90   }
91 }
92 
93 // test4 with no sext required.
94 namespace test5 {
95   struct A {
96     A();
97   };
98 
99   typedef A elt;
100 
101   // CHECK:    define{{.*}} ptr @_ZN5test54testEi(i32
102   // CHECK:      [[N:%.*]] = load i32, ptr
103   // CHECK-NEXT: call noalias noundef nonnull ptr @_Znaj(i32 noundef [[N]])
104   // CHECK:      getelementptr inbounds {{.*}}, i32 [[N]]
test(int s)105   elt *test(int s) {
106     return new elt[s];
107   }
108 }
109 
110 // test0 with an unsigned size.
111 namespace test6 {
112   struct A {
113     A();
114     int x;
115   };
116 
117   typedef A elt;
118 
119   // CHECK:    define{{.*}} ptr @_ZN5test64testEt(i16 noundef zeroext
120   // CHECK:      [[N:%.*]] = zext i16 {{%.*}} to i32
121   // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
122   // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
123   // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
124   // CHECK-NEXT: [[T3:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
125   // CHECK-NEXT: call noalias noundef nonnull ptr @_Znaj(i32 noundef [[T3]])
126   // CHECK:      getelementptr inbounds {{.*}}, i32 [[N]]
test(unsigned short s)127   elt *test(unsigned short s) {
128     return new elt[s];
129   }
130 }
131 
132 // test1 with an unsigned size.
133 namespace test7 {
134   struct A {
135     A();
136     int x;
137   };
138 
139   typedef A elt[100];
140 
141   // CHECK:    define{{.*}} ptr @_ZN5test74testEt(i16 noundef zeroext
142   // CHECK:      [[N:%.*]] = zext i16 {{%.*}} to i32
143   // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 400)
144   // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
145   // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
146   // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
147   // CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
148   // CHECK-NEXT: call noalias noundef nonnull ptr @_Znaj(i32 noundef [[T4]])
149   // CHECK:      getelementptr inbounds {{.*}}, i32 [[T3]]
test(unsigned short s)150   elt *test(unsigned short s) {
151     return new elt[s];
152   }
153 }
154 
155 // test0 with a signed type larger than size_t.
156 namespace test8 {
157   struct A {
158     A();
159     int x;
160   };
161 
162   typedef A elt;
163 
164   // CHECK:    define{{.*}} ptr @_ZN5test84testEx(i64
165   // CHECK:      [[N:%.*]] = load i64, ptr
166   // CHECK-NEXT: [[T1:%.*]] = trunc i64 [[N]] to i32
167   // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 4)
168   // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 1
169   // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0
170   // CHECK-NEXT: [[T6:%.*]] = select i1 [[T3]], i32 -1, i32 [[T5]]
171   // CHECK-NEXT: call noalias noundef nonnull ptr @_Znaj(i32 noundef [[T6]])
172   // CHECK:      getelementptr inbounds {{.*}}, i32 [[T1]]
test(long long s)173   elt *test(long long s) {
174     return new elt[s];
175   }
176 }
177 
178 // test8 with an unsigned type.
179 namespace test9 {
180   struct A {
181     A();
182     int x;
183   };
184 
185   typedef A elt;
186 
187   // CHECK:    define{{.*}} ptr @_ZN5test94testEy(i64
188   // CHECK:      [[N:%.*]] = load i64, ptr
189   // CHECK-NEXT: [[T1:%.*]] = trunc i64 [[N]] to i32
190   // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 4)
191   // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 1
192   // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0
193   // CHECK-NEXT: [[T6:%.*]] = select i1 [[T3]], i32 -1, i32 [[T5]]
194   // CHECK-NEXT: call noalias noundef nonnull ptr @_Znaj(i32 noundef [[T6]])
195   // CHECK:      getelementptr inbounds {{.*}}, i32 [[T1]]
test(unsigned long long s)196   elt *test(unsigned long long s) {
197     return new elt[s];
198   }
199 }
200