blob: f54afffdadab18dd2fe29659c82915651b108819 [file] [log] [blame]
John McCallf6a16482010-12-04 03:47:34 +00001// RUN: %clang_cc1 -Wno-return-type -Wno-unused-value -emit-llvm %s -o - | FileCheck %s
Mike Stump7f79f9b2009-05-29 15:46:01 +00002
John McCallb418d742010-11-16 10:08:07 +00003// CHECK: @i = common global [[INT:i[0-9]+]] 0
Mike Stump7f79f9b2009-05-29 15:46:01 +00004volatile int i, j, k;
5volatile int ar[5];
6volatile char c;
John McCallb418d742010-11-16 10:08:07 +00007// CHECK: @ci = common global [[CINT:%.*]] zeroinitializer
Mike Stump7f79f9b2009-05-29 15:46:01 +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;
Daniel Dunbar23afaad2009-11-17 08:57:36 +000017int printf(const char *, ...);
Mike Stump7f79f9b2009-05-29 15:46:01 +000018
John McCallb418d742010-11-16 10:08:07 +000019
20// Note that these test results are very much specific to C!
21// Assignments in C++ yield l-values, not r-values, and the situations
22// that do implicit lvalue-to-rvalue conversion are substantially
23// reduced.
24
25// CHECK: define void @test()
26void test() {
27 // CHECK: volatile load [[INT]]* @i
Mike Stump7f79f9b2009-05-29 15:46:01 +000028 i;
John McCallb418d742010-11-16 10:08:07 +000029 // CHECK-NEXT: volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
30 // CHECK-NEXT: volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
31 // CHECK-NEXT: sitofp [[INT]]
Mike Stump7f79f9b2009-05-29 15:46:01 +000032 (float)(ci);
John McCallb418d742010-11-16 10:08:07 +000033 // CHECK-NEXT: volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
34 // CHECK-NEXT: volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
Mike Stump7f79f9b2009-05-29 15:46:01 +000035 (void)ci;
John McCallb418d742010-11-16 10:08:07 +000036 // CHECK-NEXT: bitcast
37 // CHECK-NEXT: memcpy
Mike Stump7f79f9b2009-05-29 15:46:01 +000038 (void)a;
John McCallb418d742010-11-16 10:08:07 +000039 // CHECK-NEXT: [[R:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
40 // CHECK-NEXT: [[I:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
41 // CHECK-NEXT: volatile store [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
42 // CHECK-NEXT: volatile store [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
Mike Stump7f79f9b2009-05-29 15:46:01 +000043 (void)(ci=ci);
John McCallb418d742010-11-16 10:08:07 +000044 // CHECK-NEXT: [[T:%.*]] = volatile load [[INT]]* @j
45 // CHECK-NEXT: volatile store [[INT]] [[T]], [[INT]]* @i
Mike Stump7f79f9b2009-05-29 15:46:01 +000046 (void)(i=j);
John McCallb418d742010-11-16 10:08:07 +000047 // CHECK-NEXT: [[R1:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
48 // CHECK-NEXT: [[I1:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
49 // CHECK-NEXT: [[R2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
50 // CHECK-NEXT: [[I2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
51 // Not sure why they're ordered this way.
52 // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]]
53 // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]]
54 // CHECK-NEXT: volatile store [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
55 // CHECK-NEXT: volatile store [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
Mike Stump7f79f9b2009-05-29 15:46:01 +000056 ci+=ci;
John McCallb418d742010-11-16 10:08:07 +000057
58 // CHECK-NEXT: [[R1:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
59 // CHECK-NEXT: [[I1:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
60 // CHECK-NEXT: [[R2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
61 // CHECK-NEXT: [[I2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
62 // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]]
63 // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]]
64 // CHECK-NEXT: volatile store [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
65 // CHECK-NEXT: volatile store [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
66 // CHECK-NEXT: [[R2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
67 // CHECK-NEXT: [[I2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
68 // These additions can be elided
69 // CHECK-NEXT: add [[INT]] [[R]], [[R2]]
70 // CHECK-NEXT: add [[INT]] [[I]], [[I2]]
Mike Stump7f79f9b2009-05-29 15:46:01 +000071 (ci += ci) + ci;
John McCallb418d742010-11-16 10:08:07 +000072 // CHECK-NEXT: call void asm
Mike Stump7f79f9b2009-05-29 15:46:01 +000073 asm("nop");
John McCallb418d742010-11-16 10:08:07 +000074 // CHECK-NEXT: volatile load
75 // CHECK-NEXT: volatile load
76 // CHECK-NEXT: add nsw [[INT]]
77 // CHECK-NEXT: volatile store
78 // CHECK-NEXT: volatile load
79 // CHECK-NEXT: add nsw [[INT]]
Mike Stump7f79f9b2009-05-29 15:46:01 +000080 (i += j) + k;
John McCallb418d742010-11-16 10:08:07 +000081 // CHECK-NEXT: call void asm
Mike Stump7f79f9b2009-05-29 15:46:01 +000082 asm("nop");
John McCallb418d742010-11-16 10:08:07 +000083 // CHECK-NEXT: volatile load
84 // CHECK-NEXT: volatile load
85 // CHECK-NEXT: add nsw [[INT]]
86 // CHECK-NEXT: volatile store
87 // CHECK-NEXT: add nsw [[INT]]
Mike Stump7f79f9b2009-05-29 15:46:01 +000088 (i += j) + 1;
John McCallb418d742010-11-16 10:08:07 +000089 // CHECK-NEXT: call void asm
Mike Stump7f79f9b2009-05-29 15:46:01 +000090 asm("nop");
John McCallb418d742010-11-16 10:08:07 +000091 // CHECK-NEXT: volatile load
92 // CHECK-NEXT: volatile load
93 // CHECK-NEXT: volatile load
94 // CHECK-NEXT: volatile load
95 // CHECK-NEXT: add [[INT]]
96 // CHECK-NEXT: add [[INT]]
Mike Stump7f79f9b2009-05-29 15:46:01 +000097 ci+ci;
John McCallb418d742010-11-16 10:08:07 +000098
99 // CHECK-NEXT: volatile load
Mike Stump7f79f9b2009-05-29 15:46:01 +0000100 __real i;
John McCallb418d742010-11-16 10:08:07 +0000101 // CHECK-NEXT: volatile load
102 // CHECK-NEXT: volatile load
Mike Stump7f79f9b2009-05-29 15:46:01 +0000103 +ci;
John McCallb418d742010-11-16 10:08:07 +0000104 // CHECK-NEXT: call void asm
Mike Stump7f79f9b2009-05-29 15:46:01 +0000105 asm("nop");
John McCallb418d742010-11-16 10:08:07 +0000106 // CHECK-NEXT: volatile load
107 // CHECK-NEXT: volatile store
Mike Stump7f79f9b2009-05-29 15:46:01 +0000108 (void)(i=i);
John McCallb418d742010-11-16 10:08:07 +0000109 // CHECK-NEXT: volatile load
110 // CHECK-NEXT: volatile store
111 // CHECK-NEXT: sitofp
Mike Stump7f79f9b2009-05-29 15:46:01 +0000112 (float)(i=i);
John McCallb418d742010-11-16 10:08:07 +0000113 // CHECK-NEXT: volatile load
Mike Stump7f79f9b2009-05-29 15:46:01 +0000114 (void)i;
John McCallb418d742010-11-16 10:08:07 +0000115 // CHECK-NEXT: volatile load
116 // CHECK-NEXT: volatile store
Mike Stump7f79f9b2009-05-29 15:46:01 +0000117 i=i;
John McCallb418d742010-11-16 10:08:07 +0000118 // CHECK-NEXT: volatile load
119 // CHECK-NEXT: volatile store
120 // CHECK-NEXT: volatile store
Mike Stump7f79f9b2009-05-29 15:46:01 +0000121 i=i=i;
122#ifndef __cplusplus
John McCallb418d742010-11-16 10:08:07 +0000123 // CHECK-NEXT: volatile load
124 // CHECK-NEXT: volatile store
Mike Stump7f79f9b2009-05-29 15:46:01 +0000125 (void)__builtin_choose_expr(0, i=i, j=j);
126#endif
John McCallb418d742010-11-16 10:08:07 +0000127 // CHECK-NEXT: volatile load
128 // CHECK-NEXT: icmp
129 // CHECK-NEXT: br i1
130 // CHECK: volatile load
131 // CHECK-NEXT: volatile store
132 // CHECK-NEXT: br label
133 // CHECK: volatile load
134 // CHECK-NEXT: volatile store
135 // CHECK-NEXT: br label
Mike Stump7f79f9b2009-05-29 15:46:01 +0000136 k ? (i=i) : (j=j);
John McCallb418d742010-11-16 10:08:07 +0000137 // CHECK: phi
138 // CHECK-NEXT: volatile load
139 // CHECK-NEXT: volatile load
140 // CHECK-NEXT: volatile store
Mike Stump7f79f9b2009-05-29 15:46:01 +0000141 (void)(i,(i=i));
John McCallb418d742010-11-16 10:08:07 +0000142 // CHECK-NEXT: volatile load
143 // CHECK-NEXT: volatile store
144 // CHECK-NEXT: volatile load
Mike Stump7f79f9b2009-05-29 15:46:01 +0000145 i=i,i;
John McCallb418d742010-11-16 10:08:07 +0000146 // CHECK-NEXT: volatile load
147 // CHECK-NEXT: volatile store
148 // CHECK-NEXT: volatile load
149 // CHECK-NEXT: volatile store
Mike Stump7f79f9b2009-05-29 15:46:01 +0000150 (i=j,k=j);
John McCallb418d742010-11-16 10:08:07 +0000151 // CHECK-NEXT: volatile load
152 // CHECK-NEXT: volatile store
153 // CHECK-NEXT: volatile load
Mike Stump7f79f9b2009-05-29 15:46:01 +0000154 (i=j,k);
John McCallb418d742010-11-16 10:08:07 +0000155 // CHECK-NEXT: volatile load
156 // CHECK-NEXT: volatile load
Mike Stump7f79f9b2009-05-29 15:46:01 +0000157 (i,j);
John McCallb418d742010-11-16 10:08:07 +0000158 // CHECK-NEXT: volatile load
159 // CHECK-NEXT: trunc
160 // CHECK-NEXT: volatile store
161 // CHECK-NEXT: sext
162 // CHECK-NEXT: volatile store
Mike Stump7f79f9b2009-05-29 15:46:01 +0000163 i=c=k;
John McCallb418d742010-11-16 10:08:07 +0000164 // CHECK-NEXT: volatile load
165 // CHECK-NEXT: volatile load
166 // CHECK-NEXT: add nsw [[INT]]
167 // CHECK-NEXT: volatile store
Mike Stump7f79f9b2009-05-29 15:46:01 +0000168 i+=k;
John McCallb418d742010-11-16 10:08:07 +0000169 // CHECK-NEXT: volatile load
170 // CHECK-NEXT: volatile load
Mike Stump7f79f9b2009-05-29 15:46:01 +0000171 ci;
172#ifndef __cplusplus
John McCallb418d742010-11-16 10:08:07 +0000173 // CHECK-NEXT: volatile load
174 // CHECK-NEXT: volatile load
Mike Stump7f79f9b2009-05-29 15:46:01 +0000175 (int)ci;
John McCallb418d742010-11-16 10:08:07 +0000176 // CHECK-NEXT: volatile load
177 // CHECK-NEXT: volatile load
178 // CHECK-NEXT: icmp ne
179 // CHECK-NEXT: icmp ne
180 // CHECK-NEXT: or i1
Mike Stump7f79f9b2009-05-29 15:46:01 +0000181 (_Bool)ci;
182#endif
John McCallb418d742010-11-16 10:08:07 +0000183 // CHECK-NEXT: volatile load
184 // CHECK-NEXT: volatile load
185 // CHECK-NEXT: volatile store
186 // CHECK-NEXT: volatile store
Mike Stump7f79f9b2009-05-29 15:46:01 +0000187 ci=ci;
John McCallb418d742010-11-16 10:08:07 +0000188 // CHECK-NEXT: volatile load
189 // CHECK-NEXT: volatile load
190 // CHECK-NEXT: volatile store
191 // CHECK-NEXT: volatile store
192 // CHECK-NEXT: volatile store
193 // CHECK-NEXT: volatile store
Mike Stump7f79f9b2009-05-29 15:46:01 +0000194 ci=ci=ci;
John McCallb418d742010-11-16 10:08:07 +0000195 // CHECK-NEXT: [[T:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
196 // CHECK-NEXT: volatile store [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
197 // CHECK-NEXT: volatile store [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
Mike Stump7f79f9b2009-05-29 15:46:01 +0000198 __imag ci = __imag ci = __imag ci;
John McCallb418d742010-11-16 10:08:07 +0000199 // CHECK-NEXT: volatile load
200 // CHECK-NEXT: volatile store
Mike Stump7f79f9b2009-05-29 15:46:01 +0000201 __real (i = j);
John McCallb418d742010-11-16 10:08:07 +0000202 // CHECK-NEXT: volatile load
Mike Stump7f79f9b2009-05-29 15:46:01 +0000203 __imag i;
204
205 // ============================================================
Mike Stump46cd81f2009-05-29 16:24:13 +0000206 // FIXME: Test cases we get wrong.
Mike Stump7f79f9b2009-05-29 15:46:01 +0000207
Mike Stump2d3b36e2009-05-29 16:12:36 +0000208 // A use. We load all of a into a copy of a, then load i. gcc forgets to do
209 // the assignment.
Mike Stump46cd81f2009-05-29 16:24:13 +0000210 // (a = a).i;
Mike Stump2d3b36e2009-05-29 16:12:36 +0000211
Mike Stump7f79f9b2009-05-29 15:46:01 +0000212 // ============================================================
213 // Test cases where we intentionally differ from gcc, due to suspected bugs in
214 // gcc.
215
216 // Not a use. gcc forgets to do the assignment.
John McCallb418d742010-11-16 10:08:07 +0000217 // CHECK-NEXT: call void @llvm.memcpy{{.*}}, i1 true
218 // CHECK-NEXT: bitcast
219 // CHECK-NEXT: call void @llvm.memcpy{{.*}}, i1 true
Mike Stump7f79f9b2009-05-29 15:46:01 +0000220 ((a=a),a);
221
222 // Not a use. gcc gets this wrong, it doesn't emit the copy!
223 // (void)(a=a);
224
225 // Not a use. gcc got this wrong in 4.2 and omitted the side effects
226 // entirely, but it is fixed in 4.4.0.
John McCallb418d742010-11-16 10:08:07 +0000227 // CHECK-NEXT: volatile load
228 // CHECK-NEXT: volatile store
Mike Stump7f79f9b2009-05-29 15:46:01 +0000229 __imag (i = j);
230
231#ifndef __cplusplus
232 // A use of the real part
John McCallb418d742010-11-16 10:08:07 +0000233 // CHECK-NEXT: volatile load
234 // CHECK-NEXT: volatile load
235 // CHECK-NEXT: volatile store
236 // CHECK-NEXT: volatile store
237 // CHECK-NEXT: sitofp
Mike Stump7f79f9b2009-05-29 15:46:01 +0000238 (float)(ci=ci);
239 // Not a use, bug? gcc treats this as not a use, that's probably a bug due to
240 // tree folding ignoring volatile.
John McCallb418d742010-11-16 10:08:07 +0000241 // CHECK-NEXT: volatile load
242 // CHECK-NEXT: volatile load
243 // CHECK-NEXT: volatile store
244 // CHECK-NEXT: volatile store
Mike Stump7f79f9b2009-05-29 15:46:01 +0000245 (int)(ci=ci);
246#endif
247
248 // A use.
John McCallb418d742010-11-16 10:08:07 +0000249 // CHECK-NEXT: volatile load
250 // CHECK-NEXT: volatile store
251 // CHECK-NEXT: sitofp
Mike Stump7f79f9b2009-05-29 15:46:01 +0000252 (float)(i=i);
253 // A use. gcc treats this as not a use, that's probably a bug due to tree
254 // folding ignoring volatile.
John McCallb418d742010-11-16 10:08:07 +0000255 // CHECK-NEXT: volatile load
256 // CHECK-NEXT: volatile store
Mike Stump7f79f9b2009-05-29 15:46:01 +0000257 (int)(i=i);
258
259 // A use.
John McCallb418d742010-11-16 10:08:07 +0000260 // CHECK-NEXT: volatile load
261 // CHECK-NEXT: volatile store
262 // CHECK-NEXT: sub
Mike Stump7f79f9b2009-05-29 15:46:01 +0000263 -(i=j);
264 // A use. gcc treats this a not a use, that's probably a bug due to tree
265 // folding ignoring volatile.
John McCallb418d742010-11-16 10:08:07 +0000266 // CHECK-NEXT: volatile load
267 // CHECK-NEXT: volatile store
Mike Stump7f79f9b2009-05-29 15:46:01 +0000268 +(i=k);
269
270 // A use. gcc treats this a not a use, that's probably a bug due to tree
271 // folding ignoring volatile.
John McCallb418d742010-11-16 10:08:07 +0000272 // CHECK-NEXT: volatile load
273 // CHECK-NEXT: volatile load
274 // CHECK-NEXT: volatile store
275 // CHECK-NEXT: volatile store
Mike Stump7f79f9b2009-05-29 15:46:01 +0000276 __real (ci=ci);
277
278 // A use.
John McCallb418d742010-11-16 10:08:07 +0000279 // CHECK-NEXT: volatile load
280 // CHECK-NEXT: add
Mike Stump7f79f9b2009-05-29 15:46:01 +0000281 i + 0;
282 // A use.
John McCallb418d742010-11-16 10:08:07 +0000283 // CHECK-NEXT: volatile load
284 // CHECK-NEXT: volatile store
285 // CHECK-NEXT: volatile load
286 // CHECK-NEXT: add
Mike Stump7f79f9b2009-05-29 15:46:01 +0000287 (i=j) + i;
288 // A use. gcc treats this as not a use, that's probably a bug due to tree
289 // folding ignoring volatile.
John McCallb418d742010-11-16 10:08:07 +0000290 // CHECK-NEXT: volatile load
291 // CHECK-NEXT: volatile store
292 // CHECK-NEXT: add
Mike Stump7f79f9b2009-05-29 15:46:01 +0000293 (i=j) + 0;
294
295#ifdef __cplusplus
296 (i,j)=k;
297 (j=k,i)=i;
298 struct { int x; } s, s1;
299 printf("s is at %p\n", &s);
300 printf("s is at %p\n", &(s = s1));
301 printf("s.x is at %p\n", &((s = s1).x));
302#endif
303}
John McCallf6a16482010-12-04 03:47:34 +0000304
305extern volatile enum X x;
306// CHECK: define void @test1()
307void test1() {
John McCall3144b722010-12-04 05:19:12 +0000308 extern void test1_helper(void);
309 test1_helper();
310 // CHECK: call void @test1_helper()
John McCallf6a16482010-12-04 03:47:34 +0000311 // CHECK-NEXT: ret void
312 x;
313 (void) x;
314 return x;
315}