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