1 | // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -target-cpu core2 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s |
2 | // RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -emit-pch -o %t %s |
3 | // RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s |
4 | |
5 | // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -target-cpu core2 -fopenmp-simd -x c -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s |
6 | // RUN: %clang_cc1 -fopenmp-simd -x c -triple x86_64-apple-darwin10 -target-cpu core2 -emit-pch -o %t %s |
7 | // RUN: %clang_cc1 -fopenmp-simd -x c -triple x86_64-apple-darwin10 -target-cpu core2 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s |
8 | // SIMD-ONLY0-NOT: {{__kmpc|__tgt}} |
9 | // expected-no-diagnostics |
10 | // REQUIRES: x86-registered-target |
11 | #ifndef HEADER |
12 | #define HEADER |
13 | |
14 | _Bool bv, bx; |
15 | char cv, cx; |
16 | unsigned char ucv, ucx; |
17 | short sv, sx; |
18 | unsigned short usv, usx; |
19 | int iv, ix; |
20 | unsigned int uiv, uix; |
21 | long lv, lx; |
22 | unsigned long ulv, ulx; |
23 | long long llv, llx; |
24 | unsigned long long ullv, ullx; |
25 | float fv, fx; |
26 | double dv, dx; |
27 | long double ldv, ldx; |
28 | _Complex int civ, cix; |
29 | _Complex float cfv, cfx; |
30 | _Complex double cdv, cdx; |
31 | |
32 | typedef int int4 __attribute__((__vector_size__(16))); |
33 | int4 int4x; |
34 | |
35 | struct BitFields { |
36 | int : 32; |
37 | int a : 31; |
38 | } bfx; |
39 | |
40 | struct BitFields_packed { |
41 | int : 32; |
42 | int a : 31; |
43 | } __attribute__ ((__packed__)) bfx_packed; |
44 | |
45 | struct BitFields2 { |
46 | int : 31; |
47 | int a : 1; |
48 | } bfx2; |
49 | |
50 | struct BitFields2_packed { |
51 | int : 31; |
52 | int a : 1; |
53 | } __attribute__ ((__packed__)) bfx2_packed; |
54 | |
55 | struct BitFields3 { |
56 | int : 11; |
57 | int a : 14; |
58 | } bfx3; |
59 | |
60 | struct BitFields3_packed { |
61 | int : 11; |
62 | int a : 14; |
63 | } __attribute__ ((__packed__)) bfx3_packed; |
64 | |
65 | struct BitFields4 { |
66 | short : 16; |
67 | int a: 1; |
68 | long b : 7; |
69 | } bfx4; |
70 | |
71 | struct BitFields4_packed { |
72 | short : 16; |
73 | int a: 1; |
74 | long b : 7; |
75 | } __attribute__ ((__packed__)) bfx4_packed; |
76 | |
77 | typedef float float2 __attribute__((ext_vector_type(2))); |
78 | float2 float2x; |
79 | |
80 | // Register "0" is currently an invalid register for global register variables. |
81 | // Use "esp" instead of "0". |
82 | // register int rix __asm__("0"); |
83 | register int rix __asm__("esp"); |
84 | |
85 | int main() { |
86 | // CHECK: load atomic i8, i8* |
87 | // CHECK: store i8 |
88 | #pragma omp atomic read |
89 | bv = bx; |
90 | // CHECK: load atomic i8, i8* |
91 | // CHECK: store i8 |
92 | #pragma omp atomic read |
93 | cv = cx; |
94 | // CHECK: load atomic i8, i8* |
95 | // CHECK: store i8 |
96 | #pragma omp atomic read |
97 | ucv = ucx; |
98 | // CHECK: load atomic i16, i16* |
99 | // CHECK: store i16 |
100 | #pragma omp atomic read |
101 | sv = sx; |
102 | // CHECK: load atomic i16, i16* |
103 | // CHECK: store i16 |
104 | #pragma omp atomic read |
105 | usv = usx; |
106 | // CHECK: load atomic i32, i32* |
107 | // CHECK: store i32 |
108 | #pragma omp atomic read |
109 | iv = ix; |
110 | // CHECK: load atomic i32, i32* |
111 | // CHECK: store i32 |
112 | #pragma omp atomic read |
113 | uiv = uix; |
114 | // CHECK: load atomic i64, i64* |
115 | // CHECK: store i64 |
116 | #pragma omp atomic read |
117 | lv = lx; |
118 | // CHECK: load atomic i64, i64* |
119 | // CHECK: store i64 |
120 | #pragma omp atomic read |
121 | ulv = ulx; |
122 | // CHECK: load atomic i64, i64* |
123 | // CHECK: store i64 |
124 | #pragma omp atomic read |
125 | llv = llx; |
126 | // CHECK: load atomic i64, i64* |
127 | // CHECK: store i64 |
128 | #pragma omp atomic read |
129 | ullv = ullx; |
130 | // CHECK: load atomic i32, i32* bitcast (float* |
131 | // CHECK: bitcast i32 {{.*}} to float |
132 | // CHECK: store float |
133 | #pragma omp atomic read |
134 | fv = fx; |
135 | // CHECK: load atomic i64, i64* bitcast (double* |
136 | // CHECK: bitcast i64 {{.*}} to double |
137 | // CHECK: store double |
138 | #pragma omp atomic read |
139 | dv = dx; |
140 | // CHECK: [[LD:%.+]] = load atomic i128, i128* bitcast (x86_fp80* |
141 | // CHECK: [[BITCAST:%.+]] = bitcast x86_fp80* [[LDTEMP:%.*]] to i128* |
142 | // CHECK: store i128 [[LD]], i128* [[BITCAST]] |
143 | // CHECK: [[LD:%.+]] = load x86_fp80, x86_fp80* [[LDTEMP]] |
144 | // CHECK: store x86_fp80 [[LD]] |
145 | #pragma omp atomic read |
146 | ldv = ldx; |
147 | // CHECK: call{{.*}} void @__atomic_load(i64 8, |
148 | // CHECK: store i32 |
149 | // CHECK: store i32 |
150 | #pragma omp atomic read |
151 | civ = cix; |
152 | // CHECK: call{{.*}} void @__atomic_load(i64 8, |
153 | // CHECK: store float |
154 | // CHECK: store float |
155 | #pragma omp atomic read |
156 | cfv = cfx; |
157 | // CHECK: call{{.*}} void @__atomic_load(i64 16, |
158 | // CHECK: call{{.*}} @__kmpc_flush( |
159 | // CHECK: store double |
160 | // CHECK: store double |
161 | #pragma omp atomic seq_cst read |
162 | cdv = cdx; |
163 | // CHECK: load atomic i64, i64* |
164 | // CHECK: store i8 |
165 | #pragma omp atomic read |
166 | bv = ulx; |
167 | // CHECK: load atomic i8, i8* |
168 | // CHECK: store i8 |
169 | #pragma omp atomic read |
170 | cv = bx; |
171 | // CHECK: load atomic i8, i8* |
172 | // CHECK: call{{.*}} @__kmpc_flush( |
173 | // CHECK: store i8 |
174 | #pragma omp atomic read, seq_cst |
175 | ucv = cx; |
176 | // CHECK: load atomic i64, i64* |
177 | // CHECK: store i16 |
178 | #pragma omp atomic read |
179 | sv = ulx; |
180 | // CHECK: load atomic i64, i64* |
181 | // CHECK: store i16 |
182 | #pragma omp atomic read |
183 | usv = lx; |
184 | // CHECK: load atomic i32, i32* |
185 | // CHECK: call{{.*}} @__kmpc_flush( |
186 | // CHECK: store i32 |
187 | #pragma omp atomic seq_cst, read |
188 | iv = uix; |
189 | // CHECK: load atomic i32, i32* |
190 | // CHECK: store i32 |
191 | #pragma omp atomic read |
192 | uiv = ix; |
193 | // CHECK: call{{.*}} void @__atomic_load(i64 8, |
194 | // CHECK: store i64 |
195 | #pragma omp atomic read |
196 | lv = cix; |
197 | // CHECK: load atomic i32, i32* |
198 | // CHECK: store i64 |
199 | #pragma omp atomic read |
200 | ulv = fx; |
201 | // CHECK: load atomic i64, i64* |
202 | // CHECK: store i64 |
203 | #pragma omp atomic read |
204 | llv = dx; |
205 | // CHECK: load atomic i128, i128* |
206 | // CHECK: store i64 |
207 | #pragma omp atomic read |
208 | ullv = ldx; |
209 | // CHECK: call{{.*}} void @__atomic_load(i64 8, |
210 | // CHECK: store float |
211 | #pragma omp atomic read |
212 | fv = cix; |
213 | // CHECK: load atomic i16, i16* |
214 | // CHECK: store double |
215 | #pragma omp atomic read |
216 | dv = sx; |
217 | // CHECK: load atomic i8, i8* |
218 | // CHECK: store x86_fp80 |
219 | #pragma omp atomic read |
220 | ldv = bx; |
221 | // CHECK: load atomic i8, i8* |
222 | // CHECK: store i32 |
223 | // CHECK: store i32 |
224 | #pragma omp atomic read |
225 | civ = bx; |
226 | // CHECK: load atomic i16, i16* |
227 | // CHECK: store float |
228 | // CHECK: store float |
229 | #pragma omp atomic read |
230 | cfv = usx; |
231 | // CHECK: load atomic i64, i64* |
232 | // CHECK: store double |
233 | // CHECK: store double |
234 | #pragma omp atomic read |
235 | cdv = llx; |
236 | // CHECK: [[I128VAL:%.+]] = load atomic i128, i128* bitcast (<4 x i32>* @{{.+}} to i128*) monotonic |
237 | // CHECK: [[I128PTR:%.+]] = bitcast <4 x i32>* [[LDTEMP:%.+]] to i128* |
238 | // CHECK: store i128 [[I128VAL]], i128* [[I128PTR]] |
239 | // CHECK: [[LD:%.+]] = load <4 x i32>, <4 x i32>* [[LDTEMP]] |
240 | // CHECK: extractelement <4 x i32> [[LD]] |
241 | // CHECK: store i8 |
242 | #pragma omp atomic read |
243 | bv = int4x[0]; |
244 | // CHECK: [[LD:%.+]] = load atomic i32, i32* bitcast (i8* getelementptr (i8, i8* bitcast (%{{.+}}* @{{.+}} to i8*), i64 4) to i32*) monotonic |
245 | // CHECK: store i32 [[LD]], i32* [[LDTEMP:%.+]] |
246 | // CHECK: [[LD:%.+]] = load i32, i32* [[LDTEMP]] |
247 | // CHECK: [[SHL:%.+]] = shl i32 [[LD]], 1 |
248 | // CHECK: ashr i32 [[SHL]], 1 |
249 | // CHECK: store x86_fp80 |
250 | #pragma omp atomic read |
251 | ldv = bfx.a; |
252 | // CHECK: [[LDTEMP_VOID_PTR:%.+]] = bitcast i32* [[LDTEMP:%.+]] to i8* |
253 | // CHECK: call void @__atomic_load(i64 4, i8* getelementptr (i8, i8* bitcast (%struct.BitFields_packed* @bfx_packed to i8*), i64 4), i8* [[LDTEMP_VOID_PTR]], i32 0) |
254 | // CHECK: [[LD:%.+]] = load i32, i32* [[LDTEMP]] |
255 | // CHECK: [[SHL:%.+]] = shl i32 [[LD]], 1 |
256 | // CHECK: ashr i32 [[SHL]], 1 |
257 | // CHECK: store x86_fp80 |
258 | #pragma omp atomic read |
259 | ldv = bfx_packed.a; |
260 | // CHECK: [[LD:%.+]] = load atomic i32, i32* getelementptr inbounds (%struct.BitFields2, %struct.BitFields2* @bfx2, i32 0, i32 0) monotonic |
261 | // CHECK: store i32 [[LD]], i32* [[LDTEMP:%.+]] |
262 | // CHECK: [[LD:%.+]] = load i32, i32* [[LDTEMP]] |
263 | // CHECK: ashr i32 [[LD]], 31 |
264 | // CHECK: store x86_fp80 |
265 | #pragma omp atomic read |
266 | ldv = bfx2.a; |
267 | // CHECK: [[LD:%.+]] = load atomic i8, i8* getelementptr (i8, i8* bitcast (%struct.BitFields2_packed* @bfx2_packed to i8*), i64 3) monotonic |
268 | // CHECK: store i8 [[LD]], i8* [[LDTEMP:%.+]] |
269 | // CHECK: [[LD:%.+]] = load i8, i8* [[LDTEMP]] |
270 | // CHECK: ashr i8 [[LD]], 7 |
271 | // CHECK: store x86_fp80 |
272 | #pragma omp atomic read |
273 | ldv = bfx2_packed.a; |
274 | // CHECK: [[LD:%.+]] = load atomic i32, i32* getelementptr inbounds (%struct.BitFields3, %struct.BitFields3* @bfx3, i32 0, i32 0) monotonic |
275 | // CHECK: store i32 [[LD]], i32* [[LDTEMP:%.+]] |
276 | // CHECK: [[LD:%.+]] = load i32, i32* [[LDTEMP]] |
277 | // CHECK: [[SHL:%.+]] = shl i32 [[LD]], 7 |
278 | // CHECK: ashr i32 [[SHL]], 18 |
279 | // CHECK: store x86_fp80 |
280 | #pragma omp atomic read |
281 | ldv = bfx3.a; |
282 | // CHECK: [[LDTEMP_VOID_PTR:%.+]] = bitcast i24* [[LDTEMP:%.+]] to i8* |
283 | // CHECK: call void @__atomic_load(i64 3, i8* getelementptr (i8, i8* bitcast (%struct.BitFields3_packed* @bfx3_packed to i8*), i64 1), i8* [[LDTEMP_VOID_PTR]], i32 0) |
284 | // CHECK: [[LD:%.+]] = load i24, i24* [[LDTEMP]] |
285 | // CHECK: [[SHL:%.+]] = shl i24 [[LD]], 7 |
286 | // CHECK: [[ASHR:%.+]] = ashr i24 [[SHL]], 10 |
287 | // CHECK: sext i24 [[ASHR]] to i32 |
288 | // CHECK: store x86_fp80 |
289 | #pragma omp atomic read |
290 | ldv = bfx3_packed.a; |
291 | // CHECK: [[LD:%.+]] = load atomic i64, i64* bitcast (%struct.BitFields4* @bfx4 to i64*) monotonic |
292 | // CHECK: store i64 [[LD]], i64* [[LDTEMP:%.+]] |
293 | // CHECK: [[LD:%.+]] = load i64, i64* [[LDTEMP]] |
294 | // CHECK: [[SHL:%.+]] = shl i64 [[LD]], 47 |
295 | // CHECK: [[ASHR:%.+]] = ashr i64 [[SHL]], 63 |
296 | // CHECK: trunc i64 [[ASHR]] to i32 |
297 | // CHECK: store x86_fp80 |
298 | #pragma omp atomic read |
299 | ldv = bfx4.a; |
300 | // CHECK: [[LD:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @bfx4_packed, i32 0, i32 0, i64 2) monotonic |
301 | // CHECK: store i8 [[LD]], i8* [[LDTEMP:%.+]] |
302 | // CHECK: [[LD:%.+]] = load i8, i8* [[LDTEMP]] |
303 | // CHECK: [[SHL:%.+]] = shl i8 [[LD]], 7 |
304 | // CHECK: [[ASHR:%.+]] = ashr i8 [[SHL]], 7 |
305 | // CHECK: sext i8 [[ASHR]] to i32 |
306 | // CHECK: store x86_fp80 |
307 | #pragma omp atomic read |
308 | ldv = bfx4_packed.a; |
309 | // CHECK: [[LD:%.+]] = load atomic i64, i64* bitcast (%struct.BitFields4* @bfx4 to i64*) monotonic |
310 | // CHECK: store i64 [[LD]], i64* [[LDTEMP:%.+]] |
311 | // CHECK: [[LD:%.+]] = load i64, i64* [[LDTEMP]] |
312 | // CHECK: [[SHL:%.+]] = shl i64 [[LD]], 40 |
313 | // CHECK: [[ASHR:%.+]] = ashr i64 [[SHL]], 57 |
314 | // CHECK: store x86_fp80 |
315 | #pragma omp atomic read |
316 | ldv = bfx4.b; |
317 | // CHECK: [[LD:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @bfx4_packed, i32 0, i32 0, i64 2) monotonic |
318 | // CHECK: store i8 [[LD]], i8* [[LDTEMP:%.+]] |
319 | // CHECK: [[LD:%.+]] = load i8, i8* [[LDTEMP]] |
320 | // CHECK: [[ASHR:%.+]] = ashr i8 [[LD]], 1 |
321 | // CHECK: sext i8 [[ASHR]] to i64 |
322 | // CHECK: store x86_fp80 |
323 | #pragma omp atomic read |
324 | ldv = bfx4_packed.b; |
325 | // CHECK: [[LD:%.+]] = load atomic i64, i64* bitcast (<2 x float>* @{{.+}} to i64*) monotonic |
326 | // CHECK: [[BITCAST:%.+]] = bitcast <2 x float>* [[LDTEMP:%.+]] to i64* |
327 | // CHECK: store i64 [[LD]], i64* [[BITCAST]] |
328 | // CHECK: [[LD:%.+]] = load <2 x float>, <2 x float>* [[LDTEMP]] |
329 | // CHECK: extractelement <2 x float> [[LD]] |
330 | // CHECK: store i64 |
331 | #pragma omp atomic read |
332 | ulv = float2x.x; |
333 | // CHECK: call{{.*}} i{{[0-9]+}} @llvm.read_register |
334 | // CHECK: call{{.*}} @__kmpc_flush( |
335 | // CHECK: store double |
336 | #pragma omp atomic read seq_cst |
337 | dv = rix; |
338 | return 0; |
339 | } |
340 | |
341 | #endif |
342 | |