1 // RUN: %clang_cc1 -Wno-unused-value -triple %itanium_abi_triple -emit-llvm %s -std=c++98 -o - | FileCheck %s
2 // RUN: %clang_cc1 -Wno-unused-value -triple %itanium_abi_triple -emit-llvm %s -std=c++11 -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %s
3 
4 // CHECK: @i = {{(dso_local )?}}global [[INT:i[0-9]+]] 0
5 volatile int i, j, k;
6 volatile int ar[5];
7 volatile char c;
8 // CHECK: @ci = {{(dso_local )?}}global [[CINT:.*]] zeroinitializer
9 volatile _Complex int ci;
10 volatile struct S {
11 #ifdef __cplusplus
12   void operator =(volatile struct S&o) volatile;
13 #endif
14   int i;
15 } a, b;
16 
17 //void operator =(volatile struct S&o1, volatile struct S&o2) volatile;
18 int printf(const char *, ...);
19 
20 
21 // CHECK: define {{.*}}void @{{.*}}test
test()22 void test() {
23 
24   asm("nop"); // CHECK: call void asm
25 
26   // should not load in C++98
27   i;
28   // CHECK11-NEXT: load volatile [[INT]], [[INT]]* @i
29 
30   (float)(ci);
31   // CHECK-NEXT: load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
32   // CHECK-NEXT: load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
33   // CHECK-NEXT: sitofp [[INT]]
34 
35   // These are not uses in C++98:
36   //   [expr.static.cast]p6:
37   //     The lvalue-to-rvalue . . . conversions are not applied to the expression.
38   (void)ci;
39   // CHECK11-NEXT: load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
40   // CHECK11-NEXT: load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
41 
42   (void)a;
43 
44   (void)(ci=ci);
45   // CHECK-NEXT: [[R:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
46   // CHECK-NEXT: [[I:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
47   // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
48   // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
49 
50   (void)(i=j);
51   // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]], [[INT]]* @j
52   // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* @i
53 
54   ci+=ci;
55   // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
56   // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
57   // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
58   // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
59   // Not sure why they're ordered this way.
60   // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]]
61   // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]]
62   // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
63   // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
64 
65   // Note that C++ requires an extra load volatile over C from the LHS of the '+'.
66   (ci += ci) + ci;
67   // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
68   // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
69   // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
70   // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
71   // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]]
72   // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]]
73   // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
74   // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
75   // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
76   // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
77   // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
78   // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
79   // These additions can be elided.
80   // CHECK-NEXT: add [[INT]] [[R1]], [[R2]]
81   // CHECK-NEXT: add [[INT]] [[I1]], [[I2]]
82 
83   asm("nop"); // CHECK-NEXT: call void asm
84 
85   // Extra load volatile in C++.
86   (i += j) + k;
87   // CHECK-NEXT: load volatile
88   // CHECK-NEXT: load volatile
89   // CHECK-NEXT: add nsw [[INT]]
90   // CHECK-NEXT: store volatile
91   // CHECK-NEXT: load volatile
92   // CHECK-NEXT: load volatile
93   // CHECK-NEXT: add nsw [[INT]]
94 
95   asm("nop"); // CHECK-NEXT: call void asm
96 
97   // Extra load volatile in C++.
98   (i += j) + 1;
99   // CHECK-NEXT: load volatile
100   // CHECK-NEXT: load volatile
101   // CHECK-NEXT: add nsw [[INT]]
102   // CHECK-NEXT: store volatile
103   // CHECK-NEXT: load volatile
104   // CHECK-NEXT: add nsw [[INT]]
105 
106   asm("nop"); // CHECK-NEXT: call void asm
107 
108   ci+ci;
109   // CHECK-NEXT: load volatile
110   // CHECK-NEXT: load volatile
111   // CHECK-NEXT: load volatile
112   // CHECK-NEXT: load volatile
113   // CHECK-NEXT: add [[INT]]
114   // CHECK-NEXT: add [[INT]]
115 
116   __real i;
117 
118   +ci;
119   // CHECK-NEXT: load volatile
120   // CHECK-NEXT: load volatile
121 
122   asm("nop"); // CHECK-NEXT: call void asm
123 
124   (void)(i=i);
125   // CHECK-NEXT: load volatile
126   // CHECK-NEXT: store volatile
127 
128   (float)(i=i);
129   // CHECK-NEXT: load volatile
130   // CHECK-NEXT: store volatile
131   // CHECK-NEXT: load volatile
132   // CHECK-NEXT: sitofp
133 
134   (void)i; // This is now a load in C++11
135   // CHECK11-NEXT: load volatile
136 
137   i=i;
138   // CHECK-NEXT: load volatile
139   // CHECK-NEXT: store volatile
140 
141   // Extra load volatile in C++.
142   i=i=i;
143   // CHECK-NEXT: load volatile
144   // CHECK-NEXT: store volatile
145   // CHECK-NEXT: load volatile
146   // CHECK-NEXT: store volatile
147 
148   (void)__builtin_choose_expr(0, i=i, j=j);
149   // CHECK-NEXT: load volatile
150   // CHECK-NEXT: store volatile
151 
152   k ? (i=i) : (j=j);
153   // CHECK-NEXT: load volatile
154   // CHECK-NEXT: icmp
155   // CHECK-NEXT: br i1
156   // CHECK: load volatile
157   // CHECK-NEXT: store volatile
158   // CHECK-NEXT: br label
159   // CHECK: load volatile
160   // CHECK-NEXT: store volatile
161   // CHECK-NEXT: br label
162   // CHECK:      phi
163 
164   (void)(i,(i=i)); // first i is also a load in C++11
165   // CHECK11-NEXT: load volatile
166   // CHECK-NEXT: load volatile
167   // CHECK-NEXT: store volatile
168 
169   i=i,k; // k is also a load in C++11
170   // CHECK-NEXT: load volatile [[INT]], [[INT]]* @i
171   // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i
172   // CHECK11-NEXT: load volatile [[INT]], [[INT]]* @k
173 
174   (i=j,k=j);
175   // CHECK-NEXT: load volatile [[INT]], [[INT]]* @j
176   // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i
177   // CHECK-NEXT: load volatile [[INT]], [[INT]]* @j
178   // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @k
179 
180   (i=j,k); // k is also a load in C++11
181   // CHECK-NEXT: load volatile [[INT]], [[INT]]* @j
182   // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i
183   // CHECK11-NEXT: load volatile [[INT]], [[INT]]* @k
184 
185   (i,j); // i and j both are loads in C++11
186   // CHECK11-NEXT: load volatile [[INT]], [[INT]]* @i
187   // CHECK11-NEXT: load volatile [[INT]], [[INT]]* @j
188 
189   // Extra load in C++.
190   i=c=k;
191   // CHECK-NEXT: load volatile
192   // CHECK-NEXT: trunc
193   // CHECK-NEXT: store volatile
194   // CHECK-NEXT: load volatile
195   // CHECK-NEXT: sext
196   // CHECK-NEXT: store volatile
197 
198   i+=k;
199   // CHECK-NEXT: load volatile
200   // CHECK-NEXT: load volatile
201   // CHECK-NEXT: add nsw [[INT]]
202   // CHECK-NEXT: store volatile
203 
204   ci; // ci is a load in C++11
205   // CHECK11-NEXT: load volatile {{.*}} @ci, i32 0, i32 0
206   // CHECK11-NEXT: load volatile {{.*}} @ci, i32 0, i32 1
207 
208   asm("nop"); // CHECK-NEXT: call void asm
209 
210   (int)ci;
211   // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 0
212   // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 1
213 
214   (bool)ci;
215   // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 0
216   // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 1
217   // CHECK-NEXT: icmp ne
218   // CHECK-NEXT: icmp ne
219   // CHECK-NEXT: or i1
220 
221   ci=ci;
222   // CHECK-NEXT: load volatile
223   // CHECK-NEXT: load volatile
224   // CHECK-NEXT: store volatile
225   // CHECK-NEXT: store volatile
226 
227   asm("nop"); // CHECK-NEXT: call void asm
228 
229   // Extra load in C++.
230   ci=ci=ci;
231   // CHECK-NEXT: load volatile
232   // CHECK-NEXT: load volatile
233   // CHECK-NEXT: store volatile
234   // CHECK-NEXT: store volatile
235   // CHECK-NEXT: load volatile
236   // CHECK-NEXT: load volatile
237   // CHECK-NEXT: store volatile
238   // CHECK-NEXT: store volatile
239 
240   __imag ci = __imag ci = __imag ci;
241   // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
242   // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
243   // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
244   // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
245 
246   __real (i = j);
247   // CHECK-NEXT: load volatile
248   // CHECK-NEXT: store volatile
249 
250   __imag i;
251 
252   // ============================================================
253   // FIXME: Test cases we get wrong.
254 
255   // A use.  We load all of a into a copy of a, then load i.  gcc forgets to do
256   // the assignment.
257   // (a = a).i;
258 
259   // ============================================================
260   // Test cases where we intentionally differ from gcc, due to suspected bugs in
261   // gcc.
262 
263   // Not a use.  gcc forgets to do the assignment.
264   // CHECK-NEXT: call {{.*}}void
265   ((a=a),a);
266 
267   // Not a use.  gcc gets this wrong, it doesn't emit the copy!
268   // CHECK-NEXT: call {{.*}}void
269   (void)(a=a);
270 
271   // Not a use.  gcc got this wrong in 4.2 and omitted the side effects
272   // entirely, but it is fixed in 4.4.0.
273   __imag (i = j);
274   // CHECK-NEXT: load volatile
275   // CHECK-NEXT: store volatile
276 
277   // C++ does an extra load here.  Note that we have to do full loads.
278   (float)(ci=ci);
279   // CHECK-NEXT: load volatile
280   // CHECK-NEXT: load volatile
281   // CHECK-NEXT: store volatile
282   // CHECK-NEXT: store volatile
283   // CHECK-NEXT: load volatile
284   // CHECK-NEXT: load volatile
285   // CHECK-NEXT: sitofp
286 
287   // Not a use, bug?  gcc treats this as not a use, that's probably a
288   // bug due to tree folding ignoring volatile.
289   (int)(ci=ci);
290   // CHECK-NEXT: load volatile
291   // CHECK-NEXT: load volatile
292   // CHECK-NEXT: store volatile
293   // CHECK-NEXT: store volatile
294   // CHECK-NEXT: load volatile
295   // CHECK-NEXT: load volatile
296 
297   // A use.
298   (float)(i=i);
299   // CHECK-NEXT: load volatile
300   // CHECK-NEXT: store volatile
301   // CHECK-NEXT: load volatile
302   // CHECK-NEXT: sitofp
303 
304   // A use.  gcc treats this as not a use, that's probably a bug due to tree
305   // folding ignoring volatile.
306   (int)(i=i);
307   // CHECK-NEXT: load volatile
308   // CHECK-NEXT: store volatile
309   // CHECK-NEXT: load volatile
310 
311   // A use.
312   -(i=j);
313   // CHECK-NEXT: load volatile
314   // CHECK-NEXT: store volatile
315   // CHECK-NEXT: load volatile
316   // CHECK-NEXT: sub
317 
318   // A use.  gcc treats this a not a use, that's probably a bug due to tree
319   // folding ignoring volatile.
320   +(i=k);
321   // CHECK-NEXT: load volatile
322   // CHECK-NEXT: store volatile
323   // CHECK-NEXT: load volatile
324 
325   // A use. gcc treats this a not a use, that's probably a bug due to tree
326   // folding ignoring volatile.
327   __real (ci=ci);
328   // CHECK-NEXT: load volatile
329   // CHECK-NEXT: load volatile
330   // CHECK-NEXT: store volatile
331   // CHECK-NEXT: store volatile
332 
333   // A use.
334   i + 0;
335   // CHECK-NEXT: load volatile
336   // CHECK-NEXT: add
337 
338   // A use.
339   (i=j) + i;
340   // CHECK-NEXT: load volatile
341   // CHECK-NEXT: store volatile
342   // CHECK-NEXT: load volatile
343   // CHECK-NEXT: load volatile
344   // CHECK-NEXT: add
345 
346   // A use.  gcc treats this as not a use, that's probably a bug due to tree
347   // folding ignoring volatile.
348   (i=j) + 0;
349   // CHECK-NEXT: load volatile
350   // CHECK-NEXT: store volatile
351   // CHECK-NEXT: load volatile
352   // CHECK-NEXT: add
353 
354   (i,j)=k; // i is also a load in C++11
355   // CHECK-NEXT: load volatile [[INT]], [[INT]]* @k
356   // CHECK11-NEXT: load volatile [[INT]], [[INT]]* @i
357   // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @j
358 
359   (j=k,i)=i;
360   // CHECK-NEXT: load volatile [[INT]], [[INT]]* @i
361   // CHECK-NEXT: load volatile [[INT]], [[INT]]* @k
362   // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @j
363   // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i
364 
365   // CHECK-NEXT: ret void
366 }
367