1*67e74705SXin Li // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
2*67e74705SXin Li // RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -emit-pch -o %t %s
3*67e74705SXin Li // RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
4*67e74705SXin Li // expected-no-diagnostics
5*67e74705SXin Li // REQUIRES: x86-registered-target
6*67e74705SXin Li #ifndef HEADER
7*67e74705SXin Li #define HEADER
8*67e74705SXin Li
9*67e74705SXin Li _Bool bv, bx;
10*67e74705SXin Li char cv, cx;
11*67e74705SXin Li unsigned char ucv, ucx;
12*67e74705SXin Li short sv, sx;
13*67e74705SXin Li unsigned short usv, usx;
14*67e74705SXin Li int iv, ix;
15*67e74705SXin Li unsigned int uiv, uix;
16*67e74705SXin Li long lv, lx;
17*67e74705SXin Li unsigned long ulv, ulx;
18*67e74705SXin Li long long llv, llx;
19*67e74705SXin Li unsigned long long ullv, ullx;
20*67e74705SXin Li float fv, fx;
21*67e74705SXin Li double dv, dx;
22*67e74705SXin Li long double ldv, ldx;
23*67e74705SXin Li _Complex int civ, cix;
24*67e74705SXin Li _Complex float cfv, cfx;
25*67e74705SXin Li _Complex double cdv, cdx;
26*67e74705SXin Li
27*67e74705SXin Li typedef int int4 __attribute__((__vector_size__(16)));
28*67e74705SXin Li int4 int4x;
29*67e74705SXin Li
30*67e74705SXin Li struct BitFields {
31*67e74705SXin Li int : 32;
32*67e74705SXin Li int a : 31;
33*67e74705SXin Li } bfx;
34*67e74705SXin Li
35*67e74705SXin Li struct BitFields_packed {
36*67e74705SXin Li int : 32;
37*67e74705SXin Li int a : 31;
38*67e74705SXin Li } __attribute__ ((__packed__)) bfx_packed;
39*67e74705SXin Li
40*67e74705SXin Li struct BitFields2 {
41*67e74705SXin Li int : 31;
42*67e74705SXin Li int a : 1;
43*67e74705SXin Li } bfx2;
44*67e74705SXin Li
45*67e74705SXin Li struct BitFields2_packed {
46*67e74705SXin Li int : 31;
47*67e74705SXin Li int a : 1;
48*67e74705SXin Li } __attribute__ ((__packed__)) bfx2_packed;
49*67e74705SXin Li
50*67e74705SXin Li struct BitFields3 {
51*67e74705SXin Li int : 11;
52*67e74705SXin Li int a : 14;
53*67e74705SXin Li } bfx3;
54*67e74705SXin Li
55*67e74705SXin Li struct BitFields3_packed {
56*67e74705SXin Li int : 11;
57*67e74705SXin Li int a : 14;
58*67e74705SXin Li } __attribute__ ((__packed__)) bfx3_packed;
59*67e74705SXin Li
60*67e74705SXin Li struct BitFields4 {
61*67e74705SXin Li short : 16;
62*67e74705SXin Li int a: 1;
63*67e74705SXin Li long b : 7;
64*67e74705SXin Li } bfx4;
65*67e74705SXin Li
66*67e74705SXin Li struct BitFields4_packed {
67*67e74705SXin Li short : 16;
68*67e74705SXin Li int a: 1;
69*67e74705SXin Li long b : 7;
70*67e74705SXin Li } __attribute__ ((__packed__)) bfx4_packed;
71*67e74705SXin Li
72*67e74705SXin Li typedef float float2 __attribute__((ext_vector_type(2)));
73*67e74705SXin Li float2 float2x;
74*67e74705SXin Li
75*67e74705SXin Li // Register "0" is currently an invalid register for global register variables.
76*67e74705SXin Li // Use "esp" instead of "0".
77*67e74705SXin Li // register int rix __asm__("0");
78*67e74705SXin Li register int rix __asm__("esp");
79*67e74705SXin Li
main()80*67e74705SXin Li int main() {
81*67e74705SXin Li // CHECK: [[PREV:%.+]] = atomicrmw add i8* @{{.+}}, i8 1 monotonic
82*67e74705SXin Li // CHECK: store i8 [[PREV]], i8* @{{.+}},
83*67e74705SXin Li #pragma omp atomic capture
84*67e74705SXin Li bv = bx++;
85*67e74705SXin Li // CHECK: atomicrmw add i8* @{{.+}}, i8 1 monotonic
86*67e74705SXin Li // CHECK: add nsw i32 %{{.+}}, 1
87*67e74705SXin Li // CHECK: store i8 %{{.+}}, i8* @{{.+}},
88*67e74705SXin Li #pragma omp atomic capture
89*67e74705SXin Li cv = ++cx;
90*67e74705SXin Li // CHECK: [[PREV:%.+]] = atomicrmw sub i8* @{{.+}}, i8 1 monotonic
91*67e74705SXin Li // CHECK: store i8 [[PREV]], i8* @{{.+}},
92*67e74705SXin Li #pragma omp atomic capture
93*67e74705SXin Li ucv = ucx--;
94*67e74705SXin Li // CHECK: atomicrmw sub i16* @{{.+}}, i16 1 monotonic
95*67e74705SXin Li // CHECK: sub nsw i32 %{{.+}}, 1
96*67e74705SXin Li // CHECK: store i16 %{{.+}}, i16* @{{.+}},
97*67e74705SXin Li #pragma omp atomic capture
98*67e74705SXin Li sv = --sx;
99*67e74705SXin Li // CHECK: [[USV:%.+]] = load i16, i16* @{{.+}},
100*67e74705SXin Li // CHECK: [[EXPR:%.+]] = zext i16 [[USV]] to i32
101*67e74705SXin Li // CHECK: [[X:%.+]] = load atomic i16, i16* [[X_ADDR:@.+]] monotonic
102*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
103*67e74705SXin Li // CHECK: [[CONT]]
104*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = phi i16 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
105*67e74705SXin Li // CHECK: [[CONV:%.+]] = zext i16 [[EXPECTED]] to i32
106*67e74705SXin Li // CHECK: [[ADD:%.+]] = add nsw i32 [[CONV]], [[EXPR]]
107*67e74705SXin Li // CHECK: [[DESIRED_CALC:%.+]] = trunc i32 [[ADD]] to i16
108*67e74705SXin Li // CHECK: store i16 [[DESIRED_CALC]], i16* [[TEMP:%.+]],
109*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = load i16, i16* [[TEMP]],
110*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i16* [[X_ADDR]], i16 [[EXPECTED]], i16 [[DESIRED]] monotonic monotonic
111*67e74705SXin Li // CHECK: [[OLD_X]] = extractvalue { i16, i1 } [[RES]], 0
112*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i16, i1 } [[RES]], 1
113*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
114*67e74705SXin Li // CHECK: [[EXIT]]
115*67e74705SXin Li // CHECK: store i16 [[DESIRED_CALC]], i16* @{{.+}},
116*67e74705SXin Li #pragma omp atomic capture
117*67e74705SXin Li sv = usx += usv;
118*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load i32, i32* @{{.+}},
119*67e74705SXin Li // CHECK: [[X:%.+]] = load atomic i32, i32* [[X_ADDR:@.+]] monotonic
120*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
121*67e74705SXin Li // CHECK: [[CONT]]
122*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = phi i32 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
123*67e74705SXin Li // CHECK: [[DESIRED_CALC:%.+]] = mul nsw i32 [[EXPECTED]], [[EXPR]]
124*67e74705SXin Li // CHECK: store i32 [[DESIRED_CALC]], i32* [[TEMP:%.+]],
125*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = load i32, i32* [[TEMP]],
126*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i32* [[X_ADDR]], i32 [[EXPECTED]], i32 [[DESIRED]] monotonic monotonic
127*67e74705SXin Li // CHECK: [[OLD_X]] = extractvalue { i32, i1 } [[RES]], 0
128*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i32, i1 } [[RES]], 1
129*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
130*67e74705SXin Li // CHECK: [[EXIT]]
131*67e74705SXin Li // CHECK: store i32 [[DESIRED_CALC]], i32* @{{.+}},
132*67e74705SXin Li #pragma omp atomic capture
133*67e74705SXin Li uiv = ix *= iv;
134*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load i32, i32* @{{.+}},
135*67e74705SXin Li // CHECK: [[PREV:%.+]] = atomicrmw sub i32* @{{.+}}, i32 [[EXPR]] monotonic
136*67e74705SXin Li // CHECK: store i32 [[PREV]], i32* @{{.+}},
137*67e74705SXin Li #pragma omp atomic capture
138*67e74705SXin Li {iv = uix; uix -= uiv;}
139*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load i32, i32* @{{.+}},
140*67e74705SXin Li // CHECK: [[X:%.+]] = load atomic i32, i32* [[X_ADDR:@.+]] monotonic
141*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
142*67e74705SXin Li // CHECK: [[CONT]]
143*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = phi i32 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
144*67e74705SXin Li // CHECK: [[DESIRED_CALC:%.+]] = shl i32 [[EXPECTED]], [[EXPR]]
145*67e74705SXin Li // CHECK: store i32 [[DESIRED_CALC]], i32* [[TEMP:%.+]],
146*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = load i32, i32* [[TEMP]],
147*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i32* [[X_ADDR]], i32 [[EXPECTED]], i32 [[DESIRED]] monotonic monotonic
148*67e74705SXin Li // CHECK: [[OLD_X]] = extractvalue { i32, i1 } [[RES]], 0
149*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i32, i1 } [[RES]], 1
150*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
151*67e74705SXin Li // CHECK: [[EXIT]]
152*67e74705SXin Li // CHECK: store i32 [[DESIRED_CALC]], i32* @{{.+}},
153*67e74705SXin Li #pragma omp atomic capture
154*67e74705SXin Li {ix <<= iv; uiv = ix;}
155*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load i32, i32* @{{.+}},
156*67e74705SXin Li // CHECK: [[X:%.+]] = load atomic i32, i32* [[X_ADDR:@.+]] monotonic
157*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
158*67e74705SXin Li // CHECK: [[CONT]]
159*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = phi i32 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
160*67e74705SXin Li // CHECK: [[DESIRED_CALC:%.+]] = lshr i32 [[EXPECTED]], [[EXPR]]
161*67e74705SXin Li // CHECK: store i32 [[DESIRED_CALC]], i32* [[TEMP:%.+]],
162*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = load i32, i32* [[TEMP]],
163*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i32* [[X_ADDR]], i32 [[EXPECTED]], i32 [[DESIRED]] monotonic monotonic
164*67e74705SXin Li // CHECK: [[OLD_X]] = extractvalue { i32, i1 } [[RES]], 0
165*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i32, i1 } [[RES]], 1
166*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
167*67e74705SXin Li // CHECK: [[EXIT]]
168*67e74705SXin Li // CHECK: store i32 [[DESIRED_CALC]], i32* @{{.+}},
169*67e74705SXin Li #pragma omp atomic capture
170*67e74705SXin Li iv = uix >>= uiv;
171*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load i64, i64* @{{.+}},
172*67e74705SXin Li // CHECK: [[X:%.+]] = load atomic i64, i64* [[X_ADDR:@.+]] monotonic
173*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
174*67e74705SXin Li // CHECK: [[CONT]]
175*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = phi i64 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
176*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = sdiv i64 [[EXPECTED]], [[EXPR]]
177*67e74705SXin Li // CHECK: store i64 [[DESIRED]], i64* [[TEMP:%.+]],
178*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = load i64, i64* [[TEMP]],
179*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i64* [[X_ADDR]], i64 [[EXPECTED]], i64 [[DESIRED]] monotonic monotonic
180*67e74705SXin Li // CHECK: [[OLD_X]] = extractvalue { i64, i1 } [[RES]], 0
181*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i64, i1 } [[RES]], 1
182*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
183*67e74705SXin Li // CHECK: [[EXIT]]
184*67e74705SXin Li // CHECK: store i64 [[EXPECTED]], i64* @{{.+}},
185*67e74705SXin Li #pragma omp atomic capture
186*67e74705SXin Li {ulv = lx; lx /= lv;}
187*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load i64, i64* @{{.+}},
188*67e74705SXin Li // CHECK: [[OLD:%.+]] = atomicrmw and i64* @{{.+}}, i64 [[EXPR]] monotonic
189*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = and i64 [[OLD]], [[EXPR]]
190*67e74705SXin Li // CHECK: store i64 [[DESIRED]], i64* @{{.+}},
191*67e74705SXin Li #pragma omp atomic capture
192*67e74705SXin Li {ulx &= ulv; lv = ulx;}
193*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load i64, i64* @{{.+}},
194*67e74705SXin Li // CHECK: [[OLD:%.+]] = atomicrmw xor i64* @{{.+}}, i64 [[EXPR]] monotonic
195*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = xor i64 [[OLD]], [[EXPR]]
196*67e74705SXin Li // CHECK: store i64 [[DESIRED]], i64* @{{.+}},
197*67e74705SXin Li #pragma omp atomic capture
198*67e74705SXin Li ullv = llx ^= llv;
199*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load i64, i64* @{{.+}},
200*67e74705SXin Li // CHECK: [[OLD:%.+]] = atomicrmw or i64* @{{.+}}, i64 [[EXPR]] monotonic
201*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = or i64 [[OLD]], [[EXPR]]
202*67e74705SXin Li // CHECK: store i64 [[DESIRED]], i64* @{{.+}},
203*67e74705SXin Li #pragma omp atomic capture
204*67e74705SXin Li llv = ullx |= ullv;
205*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load float, float* @{{.+}},
206*67e74705SXin Li // CHECK: [[X:%.+]] = load atomic i32, i32* bitcast (float* [[X_ADDR:@.+]] to i32*) monotonic
207*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
208*67e74705SXin Li // CHECK: [[CONT]]
209*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = phi i32 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
210*67e74705SXin Li // CHECK: [[TEMP_I:%.+]] = bitcast float* [[TEMP:%.+]] to i32*
211*67e74705SXin Li // CHECK: [[OLD:%.+]] = bitcast i32 [[EXPECTED]] to float
212*67e74705SXin Li // CHECK: [[ADD:%.+]] = fadd float [[OLD]], [[EXPR]]
213*67e74705SXin Li // CHECK: store float [[ADD]], float* [[TEMP]],
214*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = load i32, i32* [[TEMP_I]],
215*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i32* bitcast (float* [[X_ADDR]] to i32*), i32 [[EXPECTED]], i32 [[DESIRED]] monotonic monotonic
216*67e74705SXin Li // CHECK: [[OLD_X:%.+]] = extractvalue { i32, i1 } [[RES]], 0
217*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i32, i1 } [[RES]], 1
218*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
219*67e74705SXin Li // CHECK: [[EXIT]]
220*67e74705SXin Li // CHECK: [[CAST:%.+]] = fpext float [[ADD]] to double
221*67e74705SXin Li // CHECK: store double [[CAST]], double* @{{.+}},
222*67e74705SXin Li #pragma omp atomic capture
223*67e74705SXin Li dv = fx = fx + fv;
224*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load double, double* @{{.+}},
225*67e74705SXin Li // CHECK: [[X:%.+]] = load atomic i64, i64* bitcast (double* [[X_ADDR:@.+]] to i64*) monotonic
226*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
227*67e74705SXin Li // CHECK: [[CONT]]
228*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = phi i64 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
229*67e74705SXin Li // CHECK: [[TEMP_I:%.+]] = bitcast double* [[TEMP:%.+]] to i64*
230*67e74705SXin Li // CHECK: [[OLD:%.+]] = bitcast i64 [[EXPECTED]] to double
231*67e74705SXin Li // CHECK: [[SUB:%.+]] = fsub double [[EXPR]], [[OLD]]
232*67e74705SXin Li // CHECK: store double [[SUB]], double* [[TEMP]],
233*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = load i64, i64* [[TEMP_I]],
234*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (double* [[X_ADDR]] to i64*), i64 [[EXPECTED]], i64 [[DESIRED]] monotonic monotonic
235*67e74705SXin Li // CHECK: [[OLD_X:%.+]] = extractvalue { i64, i1 } [[RES]], 0
236*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i64, i1 } [[RES]], 1
237*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
238*67e74705SXin Li // CHECK: [[EXIT]]
239*67e74705SXin Li // CHECK: [[CAST:%.+]] = fptrunc double [[OLD]] to float
240*67e74705SXin Li // CHECK: store float [[CAST]], float* @{{.+}},
241*67e74705SXin Li #pragma omp atomic capture
242*67e74705SXin Li {fv = dx; dx = dv - dx;}
243*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}},
244*67e74705SXin Li // CHECK: [[X:%.+]] = load atomic i128, i128* bitcast (x86_fp80* [[X_ADDR:@.+]] to i128*) monotonic
245*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
246*67e74705SXin Li // CHECK: [[CONT]]
247*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = phi i128 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
248*67e74705SXin Li // CHECK: [[BITCAST:%.+]] = bitcast x86_fp80* [[TEMP:%.+]] to i128*
249*67e74705SXin Li // CHECK: store i128 [[EXPECTED]], i128* [[BITCAST]]
250*67e74705SXin Li // CHECK: [[BITCAST1:%.+]] = bitcast x86_fp80* [[TEMP1:%.+]] to i128*
251*67e74705SXin Li // CHECK: store i128 [[EXPECTED]], i128* [[BITCAST1]]
252*67e74705SXin Li // CHECK: [[OLD:%.+]] = load x86_fp80, x86_fp80* [[TEMP1]]
253*67e74705SXin Li // CHECK: [[MUL:%.+]] = fmul x86_fp80 [[OLD]], [[EXPR]]
254*67e74705SXin Li // CHECK: store x86_fp80 [[MUL]], x86_fp80* [[TEMP]]
255*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = load i128, i128* [[BITCAST]]
256*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i128* bitcast (x86_fp80* [[X_ADDR]] to i128*), i128 [[EXPECTED]], i128 [[DESIRED]] monotonic monotonic
257*67e74705SXin Li // CHECK: [[OLD_X:%.+]] = extractvalue { i128, i1 } [[RES]], 0
258*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i128, i1 } [[RES]], 1
259*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
260*67e74705SXin Li // CHECK: [[EXIT]]
261*67e74705SXin Li // CHECK: [[CAST:%.+]] = fptrunc x86_fp80 [[MUL]] to double
262*67e74705SXin Li // CHECK: store double [[CAST]], double* @{{.+}},
263*67e74705SXin Li #pragma omp atomic capture
264*67e74705SXin Li {ldx = ldx * ldv; dv = ldx;}
265*67e74705SXin Li // CHECK: [[EXPR_RE:%.+]] = load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @{{.+}}, i32 0, i32 0)
266*67e74705SXin Li // CHECK: [[EXPR_IM:%.+]] = load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @{{.+}}, i32 0, i32 1)
267*67e74705SXin Li // CHECK: [[BITCAST:%.+]] = bitcast { i32, i32 }* [[EXPECTED_ADDR:%.+]] to i8*
268*67e74705SXin Li // CHECK: call void @__atomic_load(i64 8, i8* bitcast ({ i32, i32 }* [[X_ADDR:@.+]] to i8*), i8* [[BITCAST]], i32 0)
269*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
270*67e74705SXin Li // CHECK: [[CONT]]
271*67e74705SXin Li // CHECK: [[LD_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[EXPECTED_ADDR]], i32 0, i32 0
272*67e74705SXin Li // CHECK: [[LD_RE:%.+]] = load i32, i32* [[LD_RE_ADDR]]
273*67e74705SXin Li // CHECK: [[LD_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[EXPECTED_ADDR]], i32 0, i32 1
274*67e74705SXin Li // CHECK: [[LD_IM:%.+]] = load i32, i32* [[LD_IM_ADDR]]
275*67e74705SXin Li // <Skip checks for complex calculations>
276*67e74705SXin Li // CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[DESIRED_ADDR:%.+]], i32 0, i32 0
277*67e74705SXin Li // CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[DESIRED_ADDR]], i32 0, i32 1
278*67e74705SXin Li // CHECK: store i32 [[NEW_RE:%.+]], i32* [[X_RE_ADDR]]
279*67e74705SXin Li // CHECK: store i32 [[NEW_IM:%.+]], i32* [[X_IM_ADDR]]
280*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = bitcast { i32, i32 }* [[EXPECTED_ADDR]] to i8*
281*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = bitcast { i32, i32 }* [[DESIRED_ADDR]] to i8*
282*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = call zeroext i1 @__atomic_compare_exchange(i64 8, i8* bitcast ({ i32, i32 }* [[X_ADDR]] to i8*), i8* [[EXPECTED]], i8* [[DESIRED]], i32 0, i32 0)
283*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
284*67e74705SXin Li // CHECK: [[EXIT]]
285*67e74705SXin Li // CHECK: [[RE_CAST:%.+]] = sitofp i32 [[NEW_RE]] to float
286*67e74705SXin Li // CHECK: [[IM_CAST:%.+]] = sitofp i32 [[NEW_IM]] to float
287*67e74705SXin Li // CHECK: store float [[RE_CAST]], float* getelementptr inbounds ({ float, float }, { float, float }* @{{.+}}, i32 0, i32 0),
288*67e74705SXin Li // CHECK: store float [[IM_CAST]], float* getelementptr inbounds ({ float, float }, { float, float }* @{{.+}}, i32 0, i32 1),
289*67e74705SXin Li #pragma omp atomic capture
290*67e74705SXin Li cfv = cix = civ / cix;
291*67e74705SXin Li // CHECK: [[EXPR_RE:%.+]] = load float, float* getelementptr inbounds ({ float, float }, { float, float }* @{{.+}}, i32 0, i32 0)
292*67e74705SXin Li // CHECK: [[EXPR_IM:%.+]] = load float, float* getelementptr inbounds ({ float, float }, { float, float }* @{{.+}}, i32 0, i32 1)
293*67e74705SXin Li // CHECK: [[BITCAST:%.+]] = bitcast { float, float }* [[EXPECTED_ADDR:%.+]] to i8*
294*67e74705SXin Li // CHECK: call void @__atomic_load(i64 8, i8* bitcast ({ float, float }* [[X_ADDR:@.+]] to i8*), i8* [[BITCAST]], i32 0)
295*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
296*67e74705SXin Li // CHECK: [[CONT]]
297*67e74705SXin Li // CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[EXPECTED_ADDR]], i32 0, i32 0
298*67e74705SXin Li // CHECK: [[X_RE_OLD:%.+]] = load float, float* [[X_RE_ADDR]]
299*67e74705SXin Li // CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[EXPECTED_ADDR]], i32 0, i32 1
300*67e74705SXin Li // CHECK: [[X_IM_OLD:%.+]] = load float, float* [[X_IM_ADDR]]
301*67e74705SXin Li // <Skip checks for complex calculations>
302*67e74705SXin Li // CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[DESIRED_ADDR:%.+]], i32 0, i32 0
303*67e74705SXin Li // CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[DESIRED_ADDR]], i32 0, i32 1
304*67e74705SXin Li // CHECK: store float [[NEW_RE:%.+]], float* [[X_RE_ADDR]]
305*67e74705SXin Li // CHECK: store float [[NEW_IM:%.+]], float* [[X_IM_ADDR]]
306*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = bitcast { float, float }* [[EXPECTED_ADDR]] to i8*
307*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = bitcast { float, float }* [[DESIRED_ADDR]] to i8*
308*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = call zeroext i1 @__atomic_compare_exchange(i64 8, i8* bitcast ({ float, float }* [[X_ADDR]] to i8*), i8* [[EXPECTED]], i8* [[DESIRED]], i32 0, i32 0)
309*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
310*67e74705SXin Li // CHECK: [[EXIT]]
311*67e74705SXin Li // CHECK: [[RE_CAST:%.+]] = fptosi float [[X_RE_OLD]] to i32
312*67e74705SXin Li // CHECK: [[IM_CAST:%.+]] = fptosi float [[X_IM_OLD]] to i32
313*67e74705SXin Li // CHECK: store i32 [[RE_CAST]], i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @{{.+}}, i32 0, i32 0),
314*67e74705SXin Li // CHECK: store i32 [[IM_CAST]], i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @{{.+}}, i32 0, i32 1),
315*67e74705SXin Li #pragma omp atomic capture
316*67e74705SXin Li {civ = cfx; cfx = cfv + cfx;}
317*67e74705SXin Li // CHECK: [[EXPR_RE:%.+]] = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @{{.+}}, i32 0, i32 0)
318*67e74705SXin Li // CHECK: [[EXPR_IM:%.+]] = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @{{.+}}, i32 0, i32 1)
319*67e74705SXin Li // CHECK: [[BITCAST:%.+]] = bitcast { double, double }* [[EXPECTED_ADDR:%.+]] to i8*
320*67e74705SXin Li // CHECK: call void @__atomic_load(i64 16, i8* bitcast ({ double, double }* [[X_ADDR:@.+]] to i8*), i8* [[BITCAST]], i32 5)
321*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
322*67e74705SXin Li // CHECK: [[CONT]]
323*67e74705SXin Li // CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { double, double }, { double, double }* [[EXPECTED_ADDR]], i32 0, i32 0
324*67e74705SXin Li // CHECK: [[X_RE:%.+]] = load double, double* [[X_RE_ADDR]]
325*67e74705SXin Li // CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { double, double }, { double, double }* [[EXPECTED_ADDR]], i32 0, i32 1
326*67e74705SXin Li // CHECK: [[X_IM:%.+]] = load double, double* [[X_IM_ADDR]]
327*67e74705SXin Li // <Skip checks for complex calculations>
328*67e74705SXin Li // CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { double, double }, { double, double }* [[DESIRED_ADDR:%.+]], i32 0, i32 0
329*67e74705SXin Li // CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { double, double }, { double, double }* [[DESIRED_ADDR]], i32 0, i32 1
330*67e74705SXin Li // CHECK: store double [[NEW_RE:%.+]], double* [[X_RE_ADDR]]
331*67e74705SXin Li // CHECK: store double [[NEW_IM:%.+]], double* [[X_IM_ADDR]]
332*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = bitcast { double, double }* [[EXPECTED_ADDR]] to i8*
333*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = bitcast { double, double }* [[DESIRED_ADDR]] to i8*
334*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = call zeroext i1 @__atomic_compare_exchange(i64 16, i8* bitcast ({ double, double }* [[X_ADDR]] to i8*), i8* [[EXPECTED]], i8* [[DESIRED]], i32 5, i32 5)
335*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
336*67e74705SXin Li // CHECK: [[EXIT]]
337*67e74705SXin Li // CHECK: [[RE_CAST:%.+]] = fptrunc double [[NEW_RE]] to float
338*67e74705SXin Li // CHECK: [[IM_CAST:%.+]] = fptrunc double [[NEW_IM]] to float
339*67e74705SXin Li // CHECK: store float [[RE_CAST]], float* getelementptr inbounds ({ float, float }, { float, float }* @{{.+}}, i32 0, i32 0),
340*67e74705SXin Li // CHECK: store float [[IM_CAST]], float* getelementptr inbounds ({ float, float }, { float, float }* @{{.+}}, i32 0, i32 1),
341*67e74705SXin Li // CHECK: call{{.*}} @__kmpc_flush(
342*67e74705SXin Li #pragma omp atomic capture seq_cst
343*67e74705SXin Li {cdx = cdx - cdv; cfv = cdx;}
344*67e74705SXin Li // CHECK: [[BV:%.+]] = load i8, i8* @{{.+}}
345*67e74705SXin Li // CHECK: [[BOOL:%.+]] = trunc i8 [[BV]] to i1
346*67e74705SXin Li // CHECK: [[EXPR:%.+]] = zext i1 [[BOOL]] to i64
347*67e74705SXin Li // CHECK: [[OLD:%.+]] = atomicrmw and i64* @{{.+}}, i64 [[EXPR]] monotonic
348*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = and i64 [[OLD]], [[EXPR]]
349*67e74705SXin Li // CHECK: store i64 [[DESIRED]], i64* @{{.+}},
350*67e74705SXin Li #pragma omp atomic capture
351*67e74705SXin Li ulv = ulx = ulx & bv;
352*67e74705SXin Li // CHECK: [[CV:%.+]] = load i8, i8* @{{.+}}, align 1
353*67e74705SXin Li // CHECK: [[EXPR:%.+]] = sext i8 [[CV]] to i32
354*67e74705SXin Li // CHECK: [[X:%.+]] = load atomic i8, i8* [[BX_ADDR:@.+]] monotonic
355*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
356*67e74705SXin Li // CHECK: [[CONT]]
357*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = phi i8 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
358*67e74705SXin Li // CHECK: [[OLD_BOOL:%.+]] = trunc i8 [[EXPECTED]] to i1
359*67e74705SXin Li // CHECK: [[X_RVAL:%.+]] = zext i1 [[OLD_BOOL]] to i32
360*67e74705SXin Li // CHECK: [[AND:%.+]] = and i32 [[EXPR]], [[X_RVAL]]
361*67e74705SXin Li // CHECK: [[CAST:%.+]] = icmp ne i32 [[AND]], 0
362*67e74705SXin Li // CHECK: [[NEW:%.+]] = zext i1 [[CAST]] to i8
363*67e74705SXin Li // CHECK: store i8 [[NEW]], i8* [[TEMP:%.+]],
364*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = load i8, i8* [[TEMP]],
365*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i8* [[BX_ADDR]], i8 [[EXPECTED]], i8 [[DESIRED]] monotonic monotonic
366*67e74705SXin Li // CHECK: [[OLD:%.+]] = extractvalue { i8, i1 } [[RES]], 0
367*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i8, i1 } [[RES]], 1
368*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
369*67e74705SXin Li // CHECK: [[EXIT]]
370*67e74705SXin Li // CHECK: [[OLD_I8:%.+]] = zext i1 [[OLD_BOOL]] to i8
371*67e74705SXin Li // CHECK: store i8 [[OLD_I8]], i8* @{{.+}},
372*67e74705SXin Li #pragma omp atomic capture
373*67e74705SXin Li {bv = bx; bx = cv & bx;}
374*67e74705SXin Li // CHECK: [[UCV:%.+]] = load i8, i8* @{{.+}},
375*67e74705SXin Li // CHECK: [[EXPR:%.+]] = zext i8 [[UCV]] to i32
376*67e74705SXin Li // CHECK: [[X:%.+]] = load atomic i8, i8* [[CX_ADDR:@.+]] seq_cst
377*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
378*67e74705SXin Li // CHECK: [[CONT]]
379*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = phi i8 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
380*67e74705SXin Li // CHECK: [[X_RVAL:%.+]] = sext i8 [[EXPECTED]] to i32
381*67e74705SXin Li // CHECK: [[ASHR:%.+]] = ashr i32 [[X_RVAL]], [[EXPR]]
382*67e74705SXin Li // CHECK: [[NEW:%.+]] = trunc i32 [[ASHR]] to i8
383*67e74705SXin Li // CHECK: store i8 [[NEW]], i8* [[TEMP:%.+]],
384*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = load i8, i8* [[TEMP]],
385*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i8* [[CX_ADDR]], i8 [[EXPECTED]], i8 [[DESIRED]] seq_cst seq_cst
386*67e74705SXin Li // CHECK: [[OLD_X:%.+]] = extractvalue { i8, i1 } [[RES]], 0
387*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i8, i1 } [[RES]], 1
388*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
389*67e74705SXin Li // CHECK: [[EXIT]]
390*67e74705SXin Li // CHECK: store i8 [[NEW]], i8* @{{.+}},
391*67e74705SXin Li // CHECK: call{{.*}} @__kmpc_flush(
392*67e74705SXin Li #pragma omp atomic capture, seq_cst
393*67e74705SXin Li {cx = cx >> ucv; cv = cx;}
394*67e74705SXin Li // CHECK: [[SV:%.+]] = load i16, i16* @{{.+}},
395*67e74705SXin Li // CHECK: [[EXPR:%.+]] = sext i16 [[SV]] to i32
396*67e74705SXin Li // CHECK: [[X:%.+]] = load atomic i64, i64* [[ULX_ADDR:@.+]] monotonic
397*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
398*67e74705SXin Li // CHECK: [[CONT]]
399*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = phi i64 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
400*67e74705SXin Li // CHECK: [[X_RVAL:%.+]] = trunc i64 [[EXPECTED]] to i32
401*67e74705SXin Li // CHECK: [[SHL:%.+]] = shl i32 [[EXPR]], [[X_RVAL]]
402*67e74705SXin Li // CHECK: [[NEW:%.+]] = sext i32 [[SHL]] to i64
403*67e74705SXin Li // CHECK: store i64 [[NEW]], i64* [[TEMP:%.+]],
404*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = load i64, i64* [[TEMP]],
405*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i64* [[ULX_ADDR]], i64 [[EXPECTED]], i64 [[DESIRED]] monotonic monotonic
406*67e74705SXin Li // CHECK: [[OLD_X:%.+]] = extractvalue { i64, i1 } [[RES]], 0
407*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i64, i1 } [[RES]], 1
408*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
409*67e74705SXin Li // CHECK: [[EXIT]]
410*67e74705SXin Li // CHECK: store i64 [[NEW]], i64* @{{.+}},
411*67e74705SXin Li #pragma omp atomic capture
412*67e74705SXin Li ulv = ulx = sv << ulx;
413*67e74705SXin Li // CHECK: [[USV:%.+]] = load i16, i16* @{{.+}},
414*67e74705SXin Li // CHECK: [[EXPR:%.+]] = zext i16 [[USV]] to i64
415*67e74705SXin Li // CHECK: [[X:%.+]] = load atomic i64, i64* [[LX_ADDR:@.+]] monotonic
416*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
417*67e74705SXin Li // CHECK: [[CONT]]
418*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = phi i64 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
419*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = srem i64 [[EXPECTED]], [[EXPR]]
420*67e74705SXin Li // CHECK: store i64 [[DESIRED]], i64* [[TEMP:%.+]],
421*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = load i64, i64* [[TEMP]],
422*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i64* [[LX_ADDR]], i64 [[EXPECTED]], i64 [[DESIRED]] monotonic monotonic
423*67e74705SXin Li // CHECK: [[OLD_X:%.+]] = extractvalue { i64, i1 } [[RES]], 0
424*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i64, i1 } [[RES]], 1
425*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
426*67e74705SXin Li // CHECK: [[EXIT]]
427*67e74705SXin Li // CHECK: store i64 [[EXPECTED]], i64* @{{.+}},
428*67e74705SXin Li #pragma omp atomic capture
429*67e74705SXin Li {lv = lx; lx = lx % usv;}
430*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load i32, i32* @{{.+}}
431*67e74705SXin Li // CHECK: [[OLD:%.+]] = atomicrmw or i32* @{{.+}}, i32 [[EXPR]] seq_cst
432*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = or i32 [[EXPR]], [[OLD]]
433*67e74705SXin Li // CHECK: store i32 [[DESIRED]], i32* @{{.+}},
434*67e74705SXin Li // CHECK: call{{.*}} @__kmpc_flush(
435*67e74705SXin Li #pragma omp atomic seq_cst, capture
436*67e74705SXin Li {uix = iv | uix; uiv = uix;}
437*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load i32, i32* @{{.+}}
438*67e74705SXin Li // CHECK: [[OLD:%.+]] = atomicrmw and i32* @{{.+}}, i32 [[EXPR]] monotonic
439*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = and i32 [[OLD]], [[EXPR]]
440*67e74705SXin Li // CHECK: store i32 [[DESIRED]], i32* @{{.+}},
441*67e74705SXin Li #pragma omp atomic capture
442*67e74705SXin Li iv = ix = ix & uiv;
443*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load i64, i64* @{{.+}},
444*67e74705SXin Li // CHECK: [[BITCAST:%.+]] = bitcast { i32, i32 }* [[EXPECTED_ADDR:%.+]] to i8*
445*67e74705SXin Li // CHECK: call void @__atomic_load(i64 8, i8* bitcast ({ i32, i32 }* [[X_ADDR:@.+]] to i8*), i8* [[BITCAST]], i32 0)
446*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
447*67e74705SXin Li // CHECK: [[CONT]]
448*67e74705SXin Li // CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[EXPECTED_ADDR]], i32 0, i32 0
449*67e74705SXin Li // CHECK: [[OLD_RE:%.+]] = load i32, i32* [[X_RE_ADDR]]
450*67e74705SXin Li // CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[EXPECTED_ADDR]], i32 0, i32 1
451*67e74705SXin Li // CHECK: [[OLD_IM:%.+]] = load i32, i32* [[X_IM_ADDR]]
452*67e74705SXin Li // <Skip checks for complex calculations>
453*67e74705SXin Li // CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[DESIRED_ADDR:%.+]], i32 0, i32 0
454*67e74705SXin Li // CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[DESIRED_ADDR]], i32 0, i32 1
455*67e74705SXin Li // CHECK: store i32 %{{.+}}, i32* [[X_RE_ADDR]]
456*67e74705SXin Li // CHECK: store i32 %{{.+}}, i32* [[X_IM_ADDR]]
457*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = bitcast { i32, i32 }* [[EXPECTED_ADDR]] to i8*
458*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = bitcast { i32, i32 }* [[DESIRED_ADDR]] to i8*
459*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = call zeroext i1 @__atomic_compare_exchange(i64 8, i8* bitcast ({ i32, i32 }* [[X_ADDR]] to i8*), i8* [[EXPECTED]], i8* [[DESIRED]], i32 0, i32 0)
460*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
461*67e74705SXin Li // CHECK: [[EXIT]]
462*67e74705SXin Li // CHECK: store i32 [[OLD_RE]], i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @{{.+}}, i32 0, i32 0),
463*67e74705SXin Li // CHECK: store i32 [[OLD_IM]], i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @{{.+}}, i32 0, i32 1),
464*67e74705SXin Li #pragma omp atomic capture
465*67e74705SXin Li {civ = cix; cix = lv + cix;}
466*67e74705SXin Li // CHECK: [[ULV:%.+]] = load i64, i64* @{{.+}},
467*67e74705SXin Li // CHECK: [[EXPR:%.+]] = uitofp i64 [[ULV]] to float
468*67e74705SXin Li // CHECK: [[X:%.+]] = load atomic i32, i32* bitcast (float* [[X_ADDR:@.+]] to i32*) monotonic
469*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
470*67e74705SXin Li // CHECK: [[CONT]]
471*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = phi i32 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
472*67e74705SXin Li // CHECK: [[TEMP_I:%.+]] = bitcast float* [[TEMP:%.+]] to i32*
473*67e74705SXin Li // CHECK: [[OLD:%.+]] = bitcast i32 [[EXPECTED]] to float
474*67e74705SXin Li // CHECK: [[MUL:%.+]] = fmul float [[OLD]], [[EXPR]]
475*67e74705SXin Li // CHECK: store float [[MUL]], float* [[TEMP]],
476*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = load i32, i32* [[TEMP_I]],
477*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i32* bitcast (float* [[X_ADDR]] to i32*), i32 [[EXPECTED]], i32 [[DESIRED]] monotonic monotonic
478*67e74705SXin Li // CHECK: [[OLD_X:%.+]] = extractvalue { i32, i1 } [[RES]], 0
479*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i32, i1 } [[RES]], 1
480*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
481*67e74705SXin Li // CHECK: [[EXIT]]
482*67e74705SXin Li // CHECK: store float [[MUL]], float* @{{.+}},
483*67e74705SXin Li #pragma omp atomic capture
484*67e74705SXin Li {fx = fx * ulv; fv = fx;}
485*67e74705SXin Li // CHECK: [[LLV:%.+]] = load i64, i64* @{{.+}},
486*67e74705SXin Li // CHECK: [[EXPR:%.+]] = sitofp i64 [[LLV]] to double
487*67e74705SXin Li // CHECK: [[X:%.+]] = load atomic i64, i64* bitcast (double* [[X_ADDR:@.+]] to i64*) monotonic
488*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
489*67e74705SXin Li // CHECK: [[CONT]]
490*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = phi i64 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
491*67e74705SXin Li // CHECK: [[TEMP_I:%.+]] = bitcast double* [[TEMP:%.+]] to i64*
492*67e74705SXin Li // CHECK: [[OLD:%.+]] = bitcast i64 [[EXPECTED]] to double
493*67e74705SXin Li // CHECK: [[DIV:%.+]] = fdiv double [[OLD]], [[EXPR]]
494*67e74705SXin Li // CHECK: store double [[DIV]], double* [[TEMP]],
495*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = load i64, i64* [[TEMP_I]],
496*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (double* [[X_ADDR]] to i64*), i64 [[EXPECTED]], i64 [[DESIRED]] monotonic monotonic
497*67e74705SXin Li // CHECK: [[OLD_X:%.+]] = extractvalue { i64, i1 } [[RES]], 0
498*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i64, i1 } [[RES]], 1
499*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
500*67e74705SXin Li // CHECK: [[EXIT]]
501*67e74705SXin Li // CHECK: store double [[DIV]], double* @{{.+}},
502*67e74705SXin Li #pragma omp atomic capture
503*67e74705SXin Li dv = dx /= llv;
504*67e74705SXin Li // CHECK: [[ULLV:%.+]] = load i64, i64* @{{.+}},
505*67e74705SXin Li // CHECK: [[EXPR:%.+]] = uitofp i64 [[ULLV]] to x86_fp80
506*67e74705SXin Li // CHECK: [[X:%.+]] = load atomic i128, i128* bitcast (x86_fp80* [[X_ADDR:@.+]] to i128*) monotonic
507*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
508*67e74705SXin Li // CHECK: [[CONT]]
509*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = phi i128 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
510*67e74705SXin Li // CHECK: [[TEMP_I1:%.+]] = bitcast x86_fp80* [[TEMP1:%.+]] to i128*
511*67e74705SXin Li // CHECK: store i128 [[EXPECTED]], i128* [[TEMP_I1]],
512*67e74705SXin Li // CHECK: [[TEMP_I:%.+]] = bitcast x86_fp80* [[TEMP:%.+]] to i128*
513*67e74705SXin Li // CHECK: store i128 [[EXPECTED]], i128* [[TEMP_I]],
514*67e74705SXin Li // CHECK: [[OLD:%.+]] = load x86_fp80, x86_fp80* [[TEMP]],
515*67e74705SXin Li // CHECK: [[SUB:%.+]] = fsub x86_fp80 [[OLD]], [[EXPR]]
516*67e74705SXin Li // CHECK: store x86_fp80 [[SUB]], x86_fp80* [[TEMP1]]
517*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = load i128, i128* [[TEMP_I1]]
518*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i128* bitcast (x86_fp80* [[X_ADDR]] to i128*), i128 [[EXPECTED]], i128 [[DESIRED]] monotonic monotonic
519*67e74705SXin Li // CHECK: [[OLD_X:%.+]] = extractvalue { i128, i1 } [[RES]], 0
520*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i128, i1 } [[RES]], 1
521*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
522*67e74705SXin Li // CHECK: [[EXIT]]
523*67e74705SXin Li // CHECK: store x86_fp80 [[OLD]], x86_fp80* @{{.+}},
524*67e74705SXin Li #pragma omp atomic capture
525*67e74705SXin Li {ldv = ldx; ldx -= ullv;}
526*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load float, float* @{{.+}},
527*67e74705SXin Li // CHECK: [[BITCAST:%.+]] = bitcast { i32, i32 }* [[EXPECTED_ADDR:%.+]] to i8*
528*67e74705SXin Li // CHECK: call void @__atomic_load(i64 8, i8* bitcast ({ i32, i32 }* [[X_ADDR:@.+]] to i8*), i8* [[BITCAST]], i32 0)
529*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
530*67e74705SXin Li // CHECK: [[CONT]]
531*67e74705SXin Li // CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[EXPECTED_ADDR]], i32 0, i32 0
532*67e74705SXin Li // CHECK: [[X_RE:%.+]] = load i32, i32* [[X_RE_ADDR]]
533*67e74705SXin Li // CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[EXPECTED_ADDR]], i32 0, i32 1
534*67e74705SXin Li // CHECK: [[X_IM:%.+]] = load i32, i32* [[X_IM_ADDR]]
535*67e74705SXin Li // <Skip checks for complex calculations>
536*67e74705SXin Li // CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[DESIRED_ADDR:%.+]], i32 0, i32 0
537*67e74705SXin Li // CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[DESIRED_ADDR]], i32 0, i32 1
538*67e74705SXin Li // CHECK: store i32 [[NEW_RE:%.+]], i32* [[X_RE_ADDR]]
539*67e74705SXin Li // CHECK: store i32 [[NEW_IM:%.+]], i32* [[X_IM_ADDR]]
540*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = bitcast { i32, i32 }* [[EXPECTED_ADDR]] to i8*
541*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = bitcast { i32, i32 }* [[DESIRED_ADDR]] to i8*
542*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = call zeroext i1 @__atomic_compare_exchange(i64 8, i8* bitcast ({ i32, i32 }* [[X_ADDR]] to i8*), i8* [[EXPECTED]], i8* [[DESIRED]], i32 0, i32 0)
543*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
544*67e74705SXin Li // CHECK: [[EXIT]]
545*67e74705SXin Li // CHECK: store i32 [[NEW_RE]], i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @{{.+}}, i32 0, i32 0),
546*67e74705SXin Li // CHECK: store i32 [[NEW_IM]], i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @{{.+}}, i32 0, i32 1),
547*67e74705SXin Li #pragma omp atomic capture
548*67e74705SXin Li {cix = fv / cix; civ = cix;}
549*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load double, double* @{{.+}},
550*67e74705SXin Li // CHECK: [[X:%.+]] = load atomic i16, i16* [[X_ADDR:@.+]] monotonic
551*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
552*67e74705SXin Li // CHECK: [[CONT]]
553*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = phi i16 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
554*67e74705SXin Li // CHECK: [[CONV:%.+]] = sext i16 [[EXPECTED]] to i32
555*67e74705SXin Li // CHECK: [[X_RVAL:%.+]] = sitofp i32 [[CONV]] to double
556*67e74705SXin Li // CHECK: [[ADD:%.+]] = fadd double [[X_RVAL]], [[EXPR]]
557*67e74705SXin Li // CHECK: [[NEW:%.+]] = fptosi double [[ADD]] to i16
558*67e74705SXin Li // CHECK: store i16 [[NEW]], i16* [[TEMP:%.+]],
559*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = load i16, i16* [[TEMP]],
560*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i16* [[X_ADDR]], i16 [[EXPECTED]], i16 [[DESIRED]] monotonic monotonic
561*67e74705SXin Li // CHECK: [[OLD_X]] = extractvalue { i16, i1 } [[RES]], 0
562*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i16, i1 } [[RES]], 1
563*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
564*67e74705SXin Li // CHECK: [[EXIT]]
565*67e74705SXin Li // CHECK: store i16 [[NEW]], i16* @{{.+}},
566*67e74705SXin Li #pragma omp atomic capture
567*67e74705SXin Li sv = sx = sx + dv;
568*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}},
569*67e74705SXin Li // CHECK: [[XI8:%.+]] = load atomic i8, i8* [[X_ADDR:@.+]] monotonic
570*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
571*67e74705SXin Li // CHECK: [[CONT]]
572*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = phi i8 [ [[XI8]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
573*67e74705SXin Li // CHECK: [[BOOL_EXPECTED:%.+]] = trunc i8 [[EXPECTED]] to i1
574*67e74705SXin Li // CHECK: [[CONV:%.+]] = zext i1 [[BOOL_EXPECTED]] to i32
575*67e74705SXin Li // CHECK: [[X_RVAL:%.+]] = sitofp i32 [[CONV]] to x86_fp80
576*67e74705SXin Li // CHECK: [[MUL:%.+]] = fmul x86_fp80 [[EXPR]], [[X_RVAL]]
577*67e74705SXin Li // CHECK: [[BOOL_DESIRED:%.+]] = fcmp une x86_fp80 [[MUL]], 0xK00000000000000000000
578*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = zext i1 [[BOOL_DESIRED]] to i8
579*67e74705SXin Li // CHECK: store i8 [[DESIRED]], i8* [[TEMP:%.+]],
580*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = load i8, i8* [[TEMP]],
581*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i8* [[X_ADDR]], i8 [[EXPECTED]], i8 [[DESIRED]] monotonic monotonic
582*67e74705SXin Li // CHECK: [[OLD_X:%.+]] = extractvalue { i8, i1 } [[RES]], 0
583*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i8, i1 } [[RES]], 1
584*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
585*67e74705SXin Li // CHECK: [[EXIT]]
586*67e74705SXin Li // CHECK: [[EXPECTED_I8:%.+]] = zext i1 [[BOOL_EXPECTED]] to i8
587*67e74705SXin Li // CHECK: store i8 [[EXPECTED_I8]], i8* @{{.+}},
588*67e74705SXin Li #pragma omp atomic capture
589*67e74705SXin Li {bv = bx; bx = ldv * bx;}
590*67e74705SXin Li // CHECK: [[EXPR_RE:%.+]] = load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* [[CIV_ADDR:@.+]], i32 0, i32 0),
591*67e74705SXin Li // CHECK: [[EXPR_IM:%.+]] = load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* [[CIV_ADDR]], i32 0, i32 1),
592*67e74705SXin Li // CHECK: [[XI8:%.+]] = load atomic i8, i8* [[X_ADDR:@.+]] monotonic
593*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
594*67e74705SXin Li // CHECK: [[CONT]]
595*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = phi i8 [ [[XI8]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
596*67e74705SXin Li // CHECK: [[BOOL_EXPECTED:%.+]] = trunc i8 [[EXPECTED]] to i1
597*67e74705SXin Li // CHECK: [[X_RVAL:%.+]] = zext i1 [[BOOL_EXPECTED]] to i32
598*67e74705SXin Li // CHECK: [[SUB_RE:%.+]] = sub i32 [[EXPR_RE:%.+]], [[X_RVAL]]
599*67e74705SXin Li // CHECK: [[SUB_IM:%.+]] = sub i32 [[EXPR_IM:%.+]], 0
600*67e74705SXin Li // CHECK: icmp ne i32 [[SUB_RE]], 0
601*67e74705SXin Li // CHECK: icmp ne i32 [[SUB_IM]], 0
602*67e74705SXin Li // CHECK: [[BOOL_DESIRED:%.+]] = or i1
603*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = zext i1 [[BOOL_DESIRED]] to i8
604*67e74705SXin Li // CHECK: store i8 [[DESIRED]], i8* [[TEMP:%.+]],
605*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = load i8, i8* [[TEMP]],
606*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i8* [[X_ADDR]], i8 [[EXPECTED]], i8 [[DESIRED]] monotonic monotonic
607*67e74705SXin Li // CHECK: [[OLD_X:%.+]] = extractvalue { i8, i1 } [[RES]], 0
608*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i8, i1 } [[RES]], 1
609*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
610*67e74705SXin Li // CHECK: [[EXIT]]
611*67e74705SXin Li // CHECK: [[DESIRED_I8:%.+]] = zext i1 [[BOOL_DESIRED]] to i8
612*67e74705SXin Li // CHECK: store i8 [[DESIRED_I8]], i8* @{{.+}},
613*67e74705SXin Li #pragma omp atomic capture
614*67e74705SXin Li {bx = civ - bx; bv = bx;}
615*67e74705SXin Li // CHECK: [[EXPR_RE:%.+]] = load float, float* getelementptr inbounds ({ float, float }, { float, float }* @{{.+}}, i32 0, i32 0)
616*67e74705SXin Li // CHECK: [[EXPR_IM:%.+]] = load float, float* getelementptr inbounds ({ float, float }, { float, float }* @{{.+}}, i32 0, i32 1)
617*67e74705SXin Li // CHECK: [[X:%.+]] = load atomic i16, i16* [[X_ADDR:@.+]] monotonic
618*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
619*67e74705SXin Li // CHECK: [[CONT]]
620*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = phi i16 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
621*67e74705SXin Li // CHECK: [[CONV:%.+]] = zext i16 [[EXPECTED]] to i32
622*67e74705SXin Li // CHECK: [[X_RVAL:%.+]] = sitofp i32 [[CONV]] to float
623*67e74705SXin Li // <Skip checks for complex calculations>
624*67e74705SXin Li // CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP:%.+]], i32 0, i32 0
625*67e74705SXin Li // CHECK: [[X_RE:%.+]] = load float, float* [[X_RE_ADDR]]
626*67e74705SXin Li // CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP]], i32 0, i32 1
627*67e74705SXin Li // CHECK: [[X_IM:%.+]] = load float, float* [[X_IM_ADDR]]
628*67e74705SXin Li // CHECK: [[NEW:%.+]] = fptoui float [[X_RE]] to i16
629*67e74705SXin Li // CHECK: store i16 [[NEW]], i16* [[TEMP:%.+]],
630*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = load i16, i16* [[TEMP]],
631*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i16* [[X_ADDR]], i16 [[EXPECTED]], i16 [[DESIRED]] monotonic monotonic
632*67e74705SXin Li // CHECK: [[OLD_X]] = extractvalue { i16, i1 } [[RES]], 0
633*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i16, i1 } [[RES]], 1
634*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
635*67e74705SXin Li // CHECK: [[EXIT]]
636*67e74705SXin Li // CHECK: store i16 [[NEW]], i16* @{{.+}},
637*67e74705SXin Li #pragma omp atomic capture
638*67e74705SXin Li usv = usx /= cfv;
639*67e74705SXin Li // CHECK: [[EXPR_RE:%.+]] = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @{{.+}}, i32 0, i32 0)
640*67e74705SXin Li // CHECK: [[EXPR_IM:%.+]] = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @{{.+}}, i32 0, i32 1)
641*67e74705SXin Li // CHECK: [[X:%.+]] = load atomic i64, i64* [[X_ADDR:@.+]] monotonic
642*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
643*67e74705SXin Li // CHECK: [[CONT]]
644*67e74705SXin Li // CHECK: [[EXPECTED:%.+]] = phi i64 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
645*67e74705SXin Li // CHECK: [[X_RVAL:%.+]] = sitofp i64 [[EXPECTED]] to double
646*67e74705SXin Li // CHECK: [[ADD_RE:%.+]] = fadd double [[X_RVAL]], [[EXPR_RE]]
647*67e74705SXin Li // CHECK: [[ADD_IM:%.+]] = fadd double 0.000000e+00, [[EXPR_IM]]
648*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = fptosi double [[ADD_RE]] to i64
649*67e74705SXin Li // CHECK: store i64 [[DESIRED]], i64* [[TEMP:%.+]],
650*67e74705SXin Li // CHECK: [[DESIRED:%.+]] = load i64, i64* [[TEMP]],
651*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i64* [[X_ADDR]], i64 [[EXPECTED]], i64 [[DESIRED]] monotonic monotonic
652*67e74705SXin Li // CHECK: [[OLD_X]] = extractvalue { i64, i1 } [[RES]], 0
653*67e74705SXin Li // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i64, i1 } [[RES]], 1
654*67e74705SXin Li // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
655*67e74705SXin Li // CHECK: [[EXIT]]
656*67e74705SXin Li // CHECK: store i64 [[EXPECTED]], i64* @{{.+}},
657*67e74705SXin Li #pragma omp atomic capture
658*67e74705SXin Li {llv = llx; llx += cdv;}
659*67e74705SXin Li // CHECK: [[IDX:%.+]] = load i16, i16* @{{.+}}
660*67e74705SXin Li // CHECK: load i8, i8*
661*67e74705SXin Li // CHECK: [[VEC_ITEM_VAL:%.+]] = zext i1 %{{.+}} to i32
662*67e74705SXin Li // CHECK: [[I128VAL:%.+]] = load atomic i128, i128* bitcast (<4 x i32>* [[DEST:@.+]] to i128*) monotonic
663*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
664*67e74705SXin Li // CHECK: [[CONT]]
665*67e74705SXin Li // CHECK: [[OLD_I128:%.+]] = phi i128 [ [[I128VAL]], %{{.+}} ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ]
666*67e74705SXin Li // CHECK: [[TEMP_I:%.+]] = bitcast <4 x i32>* [[TEMP:%.+]] to i128*
667*67e74705SXin Li // CHECK: store i128 [[OLD_I128]], i128* [[TEMP_I]],
668*67e74705SXin Li // CHECK: [[LD:%.+]] = bitcast i128 [[OLD_I128]] to <4 x i32>
669*67e74705SXin Li // CHECK: store <4 x i32> [[LD]], <4 x i32>* [[TEMP1:%.+]],
670*67e74705SXin Li // CHECK: [[VEC_VAL:%.+]] = load <4 x i32>, <4 x i32>* [[TEMP1]]
671*67e74705SXin Li // CHECK: [[ITEM:%.+]] = extractelement <4 x i32> [[VEC_VAL]], i16 [[IDX]]
672*67e74705SXin Li // CHECK: [[OR:%.+]] = or i32 [[ITEM]], [[VEC_ITEM_VAL]]
673*67e74705SXin Li // CHECK: [[VEC_VAL:%.+]] = load <4 x i32>, <4 x i32>* [[TEMP]]
674*67e74705SXin Li // CHECK: [[NEW_VEC_VAL:%.+]] = insertelement <4 x i32> [[VEC_VAL]], i32 [[OR]], i16 [[IDX]]
675*67e74705SXin Li // CHECK: store <4 x i32> [[NEW_VEC_VAL]], <4 x i32>* [[TEMP]]
676*67e74705SXin Li // CHECK: [[NEW_I128:%.+]] = load i128, i128* [[TEMP_I]],
677*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i128* bitcast (<4 x i32>* [[DEST]] to i128*), i128 [[OLD_I128]], i128 [[NEW_I128]] monotonic monotonic
678*67e74705SXin Li // CHECK: [[FAILED_OLD_VAL:%.+]] = extractvalue { i128, i1 } [[RES]], 0
679*67e74705SXin Li // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i128, i1 } [[RES]], 1
680*67e74705SXin Li // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
681*67e74705SXin Li // CHECK: [[EXIT]]
682*67e74705SXin Li // CHECK: store i32 [[OR]], i32* @{{.+}},
683*67e74705SXin Li #pragma omp atomic capture
684*67e74705SXin Li {int4x[sv] |= bv; iv = int4x[sv];}
685*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}}
686*67e74705SXin Li // CHECK: [[PREV_VALUE:%.+]] = load atomic i32, i32* bitcast (i8* getelementptr (i8, i8* bitcast (%struct.BitFields* @{{.+}} to i8*), i64 4) to i32*) monotonic
687*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
688*67e74705SXin Li // CHECK: [[CONT]]
689*67e74705SXin Li // CHECK: [[OLD_BF_VALUE:%.+]] = phi i32 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ]
690*67e74705SXin Li // CHECK: store i32 [[OLD_BF_VALUE]], i32* [[TEMP1:%.+]],
691*67e74705SXin Li // CHECK: store i32 [[OLD_BF_VALUE]], i32* [[TEMP:%.+]],
692*67e74705SXin Li // CHECK: [[A_LD:%.+]] = load i32, i32* [[TEMP]],
693*67e74705SXin Li // CHECK: [[A_SHL:%.+]] = shl i32 [[A_LD]], 1
694*67e74705SXin Li // CHECK: [[A_ASHR:%.+]] = ashr i32 [[A_SHL]], 1
695*67e74705SXin Li // CHECK: [[X_RVAL:%.+]] = sitofp i32 [[A_ASHR]] to x86_fp80
696*67e74705SXin Li // CHECK: [[SUB:%.+]] = fsub x86_fp80 [[X_RVAL]], [[EXPR]]
697*67e74705SXin Li // CHECK: [[CONV:%.+]] = fptosi x86_fp80 [[SUB]] to i32
698*67e74705SXin Li // CHECK: [[NEW_VAL:%.+]] = load i32, i32* [[TEMP1]],
699*67e74705SXin Li // CHECK: [[BF_VALUE:%.+]] = and i32 [[CONV]], 2147483647
700*67e74705SXin Li // CHECK: [[BF_CLEAR:%.+]] = and i32 [[NEW_VAL]], -2147483648
701*67e74705SXin Li // CHECK: [[BF_SET:%.+]] = or i32 [[BF_CLEAR]], [[BF_VALUE]]
702*67e74705SXin Li // CHECK: store i32 [[BF_SET]], i32* [[TEMP1]],
703*67e74705SXin Li // CHECK: [[NEW_BF_VALUE:%.+]] = load i32, i32* [[TEMP1]],
704*67e74705SXin Li // 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
705*67e74705SXin Li // CHECK: [[FAILED_OLD_VAL]] = extractvalue { i32, i1 } [[RES]], 0
706*67e74705SXin Li // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i32, i1 } [[RES]], 1
707*67e74705SXin Li // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
708*67e74705SXin Li // CHECK: [[EXIT]]
709*67e74705SXin Li // CHECK: store i32 [[CONV]], i32* @{{.+}},
710*67e74705SXin Li #pragma omp atomic capture
711*67e74705SXin Li iv = bfx.a = bfx.a - ldv;
712*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}}
713*67e74705SXin Li // CHECK: [[BITCAST:%.+]] = bitcast i32* [[LDTEMP:%.+]] to i8*
714*67e74705SXin Li // CHECK: call void @__atomic_load(i64 4, i8* getelementptr (i8, i8* bitcast (%struct.BitFields_packed* @{{.+}} to i8*), i64 4), i8* [[BITCAST]], i32 0)
715*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
716*67e74705SXin Li // CHECK: [[CONT]]
717*67e74705SXin Li // CHECK: [[OLD:%.+]] = load i32, i32* [[LDTEMP]],
718*67e74705SXin Li // CHECK: store i32 [[OLD]], i32* [[TEMP1:%.+]],
719*67e74705SXin Li // CHECK: [[OLD:%.+]] = load i32, i32* [[LDTEMP]],
720*67e74705SXin Li // CHECK: store i32 [[OLD]], i32* [[TEMP:%.+]],
721*67e74705SXin Li // CHECK: [[A_LD:%.+]] = load i32, i32* [[TEMP]],
722*67e74705SXin Li // CHECK: [[A_SHL:%.+]] = shl i32 [[A_LD]], 1
723*67e74705SXin Li // CHECK: [[A_ASHR:%.+]] = ashr i32 [[A_SHL]], 1
724*67e74705SXin Li // CHECK: [[X_RVAL:%.+]] = sitofp i32 [[A_ASHR]] to x86_fp80
725*67e74705SXin Li // CHECK: [[MUL:%.+]] = fmul x86_fp80 [[X_RVAL]], [[EXPR]]
726*67e74705SXin Li // CHECK: [[CONV:%.+]] = fptosi x86_fp80 [[MUL]] to i32
727*67e74705SXin Li // CHECK: [[NEW_VAL:%.+]] = load i32, i32* [[TEMP1]],
728*67e74705SXin Li // CHECK: [[BF_VALUE:%.+]] = and i32 [[CONV]], 2147483647
729*67e74705SXin Li // CHECK: [[BF_CLEAR:%.+]] = and i32 [[NEW_VAL]], -2147483648
730*67e74705SXin Li // CHECK: or i32 [[BF_CLEAR]], [[BF_VALUE]]
731*67e74705SXin Li // CHECK: store i32 %{{.+}}, i32* [[TEMP1]]
732*67e74705SXin Li // CHECK: [[BITCAST_TEMP_OLD_BF_ADDR:%.+]] = bitcast i32* [[LDTEMP]] to i8*
733*67e74705SXin Li // CHECK: [[BITCAST_TEMP_NEW_BF_ADDR:%.+]] = bitcast i32* [[TEMP1]] to i8*
734*67e74705SXin Li // 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)
735*67e74705SXin Li // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
736*67e74705SXin Li // CHECK: [[EXIT]]
737*67e74705SXin Li // CHECK: store i32 [[A_ASHR]], i32* @{{.+}},
738*67e74705SXin Li #pragma omp atomic capture
739*67e74705SXin Li {iv = bfx_packed.a; bfx_packed.a *= ldv;}
740*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}}
741*67e74705SXin Li // CHECK: [[PREV_VALUE:%.+]] = load atomic i32, i32* getelementptr inbounds (%struct.BitFields2, %struct.BitFields2* @{{.+}}, i32 0, i32 0) monotonic
742*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
743*67e74705SXin Li // CHECK: [[CONT]]
744*67e74705SXin Li // CHECK: [[OLD_BF_VALUE:%.+]] = phi i32 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ]
745*67e74705SXin Li // CHECK: store i32 [[OLD_BF_VALUE]], i32* [[TEMP1:%.+]],
746*67e74705SXin Li // CHECK: store i32 [[OLD_BF_VALUE]], i32* [[TEMP:%.+]],
747*67e74705SXin Li // CHECK: [[A_LD:%.+]] = load i32, i32* [[TEMP]],
748*67e74705SXin Li // CHECK: [[A_ASHR:%.+]] = ashr i32 [[A_LD]], 31
749*67e74705SXin Li // CHECK: [[X_RVAL:%.+]] = sitofp i32 [[A_ASHR]] to x86_fp80
750*67e74705SXin Li // CHECK: [[SUB:%.+]] = fsub x86_fp80 [[X_RVAL]], [[EXPR]]
751*67e74705SXin Li // CHECK: [[CONV:%.+]] = fptosi x86_fp80 [[SUB]] to i32
752*67e74705SXin Li // CHECK: [[NEW_VAL:%.+]] = load i32, i32* [[TEMP1]],
753*67e74705SXin Li // CHECK: [[BF_AND:%.+]] = and i32 [[CONV]], 1
754*67e74705SXin Li // CHECK: [[BF_VALUE:%.+]] = shl i32 [[BF_AND]], 31
755*67e74705SXin Li // CHECK: [[BF_CLEAR:%.+]] = and i32 [[NEW_VAL]], 2147483647
756*67e74705SXin Li // CHECK: or i32 [[BF_CLEAR]], [[BF_VALUE]]
757*67e74705SXin Li // CHECK: store i32 %{{.+}}, i32* [[TEMP1]]
758*67e74705SXin Li // CHECK: [[NEW_BF_VALUE:%.+]] = load i32, i32* [[TEMP1]]
759*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i32* getelementptr inbounds (%struct.BitFields2, %struct.BitFields2* @{{.+}}, i32 0, i32 0), i32 [[OLD_BF_VALUE]], i32 [[NEW_BF_VALUE]] monotonic monotonic
760*67e74705SXin Li // CHECK: [[FAILED_OLD_VAL]] = extractvalue { i32, i1 } [[RES]], 0
761*67e74705SXin Li // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i32, i1 } [[RES]], 1
762*67e74705SXin Li // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
763*67e74705SXin Li // CHECK: [[EXIT]]
764*67e74705SXin Li // CHECK: store i32 [[CONV]], i32* @{{.+}},
765*67e74705SXin Li #pragma omp atomic capture
766*67e74705SXin Li {bfx2.a -= ldv; iv = bfx2.a;}
767*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}}
768*67e74705SXin Li // CHECK: [[PREV_VALUE:%.+]] = load atomic i8, i8* getelementptr (i8, i8* bitcast (%struct.BitFields2_packed* @{{.+}} to i8*), i64 3) monotonic
769*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
770*67e74705SXin Li // CHECK: [[CONT]]
771*67e74705SXin Li // CHECK: [[OLD_BF_VALUE:%.+]] = phi i8 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ]
772*67e74705SXin Li // CHECK: [[BITCAST_NEW:%.+]] = bitcast i32* %{{.+}} to i8*
773*67e74705SXin Li // CHECK: store i8 [[OLD_BF_VALUE]], i8* [[BITCAST_NEW]],
774*67e74705SXin Li // CHECK: [[BITCAST:%.+]] = bitcast i32* %{{.+}} to i8*
775*67e74705SXin Li // CHECK: store i8 [[OLD_BF_VALUE]], i8* [[BITCAST]],
776*67e74705SXin Li // CHECK: [[A_LD:%.+]] = load i8, i8* [[BITCAST]],
777*67e74705SXin Li // CHECK: [[A_ASHR:%.+]] = ashr i8 [[A_LD]], 7
778*67e74705SXin Li // CHECK: [[CAST:%.+]] = sext i8 [[A_ASHR]] to i32
779*67e74705SXin Li // CHECK: [[X_RVAL:%.+]] = sitofp i32 [[CAST]] to x86_fp80
780*67e74705SXin Li // CHECK: [[DIV:%.+]] = fdiv x86_fp80 [[EXPR]], [[X_RVAL]]
781*67e74705SXin Li // CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 [[DIV]] to i32
782*67e74705SXin Li // CHECK: [[TRUNC:%.+]] = trunc i32 [[NEW_VAL]] to i8
783*67e74705SXin Li // CHECK: [[BF_LD:%.+]] = load i8, i8* [[BITCAST_NEW]],
784*67e74705SXin Li // CHECK: [[BF_AND:%.+]] = and i8 [[TRUNC]], 1
785*67e74705SXin Li // CHECK: [[BF_VALUE:%.+]] = shl i8 [[BF_AND]], 7
786*67e74705SXin Li // CHECK: [[BF_CLEAR:%.+]] = and i8 %{{.+}}, 127
787*67e74705SXin Li // CHECK: or i8 [[BF_CLEAR]], [[BF_VALUE]]
788*67e74705SXin Li // CHECK: store i8 %{{.+}}, i8* [[BITCAST_NEW]]
789*67e74705SXin Li // CHECK: [[NEW_BF_VALUE:%.+]] = load i8, i8* [[BITCAST_NEW]]
790*67e74705SXin Li // 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
791*67e74705SXin Li // CHECK: [[FAILED_OLD_VAL]] = extractvalue { i8, i1 } [[RES]], 0
792*67e74705SXin Li // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i8, i1 } [[RES]], 1
793*67e74705SXin Li // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
794*67e74705SXin Li // CHECK: [[EXIT]]
795*67e74705SXin Li // CHECK: store i32 [[NEW_VAL]], i32* @{{.+}},
796*67e74705SXin Li #pragma omp atomic capture
797*67e74705SXin Li iv = bfx2_packed.a = ldv / bfx2_packed.a;
798*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}}
799*67e74705SXin Li // CHECK: [[PREV_VALUE:%.+]] = load atomic i32, i32* getelementptr inbounds (%struct.BitFields3, %struct.BitFields3* @{{.+}}, i32 0, i32 0) monotonic
800*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
801*67e74705SXin Li // CHECK: [[CONT]]
802*67e74705SXin Li // CHECK: [[OLD_BF_VALUE:%.+]] = phi i32 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ]
803*67e74705SXin Li // CHECK: store i32 [[OLD_BF_VALUE]], i32* [[TEMP1:%.+]],
804*67e74705SXin Li // CHECK: store i32 [[OLD_BF_VALUE]], i32* [[TEMP:%.+]],
805*67e74705SXin Li // CHECK: [[A_LD:%.+]] = load i32, i32* [[TEMP]],
806*67e74705SXin Li // CHECK: [[A_SHL:%.+]] = shl i32 [[A_LD]], 7
807*67e74705SXin Li // CHECK: [[A_ASHR:%.+]] = ashr i32 [[A_SHL]], 18
808*67e74705SXin Li // CHECK: [[X_RVAL:%.+]] = sitofp i32 [[A_ASHR]] to x86_fp80
809*67e74705SXin Li // CHECK: [[DIV:%.+]] = fdiv x86_fp80 [[X_RVAL]], [[EXPR]]
810*67e74705SXin Li // CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 [[DIV]] to i32
811*67e74705SXin Li // CHECK: [[BF_LD:%.+]] = load i32, i32* [[TEMP1]],
812*67e74705SXin Li // CHECK: [[BF_AND:%.+]] = and i32 [[NEW_VAL]], 16383
813*67e74705SXin Li // CHECK: [[BF_VALUE:%.+]] = shl i32 [[BF_AND]], 11
814*67e74705SXin Li // CHECK: [[BF_CLEAR:%.+]] = and i32 %{{.+}}, -33552385
815*67e74705SXin Li // CHECK: or i32 [[BF_CLEAR]], [[BF_VALUE]]
816*67e74705SXin Li // CHECK: store i32 %{{.+}}, i32* [[TEMP1]]
817*67e74705SXin Li // CHECK: [[NEW_BF_VALUE:%.+]] = load i32, i32* [[TEMP1]]
818*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i32* getelementptr inbounds (%struct.BitFields3, %struct.BitFields3* @{{.+}}, i32 0, i32 0), i32 [[OLD_BF_VALUE]], i32 [[NEW_BF_VALUE]] monotonic monotonic
819*67e74705SXin Li // CHECK: [[FAILED_OLD_VAL]] = extractvalue { i32, i1 } [[RES]], 0
820*67e74705SXin Li // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i32, i1 } [[RES]], 1
821*67e74705SXin Li // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
822*67e74705SXin Li // CHECK: [[EXIT]]
823*67e74705SXin Li // CHECK: store i32 [[A_ASHR]], i32* @{{.+}},
824*67e74705SXin Li #pragma omp atomic capture
825*67e74705SXin Li {iv = bfx3.a; bfx3.a /= ldv;}
826*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}}
827*67e74705SXin Li // CHECK: [[LDTEMP:%.+]] = bitcast i32* %{{.+}} to i24*
828*67e74705SXin Li // CHECK: [[BITCAST:%.+]] = bitcast i24* [[LDTEMP]] to i8*
829*67e74705SXin Li // CHECK: call void @__atomic_load(i64 3, i8* getelementptr (i8, i8* bitcast (%struct.BitFields3_packed* @{{.+}} to i8*), i64 1), i8* [[BITCAST]], i32 0)
830*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
831*67e74705SXin Li // CHECK: [[CONT]]
832*67e74705SXin Li // CHECK: [[OLD:%.+]] = load i24, i24* [[LDTEMP]],
833*67e74705SXin Li // CHECK: store i24 [[OLD]], i24* [[BITCAST2:%.+]],
834*67e74705SXin Li // CHECK: [[OLD:%.+]] = load i24, i24* [[LDTEMP]],
835*67e74705SXin Li // CHECK: store i24 [[OLD]], i24* [[BITCAST1:%.+]],
836*67e74705SXin Li // CHECK: [[A_LD:%.+]] = load i24, i24* [[BITCAST1]],
837*67e74705SXin Li // CHECK: [[A_SHL:%.+]] = shl i24 [[A_LD]], 7
838*67e74705SXin Li // CHECK: [[A_ASHR:%.+]] = ashr i24 [[A_SHL]], 10
839*67e74705SXin Li // CHECK: [[CAST:%.+]] = sext i24 [[A_ASHR]] to i32
840*67e74705SXin Li // CHECK: [[X_RVAL:%.+]] = sitofp i32 [[CAST]] to x86_fp80
841*67e74705SXin Li // CHECK: [[ADD:%.+]] = fadd x86_fp80 [[X_RVAL]], [[EXPR]]
842*67e74705SXin Li // CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 [[ADD]] to i32
843*67e74705SXin Li // CHECK: [[TRUNC:%.+]] = trunc i32 [[NEW_VAL]] to i24
844*67e74705SXin Li // CHECK: [[BF_LD:%.+]] = load i24, i24* [[BITCAST2]],
845*67e74705SXin Li // CHECK: [[BF_AND:%.+]] = and i24 [[TRUNC]], 16383
846*67e74705SXin Li // CHECK: [[BF_VALUE:%.+]] = shl i24 [[BF_AND]], 3
847*67e74705SXin Li // CHECK: [[BF_CLEAR:%.+]] = and i24 [[BF_LD]], -131065
848*67e74705SXin Li // CHECK: or i24 [[BF_CLEAR]], [[BF_VALUE]]
849*67e74705SXin Li // CHECK: store i24 %{{.+}}, i24* [[BITCAST2]]
850*67e74705SXin Li // CHECK: [[BITCAST_TEMP_OLD_BF_ADDR:%.+]] = bitcast i24* [[LDTEMP]] to i8*
851*67e74705SXin Li // CHECK: [[BITCAST_TEMP_NEW_BF_ADDR:%.+]] = bitcast i24* [[BITCAST2]] to i8*
852*67e74705SXin Li // 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)
853*67e74705SXin Li // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
854*67e74705SXin Li // CHECK: [[EXIT]]
855*67e74705SXin Li // CHECK: store i32 [[NEW_VAL]], i32* @{{.+}},
856*67e74705SXin Li #pragma omp atomic capture
857*67e74705SXin Li {bfx3_packed.a += ldv; iv = bfx3_packed.a;}
858*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}}
859*67e74705SXin Li // CHECK: [[PREV_VALUE:%.+]] = load atomic i64, i64* bitcast (%struct.BitFields4* @{{.+}} to i64*) monotonic
860*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
861*67e74705SXin Li // CHECK: [[CONT]]
862*67e74705SXin Li // CHECK: [[OLD_BF_VALUE:%.+]] = phi i64 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ]
863*67e74705SXin Li // CHECK: store i64 [[OLD_BF_VALUE]], i64* [[TEMP1:%.+]],
864*67e74705SXin Li // CHECK: store i64 [[OLD_BF_VALUE]], i64* [[TEMP:%.+]],
865*67e74705SXin Li // CHECK: [[A_LD:%.+]] = load i64, i64* [[TEMP]],
866*67e74705SXin Li // CHECK: [[A_SHL:%.+]] = shl i64 [[A_LD]], 47
867*67e74705SXin Li // CHECK: [[A_ASHR:%.+]] = ashr i64 [[A_SHL:%.+]], 63
868*67e74705SXin Li // CHECK: [[A_CAST:%.+]] = trunc i64 [[A_ASHR:%.+]] to i32
869*67e74705SXin Li // CHECK: [[X_RVAL:%.+]] = sitofp i32 [[CAST:%.+]] to x86_fp80
870*67e74705SXin Li // CHECK: [[MUL:%.+]] = fmul x86_fp80 [[X_RVAL]], [[EXPR]]
871*67e74705SXin Li // CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 [[MUL]] to i32
872*67e74705SXin Li // CHECK: [[ZEXT:%.+]] = zext i32 [[NEW_VAL]] to i64
873*67e74705SXin Li // CHECK: [[BF_LD:%.+]] = load i64, i64* [[TEMP1]],
874*67e74705SXin Li // CHECK: [[BF_AND:%.+]] = and i64 [[ZEXT]], 1
875*67e74705SXin Li // CHECK: [[BF_VALUE:%.+]] = shl i64 [[BF_AND]], 16
876*67e74705SXin Li // CHECK: [[BF_CLEAR:%.+]] = and i64 [[BF_LD]], -65537
877*67e74705SXin Li // CHECK: or i64 [[BF_CLEAR]], [[BF_VALUE]]
878*67e74705SXin Li // CHECK: store i64 %{{.+}}, i64* [[TEMP1]]
879*67e74705SXin Li // CHECK: [[NEW_BF_VALUE:%.+]] = load i64, i64* [[TEMP1]]
880*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (%struct.BitFields4* @{{.+}} to i64*), i64 [[OLD_BF_VALUE]], i64 [[NEW_BF_VALUE]] monotonic monotonic
881*67e74705SXin Li // CHECK: [[FAILED_OLD_VAL]] = extractvalue { i64, i1 } [[RES]], 0
882*67e74705SXin Li // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i64, i1 } [[RES]], 1
883*67e74705SXin Li // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
884*67e74705SXin Li // CHECK: [[EXIT]]
885*67e74705SXin Li // CHECK: store i32 [[NEW_VAL]], i32* @{{.+}},
886*67e74705SXin Li #pragma omp atomic capture
887*67e74705SXin Li iv = bfx4.a = bfx4.a * ldv;
888*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}}
889*67e74705SXin Li // CHECK: [[PREV_VALUE:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2) monotonic
890*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
891*67e74705SXin Li // CHECK: [[CONT]]
892*67e74705SXin Li // CHECK: [[OLD_BF_VALUE:%.+]] = phi i8 [ [[PREV_VALUE]], %{{.+}} ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ]
893*67e74705SXin Li // CHECK: [[BITCAST1:%.+]] = bitcast i32* %{{.+}} to i8*
894*67e74705SXin Li // CHECK: store i8 [[OLD_BF_VALUE]], i8* [[BITCAST1]],
895*67e74705SXin Li // CHECK: [[BITCAST:%.+]] = bitcast i32* %{{.+}} to i8*
896*67e74705SXin Li // CHECK: store i8 [[OLD_BF_VALUE]], i8* [[BITCAST]],
897*67e74705SXin Li // CHECK: [[A_LD:%.+]] = load i8, i8* [[BITCAST]],
898*67e74705SXin Li // CHECK: [[A_SHL:%.+]] = shl i8 [[A_LD]], 7
899*67e74705SXin Li // CHECK: [[A_ASHR:%.+]] = ashr i8 [[A_SHL:%.+]], 7
900*67e74705SXin Li // CHECK: [[CAST:%.+]] = sext i8 [[A_ASHR:%.+]] to i32
901*67e74705SXin Li // CHECK: [[CONV:%.+]] = sitofp i32 [[CAST]] to x86_fp80
902*67e74705SXin Li // CHECK: [[SUB: %.+]] = fsub x86_fp80 [[CONV]], [[EXPR]]
903*67e74705SXin Li // CHECK: [[CONV:%.+]] = fptosi x86_fp80 [[SUB:%.+]] to i32
904*67e74705SXin Li // CHECK: [[NEW_VAL:%.+]] = trunc i32 [[CONV]] to i8
905*67e74705SXin Li // CHECK: [[BF_LD:%.+]] = load i8, i8* [[BITCAST1]],
906*67e74705SXin Li // CHECK: [[BF_VALUE:%.+]] = and i8 [[NEW_VAL]], 1
907*67e74705SXin Li // CHECK: [[BF_CLEAR:%.+]] = and i8 [[BF_LD]], -2
908*67e74705SXin Li // CHECK: or i8 [[BF_CLEAR]], [[BF_VALUE]]
909*67e74705SXin Li // CHECK: store i8 %{{.+}}, i8* [[BITCAST1]]
910*67e74705SXin Li // CHECK: [[NEW_BF_VALUE:%.+]] = load i8, i8* [[BITCAST1]]
911*67e74705SXin Li // 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
912*67e74705SXin Li // CHECK: [[FAILED_OLD_VAL]] = extractvalue { i8, i1 } [[RES]], 0
913*67e74705SXin Li // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i8, i1 } [[RES]], 1
914*67e74705SXin Li // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
915*67e74705SXin Li // CHECK: [[EXIT]]
916*67e74705SXin Li // CHECK: store i32 [[CAST]], i32* @{{.+}},
917*67e74705SXin Li #pragma omp atomic capture
918*67e74705SXin Li {iv = bfx4_packed.a; bfx4_packed.a -= ldv;}
919*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}}
920*67e74705SXin Li // CHECK: [[PREV_VALUE:%.+]] = load atomic i64, i64* bitcast (%struct.BitFields4* @{{.+}} to i64*) monotonic
921*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
922*67e74705SXin Li // CHECK: [[CONT]]
923*67e74705SXin Li // CHECK: [[OLD_BF_VALUE:%.+]] = phi i64 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ]
924*67e74705SXin Li // CHECK: store i64 [[OLD_BF_VALUE]], i64* [[TEMP1:%.+]],
925*67e74705SXin Li // CHECK: store i64 [[OLD_BF_VALUE]], i64* [[TEMP:%.+]],
926*67e74705SXin Li // CHECK: [[A_LD:%.+]] = load i64, i64* [[TEMP]],
927*67e74705SXin Li // CHECK: [[A_SHL:%.+]] = shl i64 [[A_LD]], 40
928*67e74705SXin Li // CHECK: [[A_ASHR:%.+]] = ashr i64 [[A_SHL:%.+]], 57
929*67e74705SXin Li // CHECK: [[CONV:%.+]] = sitofp i64 [[A_ASHR]] to x86_fp80
930*67e74705SXin Li // CHECK: [[DIV:%.+]] = fdiv x86_fp80 [[CONV]], [[EXPR]]
931*67e74705SXin Li // CHECK: [[CONV:%.+]] = fptosi x86_fp80 [[DIV]] to i64
932*67e74705SXin Li // CHECK: [[BF_LD:%.+]] = load i64, i64* [[TEMP1]],
933*67e74705SXin Li // CHECK: [[BF_AND:%.+]] = and i64 [[CONV]], 127
934*67e74705SXin Li // CHECK: [[BF_VALUE:%.+]] = shl i64 [[BF_AND:%.+]], 17
935*67e74705SXin Li // CHECK: [[BF_CLEAR:%.+]] = and i64 [[BF_LD]], -16646145
936*67e74705SXin Li // CHECK: [[VAL:%.+]] = or i64 [[BF_CLEAR]], [[BF_VALUE]]
937*67e74705SXin Li // CHECK: store i64 [[VAL]], i64* [[TEMP1]]
938*67e74705SXin Li // CHECK: [[NEW_BF_VALUE:%.+]] = load i64, i64* [[TEMP1]]
939*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (%struct.BitFields4* @{{.+}} to i64*), i64 [[OLD_BF_VALUE]], i64 [[NEW_BF_VALUE]] monotonic monotonic
940*67e74705SXin Li // CHECK: [[FAILED_OLD_VAL]] = extractvalue { i64, i1 } [[RES]], 0
941*67e74705SXin Li // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i64, i1 } [[RES]], 1
942*67e74705SXin Li // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
943*67e74705SXin Li // CHECK: [[EXIT]]
944*67e74705SXin Li // CHECK: [[NEW_VAL:%.+]] = trunc i64 [[CONV]] to i32
945*67e74705SXin Li // CHECK: store i32 [[NEW_VAL]], i32* @{{.+}},
946*67e74705SXin Li #pragma omp atomic capture
947*67e74705SXin Li {bfx4.b /= ldv; iv = bfx4.b;}
948*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}}
949*67e74705SXin Li // CHECK: [[PREV_VALUE:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2) monotonic
950*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
951*67e74705SXin Li // CHECK: [[CONT]]
952*67e74705SXin Li // CHECK: [[OLD_BF_VALUE:%.+]] = phi i8 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ]
953*67e74705SXin Li // CHECK: [[BITCAST1:%.+]] = bitcast i64* %{{.+}} to i8*
954*67e74705SXin Li // CHECK: store i8 [[OLD_BF_VALUE]], i8* [[BITCAST1]],
955*67e74705SXin Li // CHECK: [[BITCAST:%.+]] = bitcast i64* %{{.+}} to i8*
956*67e74705SXin Li // CHECK: store i8 [[OLD_BF_VALUE]], i8* [[BITCAST]],
957*67e74705SXin Li // CHECK: [[A_LD:%.+]] = load i8, i8* [[BITCAST]],
958*67e74705SXin Li // CHECK: [[A_ASHR:%.+]] = ashr i8 [[A_LD]], 1
959*67e74705SXin Li // CHECK: [[CAST:%.+]] = sext i8 [[A_ASHR]] to i64
960*67e74705SXin Li // CHECK: [[CONV:%.+]] = sitofp i64 [[CAST]] to x86_fp80
961*67e74705SXin Li // CHECK: [[ADD:%.+]] = fadd x86_fp80 [[CONV]], [[EXPR]]
962*67e74705SXin Li // CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 [[ADD]] to i64
963*67e74705SXin Li // CHECK: [[TRUNC:%.+]] = trunc i64 [[NEW_VAL]] to i8
964*67e74705SXin Li // CHECK: [[BF_LD:%.+]] = load i8, i8* [[BITCAST1]],
965*67e74705SXin Li // CHECK: [[BF_AND:%.+]] = and i8 [[TRUNC]], 127
966*67e74705SXin Li // CHECK: [[BF_VALUE:%.+]] = shl i8 [[BF_AND]], 1
967*67e74705SXin Li // CHECK: [[BF_CLEAR:%.+]] = and i8 [[BF_LD]], 1
968*67e74705SXin Li // CHECK: or i8 [[BF_CLEAR]], [[BF_VALUE]]
969*67e74705SXin Li // CHECK: store i8 %{{.+}}, i8* [[BITCAST1]]
970*67e74705SXin Li // CHECK: [[NEW_BF_VALUE:%.+]] = load i8, i8* [[BITCAST1]]
971*67e74705SXin Li // 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
972*67e74705SXin Li // CHECK: [[FAILED_OLD_VAL]] = extractvalue { i8, i1 } [[RES]], 0
973*67e74705SXin Li // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i8, i1 } [[RES]], 1
974*67e74705SXin Li // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
975*67e74705SXin Li // CHECK: [[EXIT]]
976*67e74705SXin Li // CHECK: [[NEW_VAL_I32:%.+]] = trunc i64 [[NEW_VAL]] to i32
977*67e74705SXin Li // CHECK: store i32 [[NEW_VAL_I32]], i32* @{{.+}},
978*67e74705SXin Li #pragma omp atomic capture
979*67e74705SXin Li iv = bfx4_packed.b += ldv;
980*67e74705SXin Li // CHECK: load i64, i64*
981*67e74705SXin Li // CHECK: [[EXPR:%.+]] = uitofp i64 %{{.+}} to float
982*67e74705SXin Li // CHECK: [[I64VAL:%.+]] = load atomic i64, i64* bitcast (<2 x float>* [[DEST:@.+]] to i64*) monotonic
983*67e74705SXin Li // CHECK: br label %[[CONT:.+]]
984*67e74705SXin Li // CHECK: [[CONT]]
985*67e74705SXin Li // CHECK: [[OLD_I64:%.+]] = phi i64 [ [[I64VAL]], %{{.+}} ], [ [[FAILED_I64_OLD_VAL:%.+]], %[[CONT]] ]
986*67e74705SXin Li // CHECK: [[BITCAST:%.+]] = bitcast <2 x float>* [[LDTEMP1:%.+]] to i64*
987*67e74705SXin Li // CHECK: store i64 [[OLD_I64]], i64* [[BITCAST]],
988*67e74705SXin Li // CHECK: [[OLD_VEC_VAL:%.+]] = bitcast i64 [[OLD_I64]] to <2 x float>
989*67e74705SXin Li // CHECK: store <2 x float> [[OLD_VEC_VAL]], <2 x float>* [[LDTEMP:%.+]],
990*67e74705SXin Li // CHECK: [[VEC_VAL:%.+]] = load <2 x float>, <2 x float>* [[LDTEMP]]
991*67e74705SXin Li // CHECK: [[X:%.+]] = extractelement <2 x float> [[VEC_VAL]], i64 0
992*67e74705SXin Li // CHECK: [[VEC_ITEM_VAL:%.+]] = fsub float [[EXPR]], [[X]]
993*67e74705SXin Li // CHECK: [[VEC_VAL:%.+]] = load <2 x float>, <2 x float>* [[LDTEMP1]],
994*67e74705SXin Li // CHECK: [[NEW_VEC_VAL:%.+]] = insertelement <2 x float> [[VEC_VAL]], float [[VEC_ITEM_VAL]], i64 0
995*67e74705SXin Li // CHECK: store <2 x float> [[NEW_VEC_VAL]], <2 x float>* [[LDTEMP1]]
996*67e74705SXin Li // CHECK: [[NEW_I64:%.+]] = load i64, i64* [[BITCAST]]
997*67e74705SXin Li // CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (<2 x float>* [[DEST]] to i64*), i64 [[OLD_I64]], i64 [[NEW_I64]] monotonic monotonic
998*67e74705SXin Li // CHECK: [[FAILED_I64_OLD_VAL:%.+]] = extractvalue { i64, i1 } [[RES]], 0
999*67e74705SXin Li // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i64, i1 } [[RES]], 1
1000*67e74705SXin Li // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
1001*67e74705SXin Li // CHECK: [[EXIT]]
1002*67e74705SXin Li // CHECK: store float [[X]], float* @{{.+}},
1003*67e74705SXin Li #pragma omp atomic capture
1004*67e74705SXin Li {fv = float2x.x; float2x.x = ulv - float2x.x;}
1005*67e74705SXin Li // CHECK: [[EXPR:%.+]] = load double, double* @{{.+}},
1006*67e74705SXin Li // CHECK: [[OLD_VAL:%.+]] = call i32 @llvm.read_register.i32([[REG:metadata ![0-9]+]])
1007*67e74705SXin Li // CHECK: [[X_RVAL:%.+]] = sitofp i32 [[OLD_VAL]] to double
1008*67e74705SXin Li // CHECK: [[DIV:%.+]] = fdiv double [[EXPR]], [[X_RVAL]]
1009*67e74705SXin Li // CHECK: [[NEW_VAL:%.+]] = fptosi double [[DIV]] to i32
1010*67e74705SXin Li // CHECK: call void @llvm.write_register.i32([[REG]], i32 [[NEW_VAL]])
1011*67e74705SXin Li // CHECK: store i32 [[NEW_VAL]], i32* @{{.+}},
1012*67e74705SXin Li // CHECK: call{{.*}} @__kmpc_flush(
1013*67e74705SXin Li #pragma omp atomic capture seq_cst
1014*67e74705SXin Li {rix = dv / rix; iv = rix;}
1015*67e74705SXin Li // CHECK: [[OLD_VAL:%.+]] = atomicrmw xchg i32* @{{.+}}, i32 5 monotonic
1016*67e74705SXin Li // CHECK: call void @llvm.write_register.i32([[REG]], i32 [[OLD_VAL]])
1017*67e74705SXin Li #pragma omp atomic capture
1018*67e74705SXin Li {rix = ix; ix = 5;}
1019*67e74705SXin Li return 0;
1020*67e74705SXin Li }
1021*67e74705SXin Li #endif
1022