1 // XFAIL: target=aarch64-pc-windows-msvc
2 // RUN: %clang_cc1 -Wno-return-type -Wno-unused-value -emit-llvm %s -w -o - | FileCheck %s
4 // CHECK: @i = {{(dso_local )?}}global [[INT:i[0-9]+]] 0
8 // CHECK: @ci = {{(dso_local )?}}global [[CINT:.*]] zeroinitializer
9 volatile _Complex
int ci
;
12 void operator =(volatile struct S
&o
) volatile;
17 //void operator =(volatile struct S&o1, volatile struct S&o2) volatile;
18 int printf(const char *, ...);
21 // Note that these test results are very much specific to C!
22 // Assignments in C++ yield l-values, not r-values, and the situations
23 // that do implicit lvalue-to-rvalue conversion are substantially
26 // CHECK-LABEL: define {{.*}}void @test()
28 // CHECK: load volatile [[INT]], ptr @i
30 // CHECK-NEXT: load volatile [[INT]], ptr @ci, align 4
31 // CHECK-NEXT: load volatile [[INT]], ptr getelementptr inbounds ([[CINT]], ptr @ci, i32 0, i32 1), align 4
32 // CHECK-NEXT: sitofp [[INT]]
34 // CHECK-NEXT: load volatile [[INT]], ptr @ci, align 4
35 // CHECK-NEXT: load volatile [[INT]], ptr getelementptr inbounds ([[CINT]], ptr @ci, i32 0, i32 1), align 4
39 // CHECK-NEXT: [[R:%.*]] = load volatile [[INT]], ptr @ci, align 4
40 // CHECK-NEXT: [[I:%.*]] = load volatile [[INT]], ptr getelementptr inbounds ([[CINT]], ptr @ci, i32 0, i32 1), align 4
41 // CHECK-NEXT: store volatile [[INT]] [[R]], ptr @ci, align 4
42 // CHECK-NEXT: store volatile [[INT]] [[I]], ptr getelementptr inbounds ([[CINT]], ptr @ci, i32 0, i32 1), align 4
44 // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]], ptr @j
45 // CHECK-NEXT: store volatile [[INT]] [[T]], ptr @i
47 // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]], ptr @ci, align 4
48 // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]], ptr getelementptr inbounds ([[CINT]], ptr @ci, i32 0, i32 1), align 4
49 // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]], ptr @ci, align 4
50 // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]], ptr getelementptr inbounds ([[CINT]], ptr @ci, i32 0, i32 1), align 4
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: store volatile [[INT]] [[R]], ptr @ci, align 4
55 // CHECK-NEXT: store volatile [[INT]] [[I]], ptr getelementptr inbounds ([[CINT]], ptr @ci, i32 0, i32 1), align 4
58 // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]], ptr @ci, align 4
59 // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]], ptr getelementptr inbounds ([[CINT]], ptr @ci, i32 0, i32 1), align 4
60 // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]], ptr @ci, align 4
61 // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]], ptr getelementptr inbounds ([[CINT]], ptr @ci, i32 0, i32 1), align 4
62 // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]]
63 // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]]
64 // CHECK-NEXT: store volatile [[INT]] [[R]], ptr @ci, align 4
65 // CHECK-NEXT: store volatile [[INT]] [[I]], ptr getelementptr inbounds ([[CINT]], ptr @ci, i32 0, i32 1), align 4
66 // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]], ptr @ci, align 4
67 // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]], ptr getelementptr inbounds ([[CINT]], ptr @ci, i32 0, i32 1), align 4
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: load volatile
75 // CHECK-NEXT: load volatile
76 // CHECK-NEXT: add nsw [[INT]]
77 // CHECK-NEXT: store volatile
78 // CHECK-NEXT: load volatile
79 // CHECK-NEXT: add nsw [[INT]]
81 // CHECK-NEXT: call void asm
83 // CHECK-NEXT: load volatile
84 // CHECK-NEXT: load volatile
85 // CHECK-NEXT: add nsw [[INT]]
86 // CHECK-NEXT: store volatile
87 // CHECK-NEXT: add nsw [[INT]]
89 // CHECK-NEXT: call void asm
91 // CHECK-NEXT: load volatile
92 // CHECK-NEXT: load volatile
93 // CHECK-NEXT: load volatile
94 // CHECK-NEXT: load volatile
95 // CHECK-NEXT: add [[INT]]
96 // CHECK-NEXT: add [[INT]]
99 // CHECK-NEXT: load volatile
101 // CHECK-NEXT: load volatile
102 // CHECK-NEXT: load volatile
104 // CHECK-NEXT: call void asm
106 // CHECK-NEXT: load volatile
107 // CHECK-NEXT: store volatile
109 // CHECK-NEXT: load volatile
110 // CHECK-NEXT: store volatile
111 // CHECK-NEXT: sitofp
113 // CHECK-NEXT: load volatile
115 // CHECK-NEXT: load volatile
116 // CHECK-NEXT: store volatile
118 // CHECK-NEXT: load volatile
119 // CHECK-NEXT: store volatile
120 // CHECK-NEXT: store volatile
123 // CHECK-NEXT: load volatile
124 // CHECK-NEXT: store volatile
125 (void)__builtin_choose_expr(0, i
=i
, j
=j
);
127 // CHECK-NEXT: load volatile
130 // CHECK: load volatile
131 // CHECK-NEXT: store volatile
132 // CHECK-NEXT: br label
133 // CHECK: load volatile
134 // CHECK-NEXT: store volatile
135 // CHECK-NEXT: br label
138 // CHECK-NEXT: load volatile
139 // CHECK-NEXT: load volatile
140 // CHECK-NEXT: store volatile
142 // CHECK-NEXT: load volatile
143 // CHECK-NEXT: store volatile
144 // CHECK-NEXT: load volatile
146 // CHECK-NEXT: load volatile
147 // CHECK-NEXT: store volatile
148 // CHECK-NEXT: load volatile
149 // CHECK-NEXT: store volatile
151 // CHECK-NEXT: load volatile
152 // CHECK-NEXT: store volatile
153 // CHECK-NEXT: load volatile
155 // CHECK-NEXT: load volatile
156 // CHECK-NEXT: load volatile
158 // CHECK-NEXT: load volatile
160 // CHECK-NEXT: store volatile
162 // CHECK-NEXT: store volatile
164 // CHECK-NEXT: load volatile
165 // CHECK-NEXT: load volatile
166 // CHECK-NEXT: add nsw [[INT]]
167 // CHECK-NEXT: store volatile
169 // CHECK-NEXT: load volatile
170 // CHECK-NEXT: load volatile
173 // CHECK-NEXT: load volatile
174 // CHECK-NEXT: load volatile
176 // CHECK-NEXT: load volatile
177 // CHECK-NEXT: load volatile
178 // CHECK-NEXT: icmp ne
179 // CHECK-NEXT: icmp ne
183 // CHECK-NEXT: load volatile
184 // CHECK-NEXT: load volatile
185 // CHECK-NEXT: store volatile
186 // CHECK-NEXT: store volatile
188 // CHECK-NEXT: load volatile
189 // CHECK-NEXT: load volatile
190 // CHECK-NEXT: store volatile
191 // CHECK-NEXT: store volatile
192 // CHECK-NEXT: store volatile
193 // CHECK-NEXT: store volatile
195 // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]], ptr getelementptr inbounds ([[CINT]], ptr @ci, i32 0, i32 1)
196 // CHECK-NEXT: store volatile [[INT]] [[T]], ptr getelementptr inbounds ([[CINT]], ptr @ci, i32 0, i32 1)
197 // CHECK-NEXT: store volatile [[INT]] [[T]], ptr getelementptr inbounds ([[CINT]], ptr @ci, i32 0, i32 1)
198 __imag ci
= __imag ci
= __imag ci
;
199 // CHECK-NEXT: load volatile
200 // CHECK-NEXT: store volatile
202 // CHECK-NEXT: load volatile
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: call void @llvm.memcpy{{.*}}, i1 true
221 // Not a use. gcc gets this wrong, it doesn't emit the copy!
224 // Not a use. gcc got this wrong in 4.2 and omitted the side effects
225 // entirely, but it is fixed in 4.4.0.
226 // CHECK-NEXT: load volatile
227 // CHECK-NEXT: store volatile
231 // A use of the real part
232 // CHECK-NEXT: load volatile
233 // CHECK-NEXT: load volatile
234 // CHECK-NEXT: store volatile
235 // CHECK-NEXT: store volatile
236 // CHECK-NEXT: sitofp
238 // Not a use, bug? gcc treats this as not a use, that's probably a bug due to
239 // tree folding ignoring volatile.
240 // CHECK-NEXT: load volatile
241 // CHECK-NEXT: load volatile
242 // CHECK-NEXT: store volatile
243 // CHECK-NEXT: store volatile
248 // CHECK-NEXT: load volatile
249 // CHECK-NEXT: store volatile
250 // CHECK-NEXT: sitofp
252 // A use. gcc treats this as not a use, that's probably a bug due to tree
253 // folding ignoring volatile.
254 // CHECK-NEXT: load volatile
255 // CHECK-NEXT: store volatile
259 // CHECK-NEXT: load volatile
260 // CHECK-NEXT: store volatile
263 // A use. gcc treats this a not a use, that's probably a bug due to tree
264 // folding ignoring volatile.
265 // CHECK-NEXT: load volatile
266 // CHECK-NEXT: store volatile
269 // A use. gcc treats this a not a use, that's probably a bug due to tree
270 // folding ignoring volatile.
271 // CHECK-NEXT: load volatile
272 // CHECK-NEXT: load volatile
273 // CHECK-NEXT: store volatile
274 // CHECK-NEXT: store volatile
278 // CHECK-NEXT: load volatile
282 // CHECK-NEXT: load volatile
283 // CHECK-NEXT: store volatile
284 // CHECK-NEXT: load volatile
287 // A use. gcc treats this as not a use, that's probably a bug due to tree
288 // folding ignoring volatile.
289 // CHECK-NEXT: load volatile
290 // CHECK-NEXT: store volatile
297 struct { int x
; } s
, s1
;
298 printf("s is at %p\n", &s
);
299 printf("s is at %p\n", &(s
= s1
));
300 printf("s.x is at %p\n", &((s
= s1
).x
));
304 extern volatile enum X x
;
305 // CHECK-LABEL: define {{.*}}void @test1()
307 extern void test1_helper(void);
309 // CHECK: call {{.*}}void @test1_helper()
310 // CHECK-NEXT: ret void
316 // CHECK: define {{.*}} @test2()
318 // CHECK: load volatile i32, ptr
319 // CHECK-NEXT: load volatile i32, ptr
320 // CHECK-NEXT: load volatile i32, ptr
321 // CHECK-NEXT: add i32
322 // CHECK-NEXT: add i32
323 // CHECK-NEXT: store volatile i32
324 // CHECK-NEXT: ret i32