Clang Project

clang_source_code/test/OpenMP/atomic_write_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: store atomic i32 1, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @civ, i32 0, i32 1) monotonic,
87#pragma omp atomic write
88 __imag(civ) = 1;
89// CHECK: load i8, i8*
90// CHECK: store atomic i8
91#pragma omp atomic write
92  bx = bv;
93// CHECK: load i8, i8*
94// CHECK: store atomic i8
95#pragma omp atomic write
96  cx = cv;
97// CHECK: load i8, i8*
98// CHECK: store atomic i8
99#pragma omp atomic write
100  ucx = ucv;
101// CHECK: load i16, i16*
102// CHECK: store atomic i16
103#pragma omp atomic write
104  sx = sv;
105// CHECK: load i16, i16*
106// CHECK: store atomic i16
107#pragma omp atomic write
108  usx = usv;
109// CHECK: load i32, i32*
110// CHECK: store atomic i32
111#pragma omp atomic write
112  ix = iv;
113// CHECK: load i32, i32*
114// CHECK: store atomic i32
115#pragma omp atomic write
116  uix = uiv;
117// CHECK: load i64, i64*
118// CHECK: store atomic i64
119#pragma omp atomic write
120  lx = lv;
121// CHECK: load i64, i64*
122// CHECK: store atomic i64
123#pragma omp atomic write
124  ulx = ulv;
125// CHECK: load i64, i64*
126// CHECK: store atomic i64
127#pragma omp atomic write
128  llx = llv;
129// CHECK: load i64, i64*
130// CHECK: store atomic i64
131#pragma omp atomic write
132  ullx = ullv;
133// CHECK: load float, float*
134// CHECK: bitcast float {{.*}} to i32
135// CHECK: store atomic i32 {{.*}}, i32* bitcast (float*
136#pragma omp atomic write
137  fx = fv;
138// CHECK: load double, double*
139// CHECK: bitcast double {{.*}} to i64
140// CHECK: store atomic i64 {{.*}}, i64* bitcast (double*
141#pragma omp atomic write
142  dx = dv;
143// CHECK: [[LD:%.+]] = load x86_fp80, x86_fp80*
144// CHECK: [[BITCAST:%.+]] = bitcast x86_fp80* [[LDTEMP:%.*]] to i8*
145// CHECK: call void @llvm.memset.p0i8.i64(i8* align 16 [[BITCAST]], i8 0, i64 16, i1 false)
146// CHECK: store x86_fp80 [[LD]], x86_fp80* [[LDTEMP]]
147// CHECK: [[BITCAST:%.+]] = bitcast x86_fp80* [[LDTEMP:%.*]] to i128*
148// CHECK: [[LD:%.+]] = load i128, i128* [[BITCAST]]
149// CHECK: store atomic i128 [[LD]], i128* bitcast (x86_fp80*
150#pragma omp atomic write
151  ldx = ldv;
152// CHECK: [[REAL_VAL:%.+]] = load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @{{.*}}, i32 0, i32 0)
153// CHECK: [[IMG_VAL:%.+]] = load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @{{.*}}, i32 0, i32 1)
154// CHECK: [[TEMP_REAL_REF:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP:%.+]], i32 0, i32 0
155// CHECK: [[TEMP_IMG_REF:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 1
156// CHECK: store i32 [[REAL_VAL]], i32* [[TEMP_REAL_REF]]
157// CHECK: store i32 [[IMG_VAL]], i32* [[TEMP_IMG_REF]]
158// CHECK: [[BITCAST:%.+]] = bitcast { i32, i32 }* [[TEMP]] to i8*
159// CHECK: call void @__atomic_store(i64 8, i8* bitcast ({ i32, i32 }* @{{.*}} to i8*), i8* [[BITCAST]], i32 0)
160#pragma omp atomic write
161  cix = civ;
162// CHECK: [[REAL_VAL:%.+]] = load float, float* getelementptr inbounds ({ float, float }, { float, float }* @{{.*}}, i32 0, i32 0)
163// CHECK: [[IMG_VAL:%.+]] = load float, float* getelementptr inbounds ({ float, float }, { float, float }* @{{.*}}, i32 0, i32 1)
164// CHECK: [[TEMP_REAL_REF:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP:%.+]], i32 0, i32 0
165// CHECK: [[TEMP_IMG_REF:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP]], i32 0, i32 1
166// CHECK: store float [[REAL_VAL]], float* [[TEMP_REAL_REF]]
167// CHECK: store float [[IMG_VAL]], float* [[TEMP_IMG_REF]]
168// CHECK: [[BITCAST:%.+]] = bitcast { float, float }* [[TEMP]] to i8*
169// CHECK: call void @__atomic_store(i64 8, i8* bitcast ({ float, float }* @{{.*}} to i8*), i8* [[BITCAST]], i32 0)
170#pragma omp atomic write
171  cfx = cfv;
172// CHECK: [[REAL_VAL:%.+]] = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @{{.*}}, i32 0, i32 0)
173// CHECK: [[IMG_VAL:%.+]] = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @{{.*}}, i32 0, i32 1)
174// CHECK: [[TEMP_REAL_REF:%.+]] = getelementptr inbounds { double, double }, { double, double }* [[TEMP:%.+]], i32 0, i32 0
175// CHECK: [[TEMP_IMG_REF:%.+]] = getelementptr inbounds { double, double }, { double, double }* [[TEMP]], i32 0, i32 1
176// CHECK: store double [[REAL_VAL]], double* [[TEMP_REAL_REF]]
177// CHECK: store double [[IMG_VAL]], double* [[TEMP_IMG_REF]]
178// CHECK: [[BITCAST:%.+]] = bitcast { double, double }* [[TEMP]] to i8*
179// CHECK: call void @__atomic_store(i64 16, i8* bitcast ({ double, double }* @{{.*}} to i8*), i8* [[BITCAST]], i32 5)
180// CHECK: call{{.*}} @__kmpc_flush(
181#pragma omp atomic seq_cst write
182  cdx = cdv;
183// CHECK: load i8, i8*
184// CHECK: store atomic i64
185#pragma omp atomic write
186  ulx = bv;
187// CHECK: load i8, i8*
188// CHECK: store atomic i8
189#pragma omp atomic write
190  bx = cv;
191// CHECK: load i8, i8*
192// CHECK: store atomic i8
193// CHECK: call{{.*}} @__kmpc_flush(
194#pragma omp atomic write, seq_cst
195  cx = ucv;
196// CHECK: load i16, i16*
197// CHECK: store atomic i64
198#pragma omp atomic write
199  ulx = sv;
200// CHECK: load i16, i16*
201// CHECK: store atomic i64
202#pragma omp atomic write
203  lx = usv;
204// CHECK: load i32, i32*
205// CHECK: store atomic i32
206// CHECK: call{{.*}} @__kmpc_flush(
207#pragma omp atomic seq_cst, write
208  uix = iv;
209// CHECK: load i32, i32*
210// CHECK: store atomic i32
211#pragma omp atomic write
212  ix = uiv;
213// CHECK: load i64, i64*
214// CHECK: [[VAL:%.+]] = trunc i64 %{{.*}} to i32
215// CHECK: [[TEMP_REAL_REF:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP:%.+]], i32 0, i32 0
216// CHECK: [[TEMP_IMG_REF:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 1
217// CHECK: store i32 [[VAL]], i32* [[TEMP_REAL_REF]]
218// CHECK: store i32 0, i32* [[TEMP_IMG_REF]]
219// CHECK: [[BITCAST:%.+]] = bitcast { i32, i32 }* [[TEMP]] to i8*
220// CHECK: call void @__atomic_store(i64 8, i8* bitcast ({ i32, i32 }* @{{.+}} to i8*), i8* [[BITCAST]], i32 0)
221#pragma omp atomic write
222  cix = lv;
223// CHECK: load i64, i64*
224// CHECK: store atomic i32 %{{.+}}, i32* bitcast (float*
225#pragma omp atomic write
226  fx = ulv;
227// CHECK: load i64, i64*
228// CHECK: store atomic i64 %{{.+}}, i64* bitcast (double*
229#pragma omp atomic write
230  dx = llv;
231// CHECK: load i64, i64*
232// CHECK: [[VAL:%.+]] = uitofp i64 %{{.+}} to x86_fp80
233// CHECK: [[BITCAST:%.+]] = bitcast x86_fp80* [[TEMP:%.+]] to i8*
234// CHECK: call void @llvm.memset.p0i8.i64(i8* align 16 [[BITCAST]], i8 0, i64 16, i1 false)
235// CHECK: store x86_fp80 [[VAL]], x86_fp80* [[TEMP]]
236// CHECK: [[BITCAST:%.+]] = bitcast x86_fp80* [[TEMP]] to i128*
237// CHECK: [[VAL:%.+]] = load i128, i128* [[BITCAST]]
238// CHECK: store atomic i128 [[VAL]], i128* bitcast (x86_fp80*
239#pragma omp atomic write
240  ldx = ullv;
241// CHECK: load float, float*
242// CHECK: [[VAL:%.+]] = fptosi float %{{.*}} to i32
243// CHECK: [[TEMP_REAL_REF:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP:%.+]], i32 0, i32 0
244// CHECK: [[TEMP_IMG_REF:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[TEMP]], i32 0, i32 1
245// CHECK: store i32 [[VAL]], i32* [[TEMP_REAL_REF]]
246// CHECK: store i32 0, i32* [[TEMP_IMG_REF]]
247// CHECK: [[BITCAST:%.+]] = bitcast { i32, i32 }* [[TEMP]] to i8*
248// CHECK: call void @__atomic_store(i64 8, i8* bitcast ({ i32, i32 }* @{{.+}} to i8*), i8* [[BITCAST]], i32 0)
249#pragma omp atomic write
250  cix = fv;
251// CHECK: load double, double*
252// CHECK: store atomic i16
253#pragma omp atomic write
254  sx = dv;
255// CHECK: load x86_fp80, x86_fp80*
256// CHECK: store atomic i8
257#pragma omp atomic write
258  bx = ldv;
259// CHECK: load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @{{.+}}, i32 0, i32 0)
260// CHECK: load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @{{.+}}, i32 0, i32 1)
261// CHECK: icmp ne i32 %{{.+}}, 0
262// CHECK: icmp ne i32 %{{.+}}, 0
263// CHECK: or i1
264// CHECK: store atomic i8
265#pragma omp atomic write
266  bx = civ;
267// CHECK: load float, float* getelementptr inbounds ({ float, float }, { float, float }* @{{.*}}, i32 0, i32 0)
268// CHECK: store atomic i16
269#pragma omp atomic write
270  usx = cfv;
271// CHECK: load double, double* getelementptr inbounds ({ double, double }, { double, double }* @{{.+}}, i32 0, i32 0)
272// CHECK: store atomic i64
273#pragma omp atomic write
274  llx = cdv;
275// CHECK-DAG: [[IDX:%.+]] = load i16, i16* @{{.+}}
276// CHECK-DAG: load i8, i8*
277// CHECK-DAG: [[VEC_ITEM_VAL:%.+]] = zext i1 %{{.+}} to i32
278// CHECK: [[I128VAL:%.+]] = load atomic i128, i128* bitcast (<4 x i32>* [[DEST:@.+]] to i128*) monotonic
279// CHECK: br label %[[CONT:.+]]
280// CHECK: [[CONT]]
281// CHECK: [[OLD_I128:%.+]] = phi i128 [ [[I128VAL]], %{{.+}} ], [ [[FAILED_I128_OLD_VAL:%.+]], %[[CONT]] ]
282// CHECK: [[BITCAST:%.+]] = bitcast <4 x i32>* [[LDTEMP:%.+]] to i128*
283// CHECK: store i128 [[OLD_I128]], i128* [[BITCAST]],
284// CHECK: [[VEC_VAL:%.+]] = load <4 x i32>, <4 x i32>* [[LDTEMP]]
285// CHECK: [[NEW_VEC_VAL:%.+]] = insertelement <4 x i32> [[VEC_VAL]], i32 [[VEC_ITEM_VAL]], i16 [[IDX]]
286// CHECK: store <4 x i32> [[NEW_VEC_VAL]], <4 x i32>* [[LDTEMP]]
287// CHECK: [[NEW_I128:%.+]] = load i128, i128* [[BITCAST]]
288// CHECK: [[RES:%.+]] = cmpxchg i128* bitcast (<4 x i32>* [[DEST]] to i128*), i128 [[OLD_I128]], i128 [[NEW_I128]] monotonic monotonic
289// CHECK: [[FAILED_I128_OLD_VAL:%.+]] = extractvalue { i128, i1 } [[RES]], 0
290// CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i128, i1 } [[RES]], 1
291// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
292// CHECK: [[EXIT]]
293#pragma omp atomic write
294  int4x[sv] = bv;
295// CHECK: load x86_fp80, x86_fp80* @{{.+}}
296// CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 %{{.+}} to i32
297// CHECK: [[PREV_VALUE:%.+]] = load atomic i32, i32* bitcast (i8* getelementptr (i8, i8* bitcast (%struct.BitFields* @{{.+}} to i8*), i64 4) to i32*) monotonic
298// CHECK: br label %[[CONT:.+]]
299// CHECK: [[CONT]]
300// CHECK: [[OLD_BF_VALUE:%.+]] = phi i32 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ]
301// CHECK: [[BF_VALUE:%.+]] = and i32 [[NEW_VAL]], 2147483647
302// CHECK: [[BF_CLEAR:%.+]] = and i32 %{{.+}}, -2147483648
303// CHECK: or i32 [[BF_CLEAR]], [[BF_VALUE]]
304// CHECK: store i32 %{{.+}}, i32* [[LDTEMP:%.+]]
305// CHECK: [[NEW_BF_VALUE:%.+]] = load i32, i32* [[LDTEMP]]
306// CHECK: [[RES:%.+]] = cmpxchg i32* bitcast (i8* getelementptr (i8, i8* bitcast (%struct.BitFields* @{{.+}} to i8*), i64 4) to i32*), i32 [[OLD_BF_VALUE]], i32 [[NEW_BF_VALUE]] monotonic monotonic
307// CHECK: [[FAILED_OLD_VAL]] = extractvalue { i32, i1 } [[RES]], 0
308// CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i32, i1 } [[RES]], 1
309// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
310// CHECK: [[EXIT]]
311#pragma omp atomic write
312  bfx.a = ldv;
313// CHECK: load x86_fp80, x86_fp80* @{{.+}}
314// CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 %{{.+}} to i32
315// CHECK: [[BITCAST:%.+]] = bitcast i32* [[LDTEMP:%.+]] to i8*
316// CHECK: call void @__atomic_load(i64 4, i8* getelementptr (i8, i8* bitcast (%struct.BitFields_packed* @{{.+}} to i8*), i64 4), i8* [[BITCAST]], i32 0)
317// CHECK: br label %[[CONT:.+]]
318// CHECK: [[CONT]]
319// CHECK: [[OLD_BF_VALUE:%.+]] = load i32, i32* [[LDTEMP]],
320// CHECK: store i32 [[OLD_BF_VALUE]], i32* [[LDTEMP1:%.+]],
321// CHECK: [[OLD_BF_VALUE:%.+]] = load i32, i32* [[LDTEMP1]],
322// CHECK: [[BF_VALUE:%.+]] = and i32 [[NEW_VAL]], 2147483647
323// CHECK: [[BF_CLEAR:%.+]] = and i32 [[OLD_BF_VALUE]], -2147483648
324// CHECK: or i32 [[BF_CLEAR]], [[BF_VALUE]]
325// CHECK: store i32 %{{.+}}, i32* [[LDTEMP1]]
326// CHECK: [[BITCAST_TEMP_OLD_BF_ADDR:%.+]] = bitcast i32* [[LDTEMP]] to i8*
327// CHECK: [[BITCAST_TEMP_NEW_BF_ADDR:%.+]] = bitcast i32* [[LDTEMP1]] to i8*
328// CHECK: [[FAIL_SUCCESS:%.+]] = call zeroext i1 @__atomic_compare_exchange(i64 4, i8* getelementptr (i8, i8* bitcast (%struct.BitFields_packed* @{{.+}} to i8*), i64 4), i8* [[BITCAST_TEMP_OLD_BF_ADDR]], i8* [[BITCAST_TEMP_NEW_BF_ADDR]], i32 0, i32 0)
329// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
330// CHECK: [[EXIT]]
331#pragma omp atomic write
332  bfx_packed.a = ldv;
333// CHECK: load x86_fp80, x86_fp80* @{{.+}}
334// CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 %{{.+}} to i32
335// CHECK: [[PREV_VALUE:%.+]] = load atomic i32, i32* getelementptr inbounds (%struct.BitFields2, %struct.BitFields2* @{{.+}}, i32 0, i32 0) monotonic
336// CHECK: br label %[[CONT:.+]]
337// CHECK: [[CONT]]
338// CHECK: [[OLD_BF_VALUE:%.+]] = phi i32 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ]
339// CHECK: [[BF_AND:%.+]] = and i32 [[NEW_VAL]], 1
340// CHECK: [[BF_VALUE:%.+]] = shl i32 [[BF_AND]], 31
341// CHECK: [[BF_CLEAR:%.+]] = and i32 %{{.+}}, 2147483647
342// CHECK: or i32 [[BF_CLEAR]], [[BF_VALUE]]
343// CHECK: store i32 %{{.+}}, i32* [[LDTEMP:%.+]]
344// CHECK: [[NEW_BF_VALUE:%.+]] = load i32, i32* [[LDTEMP]]
345// CHECK: [[RES:%.+]] = cmpxchg i32* getelementptr inbounds (%struct.BitFields2, %struct.BitFields2* @{{.+}}, i32 0, i32 0), i32 [[OLD_BF_VALUE]], i32 [[NEW_BF_VALUE]] monotonic monotonic
346// CHECK: [[FAILED_OLD_VAL]] = extractvalue { i32, i1 } [[RES]], 0
347// CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i32, i1 } [[RES]], 1
348// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
349// CHECK: [[EXIT]]
350#pragma omp atomic write
351  bfx2.a = ldv;
352// CHECK: load x86_fp80, x86_fp80* @{{.+}}
353// CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 %{{.+}} to i32
354// CHECK: [[PREV_VALUE:%.+]] = load atomic i8, i8* getelementptr (i8, i8* bitcast (%struct.BitFields2_packed* @{{.+}} to i8*), i64 3) monotonic
355// CHECK: br label %[[CONT:.+]]
356// CHECK: [[CONT]]
357// CHECK: [[OLD_BF_VALUE:%.+]] = phi i8 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ]
358// CHECK: [[TRUNC:%.+]] = trunc i32 [[NEW_VAL]] to i8
359// CHECK: [[BF_AND:%.+]] = and i8 [[TRUNC]], 1
360// CHECK: [[BF_VALUE:%.+]] = shl i8 [[BF_AND]], 7
361// CHECK: [[BF_CLEAR:%.+]] = and i8 %{{.+}}, 127
362// CHECK: or i8 [[BF_CLEAR]], [[BF_VALUE]]
363// CHECK: store i8 %{{.+}}, i8* [[LDTEMP:%.+]]
364// CHECK: [[NEW_BF_VALUE:%.+]] = load i8, i8* [[LDTEMP]]
365// CHECK: [[RES:%.+]] = cmpxchg i8* getelementptr (i8, i8* bitcast (%struct.BitFields2_packed* @{{.+}} to i8*), i64 3), i8 [[OLD_BF_VALUE]], i8 [[NEW_BF_VALUE]] monotonic monotonic
366// CHECK: [[FAILED_OLD_VAL]] = extractvalue { i8, i1 } [[RES]], 0
367// CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i8, i1 } [[RES]], 1
368// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
369// CHECK: [[EXIT]]
370#pragma omp atomic write
371  bfx2_packed.a = ldv;
372// CHECK: load x86_fp80, x86_fp80* @{{.+}}
373// CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 %{{.+}} to i32
374// CHECK: [[PREV_VALUE:%.+]] = load atomic i32, i32* getelementptr inbounds (%struct.BitFields3, %struct.BitFields3* @{{.+}}, i32 0, i32 0) monotonic
375// CHECK: br label %[[CONT:.+]]
376// CHECK: [[CONT]]
377// CHECK: [[OLD_BF_VALUE:%.+]] = phi i32 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ]
378// CHECK: [[BF_AND:%.+]] = and i32 [[NEW_VAL]], 16383
379// CHECK: [[BF_VALUE:%.+]] = shl i32 [[BF_AND]], 11
380// CHECK: [[BF_CLEAR:%.+]] = and i32 %{{.+}}, -33552385
381// CHECK: or i32 [[BF_CLEAR]], [[BF_VALUE]]
382// CHECK: store i32 %{{.+}}, i32* [[LDTEMP:%.+]]
383// CHECK: [[NEW_BF_VALUE:%.+]] = load i32, i32* [[LDTEMP]]
384// CHECK: [[RES:%.+]] = cmpxchg i32* getelementptr inbounds (%struct.BitFields3, %struct.BitFields3* @{{.+}}, i32 0, i32 0), i32 [[OLD_BF_VALUE]], i32 [[NEW_BF_VALUE]] monotonic monotonic
385// CHECK: [[FAILED_OLD_VAL]] = extractvalue { i32, i1 } [[RES]], 0
386// CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i32, i1 } [[RES]], 1
387// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
388// CHECK: [[EXIT]]
389#pragma omp atomic write
390  bfx3.a = ldv;
391// CHECK: load x86_fp80, x86_fp80* @{{.+}}
392// CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 %{{.+}} to i32
393// CHECK: [[LDTEMP:%.+]] = bitcast i32* %{{.+}} to i24*
394// CHECK: [[BITCAST:%.+]] = bitcast i24* %{{.+}} to i8*
395// CHECK: call void @__atomic_load(i64 3, i8* getelementptr (i8, i8* bitcast (%struct.BitFields3_packed* @{{.+}} to i8*), i64 1), i8* [[BITCAST]], i32 0)
396// CHECK: br label %[[CONT:.+]]
397// CHECK: [[CONT]]
398// CHECK: [[OLD_VAL:%.+]] = load i24, i24* %{{.+}},
399// CHECK: store i24 [[OLD_VAL]], i24* [[TEMP:%.+]],
400// CHECK: [[TRUNC:%.+]] = trunc i32 [[NEW_VAL]] to i24
401// CHECK: [[BF_AND:%.+]] = and i24 [[TRUNC]], 16383
402// CHECK: [[BF_VALUE:%.+]] = shl i24 [[BF_AND]], 3
403// CHECK: [[BF_CLEAR:%.+]] = and i24 %{{.+}}, -131065
404// CHECK: or i24 [[BF_CLEAR]], [[BF_VALUE]]
405// CHECK: store i24 %{{.+}}, i24* [[TEMP]]
406// CHECK: [[BITCAST_TEMP_OLD_BF_ADDR:%.+]] = bitcast i24* [[LDTEMP]] to i8*
407// CHECK: [[BITCAST_TEMP_NEW_BF_ADDR:%.+]] = bitcast i24* [[TEMP]] to i8*
408// CHECK: [[FAIL_SUCCESS:%.+]] = call zeroext i1 @__atomic_compare_exchange(i64 3, i8* getelementptr (i8, i8* bitcast (%struct.BitFields3_packed* @{{.+}} to i8*), i64 1), i8* [[BITCAST_TEMP_OLD_BF_ADDR]], i8* [[BITCAST_TEMP_NEW_BF_ADDR]], i32 0, i32 0)
409// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
410// CHECK: [[EXIT]]
411#pragma omp atomic write
412  bfx3_packed.a = ldv;
413// CHECK: load x86_fp80, x86_fp80* @{{.+}}
414// CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 %{{.+}} to i32
415// CHECK: [[PREV_VALUE:%.+]] = load atomic i64, i64* bitcast (%struct.BitFields4* @{{.+}} to i64*) monotonic
416// CHECK: br label %[[CONT:.+]]
417// CHECK: [[CONT]]
418// CHECK: [[OLD_BF_VALUE:%.+]] = phi i64 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ]
419// CHECK: [[ZEXT:%.+]] = zext i32 [[NEW_VAL]] to i64
420// CHECK: [[BF_AND:%.+]] = and i64 [[ZEXT]], 1
421// CHECK: [[BF_VALUE:%.+]] = shl i64 [[BF_AND]], 16
422// CHECK: [[BF_CLEAR:%.+]] = and i64 %{{.+}}, -65537
423// CHECK: or i64 [[BF_CLEAR]], [[BF_VALUE]]
424// CHECK: store i64 %{{.+}}, i64* [[LDTEMP:%.+]]
425// CHECK: [[NEW_BF_VALUE:%.+]] = load i64, i64* [[LDTEMP]]
426// CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (%struct.BitFields4* @{{.+}} to i64*), i64 [[OLD_BF_VALUE]], i64 [[NEW_BF_VALUE]] monotonic monotonic
427// CHECK: [[FAILED_OLD_VAL]] = extractvalue { i64, i1 } [[RES]], 0
428// CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i64, i1 } [[RES]], 1
429// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
430// CHECK: [[EXIT]]
431#pragma omp atomic write
432  bfx4.a = ldv;
433// CHECK: load x86_fp80, x86_fp80* @{{.+}}
434// CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 %{{.+}} to i32
435// CHECK: [[PREV_VALUE:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2) monotonic
436// CHECK: br label %[[CONT:.+]]
437// CHECK: [[CONT]]
438// CHECK: [[OLD_BF_VALUE:%.+]] = phi i8 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ]
439// CHECK: [[TRUNC:%.+]] = trunc i32 [[NEW_VAL]] to i8
440// CHECK: [[BF_VALUE:%.+]] = and i8 [[TRUNC]], 1
441// CHECK: [[BF_CLEAR:%.+]] = and i8 %{{.+}}, -2
442// CHECK: or i8 [[BF_CLEAR]], [[BF_VALUE]]
443// CHECK: store i8 %{{.+}}, i8* [[LDTEMP:%.+]]
444// CHECK: [[NEW_BF_VALUE:%.+]] = load i8, i8* [[LDTEMP]]
445// CHECK: [[RES:%.+]] = cmpxchg i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2), i8 [[OLD_BF_VALUE]], i8 [[NEW_BF_VALUE]] monotonic monotonic
446// CHECK: [[FAILED_OLD_VAL]] = extractvalue { i8, i1 } [[RES]], 0
447// CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i8, i1 } [[RES]], 1
448// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
449// CHECK: [[EXIT]]
450#pragma omp atomic write
451  bfx4_packed.a = ldv;
452// CHECK: load x86_fp80, x86_fp80* @{{.+}}
453// CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 %{{.+}} to i64
454// CHECK: [[PREV_VALUE:%.+]] = load atomic i64, i64* bitcast (%struct.BitFields4* @{{.+}} to i64*) monotonic
455// CHECK: br label %[[CONT:.+]]
456// CHECK: [[CONT]]
457// CHECK: [[OLD_BF_VALUE:%.+]] = phi i64 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ]
458// CHECK: [[BF_AND:%.+]] = and i64 [[NEW_VAL]], 127
459// CHECK: [[BF_VALUE:%.+]] = shl i64 [[BF_AND]], 17
460// CHECK: [[BF_CLEAR:%.+]] = and i64 %{{.+}}, -16646145
461// CHECK: or i64 [[BF_CLEAR]], [[BF_VALUE]]
462// CHECK: store i64 %{{.+}}, i64* [[LDTEMP:%.+]]
463// CHECK: [[NEW_BF_VALUE:%.+]] = load i64, i64* [[LDTEMP]]
464// CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (%struct.BitFields4* @{{.+}} to i64*), i64 [[OLD_BF_VALUE]], i64 [[NEW_BF_VALUE]] monotonic monotonic
465// CHECK: [[FAILED_OLD_VAL]] = extractvalue { i64, i1 } [[RES]], 0
466// CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i64, i1 } [[RES]], 1
467// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
468// CHECK: [[EXIT]]
469#pragma omp atomic write
470  bfx4.b = ldv;
471// CHECK: load x86_fp80, x86_fp80* @{{.+}}
472// CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 %{{.+}} to i64
473// CHECK: [[PREV_VALUE:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2) monotonic
474// CHECK: br label %[[CONT:.+]]
475// CHECK: [[CONT]]
476// CHECK: [[OLD_BF_VALUE:%.+]] = phi i8 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ]
477// CHECK: [[TRUNC:%.+]] = trunc i64 [[NEW_VAL]] to i8
478// CHECK: [[BF_AND:%.+]] = and i8 [[TRUNC]], 127
479// CHECK: [[BF_VALUE:%.+]] = shl i8 [[BF_AND]], 1
480// CHECK: [[BF_CLEAR:%.+]] = and i8 %{{.+}}, 1
481// CHECK: or i8 [[BF_CLEAR]], [[BF_VALUE]]
482// CHECK: store i8 %{{.+}}, i8* [[LDTEMP:%.+]]
483// CHECK: [[NEW_BF_VALUE:%.+]] = load i8, i8* [[LDTEMP]]
484// CHECK: [[RES:%.+]] = cmpxchg i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2), i8 [[OLD_BF_VALUE]], i8 [[NEW_BF_VALUE]] monotonic monotonic
485// CHECK: [[FAILED_OLD_VAL]] = extractvalue { i8, i1 } [[RES]], 0
486// CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i8, i1 } [[RES]], 1
487// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
488// CHECK: [[EXIT]]
489#pragma omp atomic write
490  bfx4_packed.b = ldv;
491// CHECK: load i64, i64*
492// CHECK: [[VEC_ITEM_VAL:%.+]] = uitofp i64 %{{.+}} to float
493// CHECK: [[I64VAL:%.+]] = load atomic i64, i64* bitcast (<2 x float>* [[DEST:@.+]] to i64*) monotonic
494// CHECK: br label %[[CONT:.+]]
495// CHECK: [[CONT]]
496// CHECK: [[OLD_I64:%.+]] = phi i64 [ [[I64VAL]], %{{.+}} ], [ [[FAILED_I64_OLD_VAL:%.+]], %[[CONT]] ]
497// CHECK: [[BITCAST:%.+]] = bitcast <2 x float>* [[LDTEMP:%.+]] to i64*
498// CHECK: store i64 [[OLD_I64]], i64* [[BITCAST]],
499// CHECK: [[VEC_VAL:%.+]] = load <2 x float>, <2 x float>* [[LDTEMP]]
500// CHECK: [[NEW_VEC_VAL:%.+]] = insertelement <2 x float> [[VEC_VAL]], float [[VEC_ITEM_VAL]], i64 0
501// CHECK: store <2 x float> [[NEW_VEC_VAL]], <2 x float>* [[LDTEMP]]
502// CHECK: [[NEW_I64:%.+]] = load i64, i64* [[BITCAST]]
503// CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (<2 x float>* [[DEST]] to i64*), i64 [[OLD_I64]], i64 [[NEW_I64]] monotonic monotonic
504// CHECK: [[FAILED_I64_OLD_VAL:%.+]] = extractvalue { i64, i1 } [[RES]], 0
505// CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i64, i1 } [[RES]], 1
506// CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
507// CHECK: [[EXIT]]
508#pragma omp atomic write
509  float2x.x = ulv;
510// CHECK: call i32 @llvm.read_register.i32(
511// CHECK: sitofp i32 %{{.+}} to double
512// CHECK: bitcast double %{{.+}} to i64
513// CHECK: store atomic i64 %{{.+}}, i64* bitcast (double* @{{.+}} to i64*) seq_cst
514// CHECK: call{{.*}} @__kmpc_flush(
515#pragma omp atomic write seq_cst
516  dv = rix;
517  return 0;
518}
519
520#endif
521