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