blob: 71ff1ed7d689468f8c085e19e635ddeb6c9f9053 [file] [log] [blame]
John McCall83ce9d42010-11-16 23:07:28 +00001// RUN: %clang_cc1 -Wno-unused-value -emit-llvm %s -o - | FileCheck %s
2
3// CHECK: @i = global [[INT:i[0-9]+]] 0
4volatile int i, j, k;
5volatile int ar[5];
6volatile char c;
Chris Lattner9cbe4f02011-07-09 17:41:47 +00007// CHECK: @ci = global [[CINT:.*]] zeroinitializer
John McCall83ce9d42010-11-16 23:07:28 +00008volatile _Complex int ci;
9volatile struct S {
10#ifdef __cplusplus
11 void operator =(volatile struct S&o) volatile;
12#endif
13 int i;
14} a, b;
15
16//void operator =(volatile struct S&o1, volatile struct S&o2) volatile;
17int printf(const char *, ...);
18
19
20// CHECK: define void @{{.*}}test
21void test() {
22
23 asm("nop"); // CHECK: call void asm
24
John McCall2a416372010-12-05 02:00:02 +000025 // should not load
John McCall83ce9d42010-11-16 23:07:28 +000026 i;
John McCall83ce9d42010-11-16 23:07:28 +000027
28 (float)(ci);
Eli Friedmana40b7f22011-08-12 23:33:52 +000029 // CHECK-NEXT: load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
30 // CHECK-NEXT: load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
John McCall83ce9d42010-11-16 23:07:28 +000031 // CHECK-NEXT: sitofp [[INT]]
32
33 // These are not uses in C++:
34 // [expr.static.cast]p6:
35 // The lvalue-to-rvalue . . . conversions are not applied to the expression.
36 (void)ci;
37 (void)a;
38
39 (void)(ci=ci);
Eli Friedmana40b7f22011-08-12 23:33:52 +000040 // CHECK-NEXT: [[R:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
41 // CHECK-NEXT: [[I:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
42 // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
43 // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
John McCall83ce9d42010-11-16 23:07:28 +000044
45 (void)(i=j);
Eli Friedmana40b7f22011-08-12 23:33:52 +000046 // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]]* @j
47 // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* @i
John McCall83ce9d42010-11-16 23:07:28 +000048
John McCall83ce9d42010-11-16 23:07:28 +000049 ci+=ci;
Eli Friedmana40b7f22011-08-12 23:33:52 +000050 // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
51 // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
52 // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
53 // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
John McCall83ce9d42010-11-16 23:07:28 +000054 // Not sure why they're ordered this way.
55 // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]]
56 // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]]
Eli Friedmana40b7f22011-08-12 23:33:52 +000057 // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
58 // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
John McCall83ce9d42010-11-16 23:07:28 +000059
Eli Friedmana40b7f22011-08-12 23:33:52 +000060 // Note that C++ requires an extra load volatile over C from the LHS of the '+'.
John McCall83ce9d42010-11-16 23:07:28 +000061 (ci += ci) + ci;
Eli Friedmana40b7f22011-08-12 23:33:52 +000062 // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
63 // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
64 // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
65 // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
John McCall83ce9d42010-11-16 23:07:28 +000066 // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]]
67 // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]]
Eli Friedmana40b7f22011-08-12 23:33:52 +000068 // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
69 // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
70 // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
71 // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
72 // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
73 // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
John McCall83ce9d42010-11-16 23:07:28 +000074 // These additions can be elided.
75 // CHECK-NEXT: add [[INT]] [[R1]], [[R2]]
76 // CHECK-NEXT: add [[INT]] [[I1]], [[I2]]
77
78 asm("nop"); // CHECK-NEXT: call void asm
79
Eli Friedmana40b7f22011-08-12 23:33:52 +000080 // Extra load volatile in C++.
John McCall83ce9d42010-11-16 23:07:28 +000081 (i += j) + k;
Eli Friedmana40b7f22011-08-12 23:33:52 +000082 // CHECK-NEXT: load volatile
83 // CHECK-NEXT: load volatile
John McCall83ce9d42010-11-16 23:07:28 +000084 // CHECK-NEXT: add nsw [[INT]]
Eli Friedmana40b7f22011-08-12 23:33:52 +000085 // CHECK-NEXT: store volatile
86 // CHECK-NEXT: load volatile
87 // CHECK-NEXT: load volatile
John McCall83ce9d42010-11-16 23:07:28 +000088 // CHECK-NEXT: add nsw [[INT]]
89
90 asm("nop"); // CHECK-NEXT: call void asm
91
Eli Friedmana40b7f22011-08-12 23:33:52 +000092 // Extra load volatile in C++.
John McCall83ce9d42010-11-16 23:07:28 +000093 (i += j) + 1;
Eli Friedmana40b7f22011-08-12 23:33:52 +000094 // CHECK-NEXT: load volatile
95 // CHECK-NEXT: load volatile
John McCall83ce9d42010-11-16 23:07:28 +000096 // CHECK-NEXT: add nsw [[INT]]
Eli Friedmana40b7f22011-08-12 23:33:52 +000097 // CHECK-NEXT: store volatile
98 // CHECK-NEXT: load volatile
John McCall83ce9d42010-11-16 23:07:28 +000099 // CHECK-NEXT: add nsw [[INT]]
100
101 asm("nop"); // CHECK-NEXT: call void asm
102
103 ci+ci;
Eli Friedmana40b7f22011-08-12 23:33:52 +0000104 // CHECK-NEXT: load volatile
105 // CHECK-NEXT: load volatile
106 // CHECK-NEXT: load volatile
107 // CHECK-NEXT: load volatile
John McCall83ce9d42010-11-16 23:07:28 +0000108 // CHECK-NEXT: add [[INT]]
109 // CHECK-NEXT: add [[INT]]
110
John McCall83ce9d42010-11-16 23:07:28 +0000111 __real i;
John McCall83ce9d42010-11-16 23:07:28 +0000112
113 +ci;
Eli Friedmana40b7f22011-08-12 23:33:52 +0000114 // CHECK-NEXT: load volatile
115 // CHECK-NEXT: load volatile
John McCall83ce9d42010-11-16 23:07:28 +0000116
117 asm("nop"); // CHECK-NEXT: call void asm
118
119 (void)(i=i);
Eli Friedmana40b7f22011-08-12 23:33:52 +0000120 // CHECK-NEXT: load volatile
121 // CHECK-NEXT: store volatile
John McCall83ce9d42010-11-16 23:07:28 +0000122
123 (float)(i=i);
Eli Friedmana40b7f22011-08-12 23:33:52 +0000124 // CHECK-NEXT: load volatile
125 // CHECK-NEXT: store volatile
126 // CHECK-NEXT: load volatile
John McCall83ce9d42010-11-16 23:07:28 +0000127 // CHECK-NEXT: sitofp
128
129 (void)i;
130
131 i=i;
Eli Friedmana40b7f22011-08-12 23:33:52 +0000132 // CHECK-NEXT: load volatile
133 // CHECK-NEXT: store volatile
John McCall83ce9d42010-11-16 23:07:28 +0000134
Eli Friedmana40b7f22011-08-12 23:33:52 +0000135 // Extra load volatile in C++.
John McCall83ce9d42010-11-16 23:07:28 +0000136 i=i=i;
Eli Friedmana40b7f22011-08-12 23:33:52 +0000137 // CHECK-NEXT: load volatile
138 // CHECK-NEXT: store volatile
139 // CHECK-NEXT: load volatile
140 // CHECK-NEXT: store volatile
John McCall83ce9d42010-11-16 23:07:28 +0000141
142 (void)__builtin_choose_expr(0, i=i, j=j);
Eli Friedmana40b7f22011-08-12 23:33:52 +0000143 // CHECK-NEXT: load volatile
144 // CHECK-NEXT: store volatile
John McCall83ce9d42010-11-16 23:07:28 +0000145
John McCall83ce9d42010-11-16 23:07:28 +0000146 k ? (i=i) : (j=j);
Eli Friedmana40b7f22011-08-12 23:33:52 +0000147 // CHECK-NEXT: load volatile
John McCall83ce9d42010-11-16 23:07:28 +0000148 // CHECK-NEXT: icmp
149 // CHECK-NEXT: br i1
Eli Friedmana40b7f22011-08-12 23:33:52 +0000150 // CHECK: load volatile
151 // CHECK-NEXT: store volatile
John McCall83ce9d42010-11-16 23:07:28 +0000152 // CHECK-NEXT: br label
Eli Friedmana40b7f22011-08-12 23:33:52 +0000153 // CHECK: load volatile
154 // CHECK-NEXT: store volatile
John McCall83ce9d42010-11-16 23:07:28 +0000155 // CHECK-NEXT: br label
John McCall150b4622011-01-26 04:00:11 +0000156 // CHECK: phi
John McCall83ce9d42010-11-16 23:07:28 +0000157
158 (void)(i,(i=i));
Eli Friedmana40b7f22011-08-12 23:33:52 +0000159 // CHECK-NEXT: load volatile
160 // CHECK-NEXT: store volatile
John McCall83ce9d42010-11-16 23:07:28 +0000161
John McCall83ce9d42010-11-16 23:07:28 +0000162 i=i,k;
Eli Friedmana40b7f22011-08-12 23:33:52 +0000163 // CHECK-NEXT: load volatile [[INT]]* @i
164 // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i
John McCall83ce9d42010-11-16 23:07:28 +0000165
166 (i=j,k=j);
Eli Friedmana40b7f22011-08-12 23:33:52 +0000167 // CHECK-NEXT: load volatile [[INT]]* @j
168 // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i
169 // CHECK-NEXT: load volatile [[INT]]* @j
170 // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @k
John McCall83ce9d42010-11-16 23:07:28 +0000171
John McCall83ce9d42010-11-16 23:07:28 +0000172 (i=j,k);
Eli Friedmana40b7f22011-08-12 23:33:52 +0000173 // CHECK-NEXT: load volatile [[INT]]* @j
174 // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i
John McCall83ce9d42010-11-16 23:07:28 +0000175
John McCall83ce9d42010-11-16 23:07:28 +0000176 (i,j);
John McCall83ce9d42010-11-16 23:07:28 +0000177
178 // Extra load in C++.
179 i=c=k;
Eli Friedmana40b7f22011-08-12 23:33:52 +0000180 // CHECK-NEXT: load volatile
John McCall83ce9d42010-11-16 23:07:28 +0000181 // CHECK-NEXT: trunc
Eli Friedmana40b7f22011-08-12 23:33:52 +0000182 // CHECK-NEXT: store volatile
183 // CHECK-NEXT: load volatile
John McCall83ce9d42010-11-16 23:07:28 +0000184 // CHECK-NEXT: sext
Eli Friedmana40b7f22011-08-12 23:33:52 +0000185 // CHECK-NEXT: store volatile
John McCall83ce9d42010-11-16 23:07:28 +0000186
187 i+=k;
Eli Friedmana40b7f22011-08-12 23:33:52 +0000188 // CHECK-NEXT: load volatile
189 // CHECK-NEXT: load volatile
John McCall83ce9d42010-11-16 23:07:28 +0000190 // CHECK-NEXT: add nsw [[INT]]
Eli Friedmana40b7f22011-08-12 23:33:52 +0000191 // CHECK-NEXT: store volatile
John McCall83ce9d42010-11-16 23:07:28 +0000192
John McCall83ce9d42010-11-16 23:07:28 +0000193 ci;
John McCall83ce9d42010-11-16 23:07:28 +0000194
195 asm("nop"); // CHECK-NEXT: call void asm
196
197 (int)ci;
Eli Friedmana40b7f22011-08-12 23:33:52 +0000198 // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 0
199 // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 1
John McCall83ce9d42010-11-16 23:07:28 +0000200
201 (bool)ci;
Eli Friedmana40b7f22011-08-12 23:33:52 +0000202 // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 0
203 // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 1
John McCall83ce9d42010-11-16 23:07:28 +0000204 // CHECK-NEXT: icmp ne
205 // CHECK-NEXT: icmp ne
206 // CHECK-NEXT: or i1
207
John McCall83ce9d42010-11-16 23:07:28 +0000208 ci=ci;
Eli Friedmana40b7f22011-08-12 23:33:52 +0000209 // CHECK-NEXT: load volatile
210 // CHECK-NEXT: load volatile
211 // CHECK-NEXT: store volatile
212 // CHECK-NEXT: store volatile
John McCall83ce9d42010-11-16 23:07:28 +0000213
214 asm("nop"); // CHECK-NEXT: call void asm
215
John McCall83ce9d42010-11-16 23:07:28 +0000216 // Extra load in C++.
217 ci=ci=ci;
Eli Friedmana40b7f22011-08-12 23:33:52 +0000218 // CHECK-NEXT: load volatile
219 // CHECK-NEXT: load volatile
220 // CHECK-NEXT: store volatile
221 // CHECK-NEXT: store volatile
222 // CHECK-NEXT: load volatile
223 // CHECK-NEXT: load volatile
224 // CHECK-NEXT: store volatile
225 // CHECK-NEXT: store volatile
John McCall83ce9d42010-11-16 23:07:28 +0000226
227 __imag ci = __imag ci = __imag ci;
Eli Friedmana40b7f22011-08-12 23:33:52 +0000228 // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
229 // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
230 // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
231 // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
John McCall83ce9d42010-11-16 23:07:28 +0000232
233 __real (i = j);
Eli Friedmana40b7f22011-08-12 23:33:52 +0000234 // CHECK-NEXT: load volatile
235 // CHECK-NEXT: store volatile
John McCall83ce9d42010-11-16 23:07:28 +0000236
237 __imag i;
John McCall83ce9d42010-11-16 23:07:28 +0000238
239 // ============================================================
240 // FIXME: Test cases we get wrong.
241
242 // A use. We load all of a into a copy of a, then load i. gcc forgets to do
243 // the assignment.
244 // (a = a).i;
245
246 // ============================================================
247 // Test cases where we intentionally differ from gcc, due to suspected bugs in
248 // gcc.
249
250 // Not a use. gcc forgets to do the assignment.
251 // CHECK-NEXT: call
252 ((a=a),a);
253
254 // Not a use. gcc gets this wrong, it doesn't emit the copy!
255 // CHECK-NEXT: call
256 (void)(a=a);
257
258 // Not a use. gcc got this wrong in 4.2 and omitted the side effects
259 // entirely, but it is fixed in 4.4.0.
260 __imag (i = j);
Eli Friedmana40b7f22011-08-12 23:33:52 +0000261 // CHECK-NEXT: load volatile
262 // CHECK-NEXT: store volatile
John McCall83ce9d42010-11-16 23:07:28 +0000263
264 // C++ does an extra load here. Note that we have to do full loads.
265 (float)(ci=ci);
Eli Friedmana40b7f22011-08-12 23:33:52 +0000266 // CHECK-NEXT: load volatile
267 // CHECK-NEXT: load volatile
268 // CHECK-NEXT: store volatile
269 // CHECK-NEXT: store volatile
270 // CHECK-NEXT: load volatile
271 // CHECK-NEXT: load volatile
John McCall83ce9d42010-11-16 23:07:28 +0000272 // CHECK-NEXT: sitofp
273
274 // Not a use, bug? gcc treats this as not a use, that's probably a
275 // bug due to tree folding ignoring volatile.
276 (int)(ci=ci);
Eli Friedmana40b7f22011-08-12 23:33:52 +0000277 // CHECK-NEXT: load volatile
278 // CHECK-NEXT: load volatile
279 // CHECK-NEXT: store volatile
280 // CHECK-NEXT: store volatile
281 // CHECK-NEXT: load volatile
282 // CHECK-NEXT: load volatile
John McCall83ce9d42010-11-16 23:07:28 +0000283
284 // A use.
285 (float)(i=i);
Eli Friedmana40b7f22011-08-12 23:33:52 +0000286 // CHECK-NEXT: load volatile
287 // CHECK-NEXT: store volatile
288 // CHECK-NEXT: load volatile
John McCall83ce9d42010-11-16 23:07:28 +0000289 // CHECK-NEXT: sitofp
290
291 // A use. gcc treats this as not a use, that's probably a bug due to tree
292 // folding ignoring volatile.
293 (int)(i=i);
Eli Friedmana40b7f22011-08-12 23:33:52 +0000294 // CHECK-NEXT: load volatile
295 // CHECK-NEXT: store volatile
296 // CHECK-NEXT: load volatile
John McCall83ce9d42010-11-16 23:07:28 +0000297
298 // A use.
299 -(i=j);
Eli Friedmana40b7f22011-08-12 23:33:52 +0000300 // CHECK-NEXT: load volatile
301 // CHECK-NEXT: store volatile
302 // CHECK-NEXT: load volatile
John McCall83ce9d42010-11-16 23:07:28 +0000303 // CHECK-NEXT: sub
304
305 // A use. gcc treats this a not a use, that's probably a bug due to tree
306 // folding ignoring volatile.
307 +(i=k);
Eli Friedmana40b7f22011-08-12 23:33:52 +0000308 // CHECK-NEXT: load volatile
309 // CHECK-NEXT: store volatile
310 // CHECK-NEXT: load volatile
John McCall83ce9d42010-11-16 23:07:28 +0000311
312 // A use. gcc treats this a not a use, that's probably a bug due to tree
313 // folding ignoring volatile.
John McCall83ce9d42010-11-16 23:07:28 +0000314 __real (ci=ci);
Eli Friedmana40b7f22011-08-12 23:33:52 +0000315 // CHECK-NEXT: load volatile
316 // CHECK-NEXT: load volatile
317 // CHECK-NEXT: store volatile
318 // CHECK-NEXT: store volatile
John McCall83ce9d42010-11-16 23:07:28 +0000319
320 // A use.
321 i + 0;
Eli Friedmana40b7f22011-08-12 23:33:52 +0000322 // CHECK-NEXT: load volatile
John McCall83ce9d42010-11-16 23:07:28 +0000323 // CHECK-NEXT: add
324
325 // A use.
326 (i=j) + i;
Eli Friedmana40b7f22011-08-12 23:33:52 +0000327 // CHECK-NEXT: load volatile
328 // CHECK-NEXT: store volatile
329 // CHECK-NEXT: load volatile
330 // CHECK-NEXT: load volatile
John McCall83ce9d42010-11-16 23:07:28 +0000331 // CHECK-NEXT: add
332
333 // A use. gcc treats this as not a use, that's probably a bug due to tree
334 // folding ignoring volatile.
335 (i=j) + 0;
Eli Friedmana40b7f22011-08-12 23:33:52 +0000336 // CHECK-NEXT: load volatile
337 // CHECK-NEXT: store volatile
338 // CHECK-NEXT: load volatile
John McCall83ce9d42010-11-16 23:07:28 +0000339 // CHECK-NEXT: add
340
John McCall83ce9d42010-11-16 23:07:28 +0000341 (i,j)=k;
Eli Friedmana40b7f22011-08-12 23:33:52 +0000342 // CHECK-NEXT: load volatile [[INT]]* @k
343 // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @j
John McCall83ce9d42010-11-16 23:07:28 +0000344
John McCall83ce9d42010-11-16 23:07:28 +0000345 (j=k,i)=i;
Eli Friedmana40b7f22011-08-12 23:33:52 +0000346 // CHECK-NEXT: load volatile [[INT]]* @i
347 // CHECK-NEXT: load volatile [[INT]]* @k
348 // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @j
349 // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i
John McCall2a416372010-12-05 02:00:02 +0000350
351 // CHECK-NEXT: ret void
John McCall83ce9d42010-11-16 23:07:28 +0000352}