Clang Project

clang_source_code/test/OpenMP/atomic_read_codegen.c
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;
15char cv, cx;
16unsigned char ucv, ucx;
17short sv, sx;
18unsigned short usv, usx;
19int iv, ix;
20unsigned int uiv, uix;
21long lv, lx;
22unsigned long ulv, ulx;
23long long llv, llx;
24unsigned long long ullv, ullx;
25float fv, fx;
26double dv, dx;
27long double ldv, ldx;
28_Complex int civ, cix;
29_Complex float cfv, cfx;
30_Complex double cdv, cdx;
31
32typedef int int4 __attribute__((__vector_size__(16)));
33int4 int4x;
34
35struct BitFields {
36  int : 32;
37  int a : 31;
38} bfx;
39
40struct BitFields_packed {
41  int : 32;
42  int a : 31;
43} __attribute__ ((__packed__)) bfx_packed;
44
45struct BitFields2 {
46  int : 31;
47  int a : 1;
48} bfx2;
49
50struct BitFields2_packed {
51  int : 31;
52  int a : 1;
53} __attribute__ ((__packed__)) bfx2_packed;
54
55struct BitFields3 {
56  int : 11;
57  int a : 14;
58} bfx3;
59
60struct BitFields3_packed {
61  int : 11;
62  int a : 14;
63} __attribute__ ((__packed__)) bfx3_packed;
64
65struct BitFields4 {
66  short : 16;
67  int a: 1;
68  long b : 7;
69} bfx4;
70
71struct BitFields4_packed {
72  short : 16;
73  int a: 1;
74  long b : 7;
75} __attribute__ ((__packed__)) bfx4_packed;
76
77typedef float float2 __attribute__((ext_vector_type(2)));
78float2 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");
83register int rix __asm__("esp");
84
85int 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