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