1 // RUN: %clang_cc1 -Wno-return-type -Wno-unused-value -emit-llvm %s -o - | FileCheck %s
3 // CHECK: @i = common global [[INT:i[0-9]+]] 0
7 // CHECK: @ci = common global [[CINT:%.*]] zeroinitializer
8 volatile _Complex
int ci
;
11 void operator =(volatile struct S
&o
) volatile;
16 //void operator =(volatile struct S&o1, volatile struct S&o2) volatile;
17 int printf(const char *, ...);
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
25 // CHECK: define void @test()
27 // CHECK: volatile load [[INT]]* @i
29 // 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]]
33 // 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)
36 // CHECK-NEXT: bitcast
39 // 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)
44 // CHECK-NEXT: [[T:%.*]] = volatile load [[INT]]* @j
45 // CHECK-NEXT: volatile store [[INT]] [[T]], [[INT]]* @i
47 // 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)
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]]
72 // CHECK-NEXT: call void asm
74 // 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]]
81 // CHECK-NEXT: call void asm
83 // 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]]
89 // CHECK-NEXT: call void asm
91 // 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]]
99 // CHECK-NEXT: volatile load
101 // CHECK-NEXT: volatile load
102 // CHECK-NEXT: volatile load
104 // CHECK-NEXT: call void asm
106 // CHECK-NEXT: volatile load
107 // CHECK-NEXT: volatile store
109 // CHECK-NEXT: volatile load
110 // CHECK-NEXT: volatile store
111 // CHECK-NEXT: sitofp
113 // CHECK-NEXT: volatile load
115 // CHECK-NEXT: volatile load
116 // CHECK-NEXT: volatile store
118 // CHECK-NEXT: volatile load
119 // CHECK-NEXT: volatile store
120 // CHECK-NEXT: volatile store
123 // CHECK-NEXT: volatile load
124 // CHECK-NEXT: volatile store
125 (void)__builtin_choose_expr(0, i
=i
, j
=j
);
127 // CHECK-NEXT: volatile load
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
138 // CHECK-NEXT: volatile load
139 // CHECK-NEXT: volatile load
140 // CHECK-NEXT: volatile store
142 // CHECK-NEXT: volatile load
143 // CHECK-NEXT: volatile store
144 // CHECK-NEXT: volatile load
146 // CHECK-NEXT: volatile load
147 // CHECK-NEXT: volatile store
148 // CHECK-NEXT: volatile load
149 // CHECK-NEXT: volatile store
151 // CHECK-NEXT: volatile load
152 // CHECK-NEXT: volatile store
153 // CHECK-NEXT: volatile load
155 // CHECK-NEXT: volatile load
156 // CHECK-NEXT: volatile load
158 // CHECK-NEXT: volatile load
160 // CHECK-NEXT: volatile store
162 // CHECK-NEXT: volatile store
164 // CHECK-NEXT: volatile load
165 // CHECK-NEXT: volatile load
166 // CHECK-NEXT: add nsw [[INT]]
167 // CHECK-NEXT: volatile store
169 // CHECK-NEXT: volatile load
170 // CHECK-NEXT: volatile load
173 // CHECK-NEXT: volatile load
174 // CHECK-NEXT: volatile load
176 // CHECK-NEXT: volatile load
177 // CHECK-NEXT: volatile load
178 // CHECK-NEXT: icmp ne
179 // CHECK-NEXT: icmp ne
183 // CHECK-NEXT: volatile load
184 // CHECK-NEXT: volatile load
185 // CHECK-NEXT: volatile store
186 // CHECK-NEXT: volatile store
188 // 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
195 // 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)
198 __imag ci
= __imag ci
= __imag ci
;
199 // CHECK-NEXT: volatile load
200 // CHECK-NEXT: volatile store
202 // CHECK-NEXT: volatile load
205 // ============================================================
206 // FIXME: Test cases we get wrong.
208 // A use. We load all of a into a copy of a, then load i. gcc forgets to do
212 // ============================================================
213 // Test cases where we intentionally differ from gcc, due to suspected bugs in
216 // Not a use. gcc forgets to do the assignment.
217 // CHECK-NEXT: call void @llvm.memcpy{{.*}}, i1 true
218 // CHECK-NEXT: bitcast
219 // CHECK-NEXT: call void @llvm.memcpy{{.*}}, i1 true
222 // Not a use. gcc gets this wrong, it doesn't emit the copy!
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.
227 // CHECK-NEXT: volatile load
228 // CHECK-NEXT: volatile store
232 // A use of the real part
233 // CHECK-NEXT: volatile load
234 // CHECK-NEXT: volatile load
235 // CHECK-NEXT: volatile store
236 // CHECK-NEXT: volatile store
237 // CHECK-NEXT: sitofp
239 // Not a use, bug? gcc treats this as not a use, that's probably a bug due to
240 // tree folding ignoring volatile.
241 // CHECK-NEXT: volatile load
242 // CHECK-NEXT: volatile load
243 // CHECK-NEXT: volatile store
244 // CHECK-NEXT: volatile store
249 // CHECK-NEXT: volatile load
250 // CHECK-NEXT: volatile store
251 // CHECK-NEXT: sitofp
253 // A use. gcc treats this as not a use, that's probably a bug due to tree
254 // folding ignoring volatile.
255 // CHECK-NEXT: volatile load
256 // CHECK-NEXT: volatile store
260 // CHECK-NEXT: volatile load
261 // CHECK-NEXT: volatile store
264 // A use. gcc treats this a not a use, that's probably a bug due to tree
265 // folding ignoring volatile.
266 // CHECK-NEXT: volatile load
267 // CHECK-NEXT: volatile store
270 // A use. gcc treats this a not a use, that's probably a bug due to tree
271 // folding ignoring volatile.
272 // CHECK-NEXT: volatile load
273 // CHECK-NEXT: volatile load
274 // CHECK-NEXT: volatile store
275 // CHECK-NEXT: volatile store
279 // CHECK-NEXT: volatile load
283 // CHECK-NEXT: volatile load
284 // CHECK-NEXT: volatile store
285 // CHECK-NEXT: volatile load
288 // A use. gcc treats this as not a use, that's probably a bug due to tree
289 // folding ignoring volatile.
290 // CHECK-NEXT: volatile load
291 // CHECK-NEXT: volatile store
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
));
305 extern volatile enum X x
;
306 // CHECK: define void @test1()
308 extern void test1_helper(void);
310 // CHECK: call void @test1_helper()
311 // CHECK-NEXT: ret void