1402 lines · c
1// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir2// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR3// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll4// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM5// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll6// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG7 8void f1(void) {9 _Atomic(int) x = 42;10}11 12// CIR-LABEL: @f113// CIR: %[[SLOT:.+]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init] {alignment = 4 : i64}14// CIR-NEXT: %[[INIT:.+]] = cir.const #cir.int<42> : !s32i15// CIR-NEXT: cir.store align(4) %[[INIT]], %[[SLOT]] : !s32i, !cir.ptr<!s32i>16// CIR: }17 18// LLVM-LABEL: @f119// LLVM: %[[SLOT:.+]] = alloca i32, i64 1, align 420// LLVM-NEXT: store i32 42, ptr %[[SLOT]], align 421// LLVM: }22 23// OGCG-LABEL: @f124// OGCG: %[[SLOT:.+]] = alloca i32, align 425// OGCG-NEXT: store i32 42, ptr %[[SLOT]], align 426// OGCG: }27 28void f2(void) {29 _Atomic(int) x;30 __c11_atomic_init(&x, 42);31}32 33// CIR-LABEL: @f234// CIR: %[[SLOT:.+]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["x"] {alignment = 4 : i64}35// CIR-NEXT: %[[INIT:.+]] = cir.const #cir.int<42> : !s32i36// CIR-NEXT: cir.store align(4) %[[INIT]], %[[SLOT]] : !s32i, !cir.ptr<!s32i>37// CIR: }38 39// LLVM-LABEL: @f240// LLVM: %[[SLOT:.+]] = alloca i32, i64 1, align 441// LLVM-NEXT: store i32 42, ptr %[[SLOT]], align 442// LLVM: }43 44// OGCG-LABEL: @f245// OGCG: %[[SLOT:.+]] = alloca i32, align 446// OGCG-NEXT: store i32 42, ptr %[[SLOT]], align 447// OGCG: }48 49void f3(_Atomic(int) *p) {50 *p = 42;51}52 53// CIR-LABEL: @f354// CIR: cir.store align(4) atomic(seq_cst) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i>55 56// LLVM-LABEL: @f357// LLVM: store atomic i32 42, ptr %{{.+}} seq_cst, align 458 59// OGCG-LABEL: @f360// OGCG: store atomic i32 42, ptr %{{.+}} seq_cst, align 461 62void f4(_Atomic(float) *p) {63 *p = 3.14;64}65 66// CIR-LABEL: @f467// CIR: cir.store align(4) atomic(seq_cst) %{{.+}}, %{{.+}} : !cir.float, !cir.ptr<!cir.float>68 69// LLVM-LABEL: @f470// LLVM: store atomic float 0x40091EB860000000, ptr %{{.+}} seq_cst, align 471 72// OGCG-LABEL: @f473// OGCG: store atomic float 0x40091EB860000000, ptr %{{.+}} seq_cst, align 474 75void load(int *ptr) {76 int x;77 __atomic_load(ptr, &x, __ATOMIC_RELAXED);78 __atomic_load(ptr, &x, __ATOMIC_CONSUME);79 __atomic_load(ptr, &x, __ATOMIC_ACQUIRE);80 __atomic_load(ptr, &x, __ATOMIC_SEQ_CST);81}82 83// CIR-LABEL: @load84// CIR: %{{.+}} = cir.load align(4) atomic(relaxed) %{{.+}} : !cir.ptr<!s32i>, !s32i85// CIR: %{{.+}} = cir.load align(4) atomic(consume) %{{.+}} : !cir.ptr<!s32i>, !s32i86// CIR: %{{.+}} = cir.load align(4) atomic(acquire) %{{.+}} : !cir.ptr<!s32i>, !s32i87// CIR: %{{.+}} = cir.load align(4) atomic(seq_cst) %{{.+}} : !cir.ptr<!s32i>, !s32i88// CIR: }89 90// LLVM-LABEL: @load91// LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} monotonic, align 492// LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} acquire, align 493// LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} acquire, align 494// LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} seq_cst, align 495// LLVM: }96 97// OGCG-LABEL: @load98// OGCG: %{{.+}} = load atomic i32, ptr %{{.+}} monotonic, align 499// OGCG: %{{.+}} = load atomic i32, ptr %{{.+}} acquire, align 4100// OGCG: %{{.+}} = load atomic i32, ptr %{{.+}} acquire, align 4101// OGCG: %{{.+}} = load atomic i32, ptr %{{.+}} seq_cst, align 4102// OGCG: }103 104void load_n(int *ptr) {105 int a;106 a = __atomic_load_n(ptr, __ATOMIC_RELAXED);107 a = __atomic_load_n(ptr, __ATOMIC_CONSUME);108 a = __atomic_load_n(ptr, __ATOMIC_ACQUIRE);109 a = __atomic_load_n(ptr, __ATOMIC_SEQ_CST);110}111 112// CIR-LABEL: @load_n113// CIR: %{{.+}} = cir.load align(4) atomic(relaxed) %{{.+}} : !cir.ptr<!s32i>, !s32i114// CIR: %{{.+}} = cir.load align(4) atomic(consume) %{{.+}} : !cir.ptr<!s32i>, !s32i115// CIR: %{{.+}} = cir.load align(4) atomic(acquire) %{{.+}} : !cir.ptr<!s32i>, !s32i116// CIR: %{{.+}} = cir.load align(4) atomic(seq_cst) %{{.+}} : !cir.ptr<!s32i>, !s32i117// CIR: }118 119// LLVM-LABEL: @load_n120// LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} monotonic, align 4121// LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} acquire, align 4122// LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} acquire, align 4123// LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} seq_cst, align 4124// LLVM: }125 126// OGCG-LABEL: @load_n127// OGCG: %{{.+}} = load atomic i32, ptr %{{.+}} monotonic, align 4128// OGCG: %{{.+}} = load atomic i32, ptr %{{.+}} acquire, align 4129// OGCG: %{{.+}} = load atomic i32, ptr %{{.+}} acquire, align 4130// OGCG: %{{.+}} = load atomic i32, ptr %{{.+}} seq_cst, align 4131// OGCG: }132 133void c11_load(_Atomic(int) *ptr) {134 __c11_atomic_load(ptr, __ATOMIC_RELAXED);135 __c11_atomic_load(ptr, __ATOMIC_CONSUME);136 __c11_atomic_load(ptr, __ATOMIC_ACQUIRE);137 __c11_atomic_load(ptr, __ATOMIC_SEQ_CST);138}139 140// CIR-LABEL: @c11_load141// CIR: %{{.+}} = cir.load align(4) atomic(relaxed) %{{.+}} : !cir.ptr<!s32i>, !s32i142// CIR: %{{.+}} = cir.load align(4) atomic(consume) %{{.+}} : !cir.ptr<!s32i>, !s32i143// CIR: %{{.+}} = cir.load align(4) atomic(acquire) %{{.+}} : !cir.ptr<!s32i>, !s32i144// CIR: %{{.+}} = cir.load align(4) atomic(seq_cst) %{{.+}} : !cir.ptr<!s32i>, !s32i145// CIR: }146 147// LLVM-LABEL: @c11_load148// LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} monotonic, align 4149// LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} acquire, align 4150// LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} acquire, align 4151// LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} seq_cst, align 4152// LLVM: }153 154// OGCG-LABEL: @c11_load155// OGCG: %{{.+}} = load atomic i32, ptr %{{.+}} monotonic, align 4156// OGCG: %{{.+}} = load atomic i32, ptr %{{.+}} acquire, align 4157// OGCG: %{{.+}} = load atomic i32, ptr %{{.+}} acquire, align 4158// OGCG: %{{.+}} = load atomic i32, ptr %{{.+}} seq_cst, align 4159// OGCG: }160 161void store(int *ptr, int x) {162 __atomic_store(ptr, &x, __ATOMIC_RELAXED);163 __atomic_store(ptr, &x, __ATOMIC_RELEASE);164 __atomic_store(ptr, &x, __ATOMIC_SEQ_CST);165}166 167// CIR-LABEL: @store168// CIR: cir.store align(4) atomic(relaxed) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i>169// CIR: cir.store align(4) atomic(release) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i>170// CIR: cir.store align(4) atomic(seq_cst) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i>171// CIR: }172 173// LLVM-LABEL: @store174// LLVM: store atomic i32 %{{.+}}, ptr %{{.+}} monotonic, align 4175// LLVM: store atomic i32 %{{.+}}, ptr %{{.+}} release, align 4176// LLVM: store atomic i32 %{{.+}}, ptr %{{.+}} seq_cst, align 4177// LLVM: }178 179// OGCG-LABEL: @store180// OGCG: store atomic i32 %{{.+}}, ptr %{{.+}} monotonic, align 4181// OGCG: store atomic i32 %{{.+}}, ptr %{{.+}} release, align 4182// OGCG: store atomic i32 %{{.+}}, ptr %{{.+}} seq_cst, align 4183// OGCG: }184 185void store_n(int *ptr, int x) {186 __atomic_store_n(ptr, x, __ATOMIC_RELAXED);187 __atomic_store_n(ptr, x, __ATOMIC_RELEASE);188 __atomic_store_n(ptr, x, __ATOMIC_SEQ_CST);189}190 191// CIR-LABEL: @store_n192// CIR: cir.store align(4) atomic(relaxed) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i>193// CIR: cir.store align(4) atomic(release) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i>194// CIR: cir.store align(4) atomic(seq_cst) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i>195// CIR: }196 197// LLVM-LABEL: @store_n198// LLVM: store atomic i32 %{{.+}}, ptr %{{.+}} monotonic, align 4199// LLVM: store atomic i32 %{{.+}}, ptr %{{.+}} release, align 4200// LLVM: store atomic i32 %{{.+}}, ptr %{{.+}} seq_cst, align 4201// LLVM: }202 203// OGCG-LABEL: @store_n204// OGCG: store atomic i32 %{{.+}}, ptr %{{.+}} monotonic, align 4205// OGCG: store atomic i32 %{{.+}}, ptr %{{.+}} release, align 4206// OGCG: store atomic i32 %{{.+}}, ptr %{{.+}} seq_cst, align 4207// OGCG: }208 209void c11_store(_Atomic(int) *ptr, int x) {210 __c11_atomic_store(ptr, x, __ATOMIC_RELAXED);211 __c11_atomic_store(ptr, x, __ATOMIC_RELEASE);212 __c11_atomic_store(ptr, x, __ATOMIC_SEQ_CST);213}214 215// CIR-LABEL: @c11_store216// CIR: cir.store align(4) atomic(relaxed) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i>217// CIR: cir.store align(4) atomic(release) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i>218// CIR: cir.store align(4) atomic(seq_cst) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i>219// CIR: }220 221// LLVM-LABEL: @c11_store222// LLVM: store atomic i32 %{{.+}}, ptr %{{.+}} monotonic, align 4223// LLVM: store atomic i32 %{{.+}}, ptr %{{.+}} release, align 4224// LLVM: store atomic i32 %{{.+}}, ptr %{{.+}} seq_cst, align 4225// LLVM: }226 227// OGCG-LABEL: @c11_store228// OGCG: store atomic i32 %{{.+}}, ptr %{{.+}} monotonic, align 4229// OGCG: store atomic i32 %{{.+}}, ptr %{{.+}} release, align 4230// OGCG: store atomic i32 %{{.+}}, ptr %{{.+}} seq_cst, align 4231// OGCG: }232 233void c11_atomic_cmpxchg_strong(_Atomic(int) *ptr, int *expected, int desired) {234 // CIR-LABEL: @c11_atomic_cmpxchg_strong235 // LLVM-LABEL: @c11_atomic_cmpxchg_strong236 // OGCG-LABEL: @c11_atomic_cmpxchg_strong237 238 __c11_atomic_compare_exchange_strong(ptr, expected, desired,239 __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE);240 // CIR: %[[OLD:.+]], %[[SUCCESS:.+]] = cir.atomic.cmpxchg success(seq_cst) failure(acquire) %{{.+}}, %{{.+}}, %{{.+}} align(4) : (!cir.ptr<!s32i>, !s32i, !s32i) -> (!s32i, !cir.bool)241 // CIR-NEXT: %[[FAILED:.+]] = cir.unary(not, %[[SUCCESS]]) : !cir.bool, !cir.bool242 // CIR-NEXT: cir.if %[[FAILED]] {243 // CIR-NEXT: cir.store align(4) %[[OLD]], %{{.+}} : !s32i, !cir.ptr<!s32i>244 // CIR-NEXT: }245 // CIR-NEXT: cir.store align(1) %[[SUCCESS]], %{{.+}} : !cir.bool, !cir.ptr<!cir.bool>246 247 // LLVM: %[[RESULT:.+]] = cmpxchg ptr %{{.+}}, i32 %{{.+}}, i32 %{{.+}} seq_cst acquire, align 4248 // LLVM-NEXT: %[[OLD:.+]] = extractvalue { i32, i1 } %[[RESULT]], 0249 // LLVM-NEXT: %[[SUCCESS:.+]] = extractvalue { i32, i1 } %[[RESULT]], 1250 // LLVM-NEXT: %[[FAILED:.+]] = xor i1 %[[SUCCESS]], true251 // LLVM-NEXT: br i1 %[[FAILED]], label %[[LABEL_FAILED:.+]], label %[[LABEL_CONT:.+]]252 // LLVM: [[LABEL_FAILED]]:253 // LLVM-NEXT: store i32 %[[OLD]], ptr %{{.+}}, align 4254 // LLVM-NEXT: br label %[[LABEL_CONT]]255 // LLVM: [[LABEL_CONT]]:256 // LLVM-NEXT: %[[SUCCESS_2:.+]] = zext i1 %[[SUCCESS]] to i8257 // LLVM-NEXT: store i8 %[[SUCCESS_2]], ptr %{{.+}}, align 1258 259 // OGCG: %[[RESULT:.+]] = cmpxchg ptr %{{.+}}, i32 %{{.+}}, i32 %{{.+}} seq_cst acquire, align 4260 // OGCG-NEXT: %[[OLD:.+]] = extractvalue { i32, i1 } %[[RESULT]], 0261 // OGCG-NEXT: %[[SUCCESS:.+]] = extractvalue { i32, i1 } %[[RESULT]], 1262 // OGCG-NEXT: br i1 %[[SUCCESS]], label %[[LABEL_CONT:.+]], label %[[LABEL_FAILED:.+]]263 // OGCG: [[LABEL_FAILED]]:264 // OGCG-NEXT: store i32 %[[OLD]], ptr %{{.+}}, align 4265 // OGCG-NEXT: br label %[[LABEL_CONT]]266 // OGCG: [[LABEL_CONT]]:267 // OGCG-NEXT: %[[SUCCESS_2:.+]] = zext i1 %[[SUCCESS]] to i8268 // OGCG-NEXT: store i8 %[[SUCCESS_2]], ptr %{{.+}}, align 1269}270 271void c11_atomic_cmpxchg_weak(_Atomic(int) *ptr, int *expected, int desired) {272 // CIR-LABEL: @c11_atomic_cmpxchg_weak273 // LLVM-LABEL: @c11_atomic_cmpxchg_weak274 // OGCG-LABEL: @c11_atomic_cmpxchg_weak275 276 __c11_atomic_compare_exchange_weak(ptr, expected, desired,277 __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE);278 // CIR: %[[OLD:.+]], %[[SUCCESS:.+]] = cir.atomic.cmpxchg weak success(seq_cst) failure(acquire) %{{.+}}, %{{.+}}, %{{.+}} align(4) : (!cir.ptr<!s32i>, !s32i, !s32i) -> (!s32i, !cir.bool)279 // CIR-NEXT: %[[FAILED:.+]] = cir.unary(not, %[[SUCCESS]]) : !cir.bool, !cir.bool280 // CIR-NEXT: cir.if %[[FAILED]] {281 // CIR-NEXT: cir.store align(4) %[[OLD]], %{{.+}} : !s32i, !cir.ptr<!s32i>282 // CIR-NEXT: }283 // CIR-NEXT: cir.store align(1) %[[SUCCESS]], %{{.+}} : !cir.bool, !cir.ptr<!cir.bool>284 285 // LLVM: %[[RESULT:.+]] = cmpxchg weak ptr %{{.+}}, i32 %{{.+}}, i32 %{{.+}} seq_cst acquire, align 4286 // LLVM-NEXT: %[[OLD:.+]] = extractvalue { i32, i1 } %[[RESULT]], 0287 // LLVM-NEXT: %[[SUCCESS:.+]] = extractvalue { i32, i1 } %[[RESULT]], 1288 // LLVM-NEXT: %[[FAILED:.+]] = xor i1 %[[SUCCESS]], true289 // LLVM-NEXT: br i1 %[[FAILED]], label %[[LABEL_FAILED:.+]], label %[[LABEL_CONT:.+]]290 // LLVM: [[LABEL_FAILED]]:291 // LLVM-NEXT: store i32 %[[OLD]], ptr %{{.+}}, align 4292 // LLVM-NEXT: br label %[[LABEL_CONT]]293 // LLVM: [[LABEL_CONT]]:294 // LLVM-NEXT: %[[SUCCESS_2:.+]] = zext i1 %[[SUCCESS]] to i8295 // LLVM-NEXT: store i8 %[[SUCCESS_2]], ptr %{{.+}}, align 1296 297 // OGCG: %[[RESULT:.+]] = cmpxchg weak ptr %{{.+}}, i32 %{{.+}}, i32 %{{.+}} seq_cst acquire, align 4298 // OGCG-NEXT: %[[OLD:.+]] = extractvalue { i32, i1 } %[[RESULT]], 0299 // OGCG-NEXT: %[[SUCCESS:.+]] = extractvalue { i32, i1 } %[[RESULT]], 1300 // OGCG-NEXT: br i1 %[[SUCCESS]], label %[[LABEL_CONT:.+]], label %[[LABEL_FAILED:.+]]301 // OGCG: [[LABEL_FAILED]]:302 // OGCG-NEXT: store i32 %[[OLD]], ptr %{{.+}}, align 4303 // OGCG-NEXT: br label %[[LABEL_CONT]]304 // OGCG: [[LABEL_CONT]]:305 // OGCG-NEXT: %[[SUCCESS_2:.+]] = zext i1 %[[SUCCESS]] to i8306 // OGCG-NEXT: store i8 %[[SUCCESS_2]], ptr %{{.+}}, align 1307}308 309void atomic_cmpxchg(int *ptr, int *expected, int *desired) {310 // CIR-LABEL: @atomic_cmpxchg311 // LLVM-LABEL: @atomic_cmpxchg312 // OGCG-LABEL: @atomic_cmpxchg313 314 __atomic_compare_exchange(ptr, expected, desired, /*weak=*/0, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE);315 // CIR: %[[OLD:.+]], %[[SUCCESS:.+]] = cir.atomic.cmpxchg success(seq_cst) failure(acquire) %{{.+}}, %{{.+}}, %{{.+}} align(4) : (!cir.ptr<!s32i>, !s32i, !s32i) -> (!s32i, !cir.bool)316 // CIR-NEXT: %[[FAILED:.+]] = cir.unary(not, %[[SUCCESS]]) : !cir.bool, !cir.bool317 // CIR-NEXT: cir.if %[[FAILED]] {318 // CIR-NEXT: cir.store align(4) %[[OLD]], %{{.+}} : !s32i, !cir.ptr<!s32i>319 // CIR-NEXT: }320 // CIR-NEXT: cir.store align(1) %[[SUCCESS]], %{{.+}} : !cir.bool, !cir.ptr<!cir.bool>321 322 // LLVM: %[[RESULT:.+]] = cmpxchg ptr %{{.+}}, i32 %{{.+}}, i32 %{{.+}} seq_cst acquire, align 4323 // LLVM-NEXT: %[[OLD:.+]] = extractvalue { i32, i1 } %[[RESULT]], 0324 // LLVM-NEXT: %[[SUCCESS:.+]] = extractvalue { i32, i1 } %[[RESULT]], 1325 // LLVM-NEXT: %[[FAILED:.+]] = xor i1 %[[SUCCESS]], true326 // LLVM-NEXT: br i1 %[[FAILED]], label %[[LABEL_FAILED:.+]], label %[[LABEL_CONT:.+]]327 // LLVM: [[LABEL_FAILED]]:328 // LLVM-NEXT: store i32 %[[OLD]], ptr %{{.+}}, align 4329 // LLVM-NEXT: br label %[[LABEL_CONT]]330 // LLVM: [[LABEL_CONT]]:331 // LLVM-NEXT: %[[SUCCESS_2:.+]] = zext i1 %[[SUCCESS]] to i8332 // LLVM-NEXT: store i8 %[[SUCCESS_2]], ptr %{{.+}}, align 1333 334 // OGCG: %[[RESULT:.+]] = cmpxchg ptr %{{.+}}, i32 %{{.+}}, i32 %{{.+}} seq_cst acquire, align 4335 // OGCG-NEXT: %[[OLD:.+]] = extractvalue { i32, i1 } %[[RESULT]], 0336 // OGCG-NEXT: %[[SUCCESS:.+]] = extractvalue { i32, i1 } %[[RESULT]], 1337 // OGCG-NEXT: br i1 %[[SUCCESS]], label %[[LABEL_CONT:.+]], label %[[LABEL_FAILED:.+]]338 // OGCG: [[LABEL_FAILED]]:339 // OGCG-NEXT: store i32 %[[OLD]], ptr %{{.+}}, align 4340 // OGCG-NEXT: br label %[[LABEL_CONT]]341 // OGCG: [[LABEL_CONT]]:342 // OGCG-NEXT: %[[SUCCESS_2:.+]] = zext i1 %[[SUCCESS]] to i8343 // OGCG-NEXT: store i8 %[[SUCCESS_2]], ptr %{{.+}}, align 1344 345 __atomic_compare_exchange(ptr, expected, desired, /*weak=*/1, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE);346 // CIR: %[[OLD:.+]], %[[SUCCESS:.+]] = cir.atomic.cmpxchg weak success(seq_cst) failure(acquire) %{{.+}}, %{{.+}}, %{{.+}} align(4) : (!cir.ptr<!s32i>, !s32i, !s32i) -> (!s32i, !cir.bool)347 // CIR-NEXT: %[[FAILED:.+]] = cir.unary(not, %[[SUCCESS]]) : !cir.bool, !cir.bool348 // CIR-NEXT: cir.if %[[FAILED]] {349 // CIR-NEXT: cir.store align(4) %[[OLD]], %{{.+}} : !s32i, !cir.ptr<!s32i>350 // CIR-NEXT: }351 // CIR-NEXT: cir.store align(1) %[[SUCCESS]], %{{.+}} : !cir.bool, !cir.ptr<!cir.bool>352 353 // LLVM: %[[RESULT:.+]] = cmpxchg weak ptr %{{.+}}, i32 %{{.+}}, i32 %{{.+}} seq_cst acquire, align 4354 // LLVM-NEXT: %[[OLD:.+]] = extractvalue { i32, i1 } %[[RESULT]], 0355 // LLVM-NEXT: %[[SUCCESS:.+]] = extractvalue { i32, i1 } %[[RESULT]], 1356 // LLVM-NEXT: %[[FAILED:.+]] = xor i1 %[[SUCCESS]], true357 // LLVM-NEXT: br i1 %[[FAILED]], label %[[LABEL_FAILED:.+]], label %[[LABEL_CONT:.+]]358 // LLVM: [[LABEL_FAILED]]:359 // LLVM-NEXT: store i32 %[[OLD]], ptr %{{.+}}, align 4360 // LLVM-NEXT: br label %[[LABEL_CONT]]361 // LLVM: [[LABEL_CONT]]:362 // LLVM-NEXT: %[[SUCCESS_2:.+]] = zext i1 %[[SUCCESS]] to i8363 // LLVM-NEXT: store i8 %[[SUCCESS_2]], ptr %{{.+}}, align 1364 365 // OGCG: %[[RESULT:.+]] = cmpxchg weak ptr %{{.+}}, i32 %{{.+}}, i32 %{{.+}} seq_cst acquire, align 4366 // OGCG-NEXT: %[[OLD:.+]] = extractvalue { i32, i1 } %[[RESULT]], 0367 // OGCG-NEXT: %[[SUCCESS:.+]] = extractvalue { i32, i1 } %[[RESULT]], 1368 // OGCG-NEXT: br i1 %[[SUCCESS]], label %[[LABEL_CONT:.+]], label %[[LABEL_FAILED:.+]]369 // OGCG: [[LABEL_FAILED]]:370 // OGCG-NEXT: store i32 %[[OLD]], ptr %{{.+}}, align 4371 // OGCG-NEXT: br label %[[LABEL_CONT]]372 // OGCG: [[LABEL_CONT]]:373 // OGCG-NEXT: %[[SUCCESS_2:.+]] = zext i1 %[[SUCCESS]] to i8374 // OGCG-NEXT: store i8 %[[SUCCESS_2]], ptr %{{.+}}, align 1375}376 377void atomic_cmpxchg_n(int *ptr, int *expected, int desired) {378 // CIR-LABEL: @atomic_cmpxchg_n379 // LLVM-LABEL: @atomic_cmpxchg_n380 // OGCG-LABEL: @atomic_cmpxchg_n381 382 __atomic_compare_exchange_n(ptr, expected, desired, /*weak=*/0, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE);383 // CIR: %[[OLD:.+]], %[[SUCCESS:.+]] = cir.atomic.cmpxchg success(seq_cst) failure(acquire) %{{.+}}, %{{.+}}, %{{.+}} align(4) : (!cir.ptr<!s32i>, !s32i, !s32i) -> (!s32i, !cir.bool)384 // CIR-NEXT: %[[FAILED:.+]] = cir.unary(not, %[[SUCCESS]]) : !cir.bool, !cir.bool385 // CIR-NEXT: cir.if %[[FAILED]] {386 // CIR-NEXT: cir.store align(4) %[[OLD]], %{{.+}} : !s32i, !cir.ptr<!s32i>387 // CIR-NEXT: }388 // CIR-NEXT: cir.store align(1) %[[SUCCESS]], %{{.+}} : !cir.bool, !cir.ptr<!cir.bool>389 390 // LLVM: %[[RESULT:.+]] = cmpxchg ptr %{{.+}}, i32 %{{.+}}, i32 %{{.+}} seq_cst acquire, align 4391 // LLVM-NEXT: %[[OLD:.+]] = extractvalue { i32, i1 } %[[RESULT]], 0392 // LLVM-NEXT: %[[SUCCESS:.+]] = extractvalue { i32, i1 } %[[RESULT]], 1393 // LLVM-NEXT: %[[FAILED:.+]] = xor i1 %[[SUCCESS]], true394 // LLVM-NEXT: br i1 %[[FAILED]], label %[[LABEL_FAILED:.+]], label %[[LABEL_CONT:.+]]395 // LLVM: [[LABEL_FAILED]]:396 // LLVM-NEXT: store i32 %[[OLD]], ptr %{{.+}}, align 4397 // LLVM-NEXT: br label %[[LABEL_CONT]]398 // LLVM: [[LABEL_CONT]]:399 // LLVM-NEXT: %[[SUCCESS_2:.+]] = zext i1 %[[SUCCESS]] to i8400 // LLVM-NEXT: store i8 %[[SUCCESS_2]], ptr %{{.+}}, align 1401 402 // OGCG: %[[RESULT:.+]] = cmpxchg ptr %{{.+}}, i32 %{{.+}}, i32 %{{.+}} seq_cst acquire, align 4403 // OGCG-NEXT: %[[OLD:.+]] = extractvalue { i32, i1 } %[[RESULT]], 0404 // OGCG-NEXT: %[[SUCCESS:.+]] = extractvalue { i32, i1 } %[[RESULT]], 1405 // OGCG-NEXT: br i1 %[[SUCCESS]], label %[[LABEL_CONT:.+]], label %[[LABEL_FAILED:.+]]406 // OGCG: [[LABEL_FAILED]]:407 // OGCG-NEXT: store i32 %[[OLD]], ptr %{{.+}}, align 4408 // OGCG-NEXT: br label %[[LABEL_CONT]]409 // OGCG: [[LABEL_CONT]]:410 // OGCG-NEXT: %[[SUCCESS_2:.+]] = zext i1 %[[SUCCESS]] to i8411 // OGCG-NEXT: store i8 %[[SUCCESS_2]], ptr %{{.+}}, align 1412 413 __atomic_compare_exchange_n(ptr, expected, desired, /*weak=*/1, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE);414 // CIR: %[[OLD:.+]], %[[SUCCESS:.+]] = cir.atomic.cmpxchg weak success(seq_cst) failure(acquire) %{{.+}}, %{{.+}}, %{{.+}} align(4) : (!cir.ptr<!s32i>, !s32i, !s32i) -> (!s32i, !cir.bool)415 // CIR-NEXT: %[[FAILED:.+]] = cir.unary(not, %[[SUCCESS]]) : !cir.bool, !cir.bool416 // CIR-NEXT: cir.if %[[FAILED]] {417 // CIR-NEXT: cir.store align(4) %[[OLD]], %{{.+}} : !s32i, !cir.ptr<!s32i>418 // CIR-NEXT: }419 // CIR-NEXT: cir.store align(1) %[[SUCCESS]], %{{.+}} : !cir.bool, !cir.ptr<!cir.bool>420 421 // LLVM: %[[RESULT:.+]] = cmpxchg weak ptr %{{.+}}, i32 %{{.+}}, i32 %{{.+}} seq_cst acquire, align 4422 // LLVM-NEXT: %[[OLD:.+]] = extractvalue { i32, i1 } %[[RESULT]], 0423 // LLVM-NEXT: %[[SUCCESS:.+]] = extractvalue { i32, i1 } %[[RESULT]], 1424 // LLVM-NEXT: %[[FAILED:.+]] = xor i1 %[[SUCCESS]], true425 // LLVM-NEXT: br i1 %[[FAILED]], label %[[LABEL_FAILED:.+]], label %[[LABEL_CONT:.+]]426 // LLVM: [[LABEL_FAILED]]:427 // LLVM-NEXT: store i32 %[[OLD]], ptr %{{.+}}, align 4428 // LLVM-NEXT: br label %[[LABEL_CONT]]429 // LLVM: [[LABEL_CONT]]:430 // LLVM-NEXT: %[[SUCCESS_2:.+]] = zext i1 %[[SUCCESS]] to i8431 // LLVM-NEXT: store i8 %[[SUCCESS_2]], ptr %{{.+}}, align 1432 433 // OGCG: %[[RESULT:.+]] = cmpxchg weak ptr %{{.+}}, i32 %{{.+}}, i32 %{{.+}} seq_cst acquire, align 4434 // OGCG-NEXT: %[[OLD:.+]] = extractvalue { i32, i1 } %[[RESULT]], 0435 // OGCG-NEXT: %[[SUCCESS:.+]] = extractvalue { i32, i1 } %[[RESULT]], 1436 // OGCG-NEXT: br i1 %[[SUCCESS]], label %[[LABEL_CONT:.+]], label %[[LABEL_FAILED:.+]]437 // OGCG: [[LABEL_FAILED]]:438 // OGCG-NEXT: store i32 %[[OLD]], ptr %{{.+}}, align 4439 // OGCG-NEXT: br label %[[LABEL_CONT]]440 // OGCG: [[LABEL_CONT]]:441 // OGCG-NEXT: %[[SUCCESS_2:.+]] = zext i1 %[[SUCCESS]] to i8442 // OGCG-NEXT: store i8 %[[SUCCESS_2]], ptr %{{.+}}, align 1443}444 445void c11_atomic_exchange(_Atomic(int) *ptr, int value) {446 // CIR-LABEL: @c11_atomic_exchange447 // LLVM-LABEL: @c11_atomic_exchange448 // OGCG-LABEL: @c11_atomic_exchange449 450 __c11_atomic_exchange(ptr, value, __ATOMIC_RELAXED);451 __c11_atomic_exchange(ptr, value, __ATOMIC_CONSUME);452 __c11_atomic_exchange(ptr, value, __ATOMIC_ACQUIRE);453 __c11_atomic_exchange(ptr, value, __ATOMIC_RELEASE);454 __c11_atomic_exchange(ptr, value, __ATOMIC_ACQ_REL);455 __c11_atomic_exchange(ptr, value, __ATOMIC_SEQ_CST);456 // CIR: %{{.+}} = cir.atomic.xchg relaxed %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i457 // CIR: %{{.+}} = cir.atomic.xchg consume %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i458 // CIR: %{{.+}} = cir.atomic.xchg acquire %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i459 // CIR: %{{.+}} = cir.atomic.xchg release %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i460 // CIR: %{{.+}} = cir.atomic.xchg acq_rel %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i461 // CIR: %{{.+}} = cir.atomic.xchg seq_cst %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i462 463 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} monotonic, align 4464 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acquire, align 4465 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acquire, align 4466 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} release, align 4467 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acq_rel, align 4468 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4469 470 // OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} monotonic, align 4471 // OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acquire, align 4472 // OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acquire, align 4473 // OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} release, align 4474 // OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acq_rel, align 4475 // OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4476}477 478void atomic_exchange(int *ptr, int *value, int *old) {479 // CIR-LABEL: @atomic_exchange480 // LLVM-LABEL: @atomic_exchange481 // OGCG-LABEL: @atomic_exchange482 483 __atomic_exchange(ptr, value, old, __ATOMIC_RELAXED);484 __atomic_exchange(ptr, value, old, __ATOMIC_CONSUME);485 __atomic_exchange(ptr, value, old, __ATOMIC_ACQUIRE);486 __atomic_exchange(ptr, value, old, __ATOMIC_RELEASE);487 __atomic_exchange(ptr, value, old, __ATOMIC_ACQ_REL);488 __atomic_exchange(ptr, value, old, __ATOMIC_SEQ_CST);489 // CIR: %{{.+}} = cir.atomic.xchg relaxed %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i490 // CIR: %{{.+}} = cir.atomic.xchg consume %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i491 // CIR: %{{.+}} = cir.atomic.xchg acquire %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i492 // CIR: %{{.+}} = cir.atomic.xchg release %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i493 // CIR: %{{.+}} = cir.atomic.xchg acq_rel %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i494 // CIR: %{{.+}} = cir.atomic.xchg seq_cst %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i495 496 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} monotonic, align 4497 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acquire, align 4498 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acquire, align 4499 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} release, align 4500 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acq_rel, align 4501 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4502 503 // OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} monotonic, align 4504 // OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acquire, align 4505 // OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acquire, align 4506 // OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} release, align 4507 // OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acq_rel, align 4508 // OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4509}510 511void atomic_exchange_n(int *ptr, int value) {512 // CIR-LABEL: @atomic_exchange_n513 // LLVM-LABEL: @atomic_exchange_n514 // OGCG-LABEL: @atomic_exchange_n515 516 __atomic_exchange_n(ptr, value, __ATOMIC_RELAXED);517 __atomic_exchange_n(ptr, value, __ATOMIC_CONSUME);518 __atomic_exchange_n(ptr, value, __ATOMIC_ACQUIRE);519 __atomic_exchange_n(ptr, value, __ATOMIC_RELEASE);520 __atomic_exchange_n(ptr, value, __ATOMIC_ACQ_REL);521 __atomic_exchange_n(ptr, value, __ATOMIC_SEQ_CST);522 // CIR: %{{.+}} = cir.atomic.xchg relaxed %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i523 // CIR: %{{.+}} = cir.atomic.xchg consume %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i524 // CIR: %{{.+}} = cir.atomic.xchg acquire %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i525 // CIR: %{{.+}} = cir.atomic.xchg release %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i526 // CIR: %{{.+}} = cir.atomic.xchg acq_rel %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i527 // CIR: %{{.+}} = cir.atomic.xchg seq_cst %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i528 529 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} monotonic, align 4530 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acquire, align 4531 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acquire, align 4532 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} release, align 4533 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acq_rel, align 4534 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4535 536 // OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} monotonic, align 4537 // OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acquire, align 4538 // OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acquire, align 4539 // OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} release, align 4540 // OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acq_rel, align 4541 // OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4542}543 544void test_and_set(void *p) {545 // CIR-LABEL: @test_and_set546 // LLVM-LABEL: @test_and_set547 // OGCG-LABEL: @test_and_set548 549 __atomic_test_and_set(p, __ATOMIC_SEQ_CST);550 // CIR: %[[VOID_PTR:.+]] = cir.load align(8) %{{.+}} : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>551 // CIR-NEXT: %[[PTR:.+]] = cir.cast bitcast %[[VOID_PTR]] : !cir.ptr<!void> -> !cir.ptr<!s8i>552 // CIR-NEXT: %[[RES:.+]] = cir.atomic.test_and_set seq_cst %[[PTR]] : !cir.ptr<!s8i> -> !cir.bool553 // CIR-NEXT: cir.store align(1) %[[RES]], %{{.+}} : !cir.bool, !cir.ptr<!cir.bool>554 555 // LLVM: %[[PTR:.+]] = load ptr, ptr %{{.+}}, align 8556 // LLVM-NEXT: %[[RES:.+]] = atomicrmw xchg ptr %[[PTR]], i8 1 seq_cst, align 1557 // LLVM-NEXT: %{{.+}} = icmp ne i8 %[[RES]], 0558 559 // OGCG: %[[PTR:.+]] = load ptr, ptr %{{.+}}, align 8560 // OGCG-NEXT: %[[RES:.+]] = atomicrmw xchg ptr %[[PTR]], i8 1 seq_cst, align 1561 // OGCG-NEXT: %{{.+}} = icmp ne i8 %[[RES]], 0562}563 564void test_and_set_volatile(volatile void *p) {565 // CIR-LABEL: @test_and_set_volatile566 // LLVM-LABEL: @test_and_set_volatile567 // OGCG-LABEL: @test_and_set_volatile568 569 __atomic_test_and_set(p, __ATOMIC_SEQ_CST);570 // CIR: %[[VOID_PTR:.+]] = cir.load align(8) %{{.+}} : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>571 // CIR-NEXT: %[[PTR:.+]] = cir.cast bitcast %[[VOID_PTR]] : !cir.ptr<!void> -> !cir.ptr<!s8i>572 // CIR-NEXT: %[[RES:.+]] = cir.atomic.test_and_set seq_cst %[[PTR]] volatile : !cir.ptr<!s8i> -> !cir.bool573 // CIR-NEXT: cir.store align(1) %[[RES]], %{{.+}} : !cir.bool, !cir.ptr<!cir.bool>574 575 // LLVM: %[[PTR:.+]] = load ptr, ptr %{{.+}}, align 8576 // LLVM-NEXT: %[[RES:.+]] = atomicrmw volatile xchg ptr %[[PTR]], i8 1 seq_cst, align 1577 // LLVM-NEXT: %{{.+}} = icmp ne i8 %[[RES]], 0578 579 // OGCG: %[[PTR:.+]] = load ptr, ptr %{{.+}}, align 8580 // OGCG-NEXT: %[[RES:.+]] = atomicrmw volatile xchg ptr %[[PTR]], i8 1 seq_cst, align 1581 // OGCG-NEXT: %{{.+}} = icmp ne i8 %[[RES]], 0582}583 584void clear(void *p) {585 // CIR-LABEL: @clear586 // LLVM-LABEL: @clear587 // OGCG-LABEL: @clear588 589 __atomic_clear(p, __ATOMIC_SEQ_CST);590 // CIR: %[[VOID_PTR:.+]] = cir.load align(8) %{{.+}} : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>591 // CIR-NEXT: %[[PTR:.+]] = cir.cast bitcast %[[VOID_PTR]] : !cir.ptr<!void> -> !cir.ptr<!s8i>592 // CIR: cir.atomic.clear seq_cst %[[PTR]] : !cir.ptr<!s8i>593 594 // LLVM: store atomic i8 0, ptr %{{.+}} seq_cst, align 1595 596 // OGCG: store atomic i8 0, ptr %{{.+}} seq_cst, align 1597}598 599void clear_volatile(volatile void *p) {600 // CIR-LABEL: @clear_volatile601 // LLVM-LABEL: @clear_volatile602 // OGCG-LABEL: @clear_volatile603 604 __atomic_clear(p, __ATOMIC_SEQ_CST);605 // CIR: %[[VOID_PTR:.+]] = cir.load align(8) %{{.+}} : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>606 // CIR-NEXT: %[[PTR:.+]] = cir.cast bitcast %[[VOID_PTR]] : !cir.ptr<!void> -> !cir.ptr<!s8i>607 // CIR: cir.atomic.clear seq_cst %[[PTR]] volatile : !cir.ptr<!s8i>608 609 // LLVM: store atomic volatile i8 0, ptr %{{.+}} seq_cst, align 1610 611 // OGCG: store atomic volatile i8 0, ptr %{{.+}} seq_cst, align 1612}613 614int atomic_fetch_add(int *ptr, int value) {615 // CIR-LABEL: @atomic_fetch_add616 // LLVM-LABEL: @atomic_fetch_add617 // OGCG-LABEL: @atomic_fetch_add618 619 return __atomic_fetch_add(ptr, value, __ATOMIC_SEQ_CST);620 // CIR: %{{.+}} = cir.atomic.fetch add seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i621 622 // LLVM: %[[RES:.+]] = atomicrmw add ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4623 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4624 625 // OGCG: %[[RES:.+]] = atomicrmw add ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4626 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4627}628 629int atomic_add_fetch(int *ptr, int value) {630 // CIR-LABEL: @atomic_add_fetch631 // LLVM-LABEL: @atomic_add_fetch632 // OGCG-LABEL: @atomic_add_fetch633 634 return __atomic_add_fetch(ptr, value, __ATOMIC_SEQ_CST);635 // CIR: %{{.+}} = cir.atomic.fetch add seq_cst %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i636 637 // LLVM: %[[OLD:.+]] = atomicrmw add ptr %{{.+}}, i32 %[[VAL:.+]] seq_cst, align 4638 // LLVM-NEXT: %[[RES:.+]] = add i32 %[[OLD]], %[[VAL]]639 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4640 641 // OGCG: %[[OLD:.+]] = atomicrmw add ptr %{{.+}}, i32 %[[VAL:.+]] seq_cst, align 4642 // OGCG-NEXT: %[[RES:.+]] = add i32 %[[OLD]], %[[VAL]]643 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4644}645 646int c11_atomic_fetch_add(_Atomic(int) *ptr, int value) {647 // CIR-LABEL: @c11_atomic_fetch_add648 // LLVM-LABEL: @c11_atomic_fetch_add649 // OGCG-LABEL: @c11_atomic_fetch_add650 651 return __c11_atomic_fetch_add(ptr, value, __ATOMIC_SEQ_CST);652 // CIR: %{{.+}} = cir.atomic.fetch add seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i653 654 // LLVM: %[[RES:.+]] = atomicrmw add ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4655 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4656 657 // OGCG: %[[RES:.+]] = atomicrmw add ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4658 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4659}660 661int atomic_fetch_sub(int *ptr, int value) {662 // CIR-LABEL: @atomic_fetch_sub663 // LLVM-LABEL: @atomic_fetch_sub664 // OGCG-LABEL: @atomic_fetch_sub665 666 return __atomic_fetch_sub(ptr, value, __ATOMIC_SEQ_CST);667 // CIR: %{{.+}} = cir.atomic.fetch sub seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i668 669 // LLVM: %[[RES:.+]] = atomicrmw sub ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4670 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4671 672 // OGCG: %[[RES:.+]] = atomicrmw sub ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4673 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4674}675 676int atomic_sub_fetch(int *ptr, int value) {677 // CIR-LABEL: @atomic_sub_fetch678 // LLVM-LABEL: @atomic_sub_fetch679 // OGCG-LABEL: @atomic_sub_fetch680 681 return __atomic_sub_fetch(ptr, value, __ATOMIC_SEQ_CST);682 // CIR: %{{.+}} = cir.atomic.fetch sub seq_cst %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i683 684 // LLVM: %[[OLD:.+]] = atomicrmw sub ptr %{{.+}}, i32 %[[VAL:.+]] seq_cst, align 4685 // LLVM-NEXT: %[[RES:.+]] = sub i32 %[[OLD]], %[[VAL]]686 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4687 688 // OGCG: %[[OLD:.+]] = atomicrmw sub ptr %{{.+}}, i32 %[[VAL:.+]] seq_cst, align 4689 // OGCG-NEXT: %[[RES:.+]] = sub i32 %[[OLD]], %[[VAL]]690 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4691}692 693int c11_atomic_fetch_sub(_Atomic(int) *ptr, int value) {694 // CIR-LABEL: @c11_atomic_fetch_sub695 // LLVM-LABEL: @c11_atomic_fetch_sub696 // OGCG-LABEL: @c11_atomic_fetch_sub697 698 return __c11_atomic_fetch_sub(ptr, value, __ATOMIC_SEQ_CST);699 // CIR: %{{.+}} = cir.atomic.fetch sub seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i700 701 // LLVM: %[[RES:.+]] = atomicrmw sub ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4702 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4703 704 // OGCG: %[[RES:.+]] = atomicrmw sub ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4705 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4706}707 708float atomic_fetch_add_fp(float *ptr, float value) {709 // CIR-LABEL: @atomic_fetch_add_fp710 // LLVM-LABEL: @atomic_fetch_add_fp711 // OGCG-LABEL: @atomic_fetch_add_fp712 713 return __atomic_fetch_add(ptr, value, __ATOMIC_SEQ_CST);714 // CIR: %{{.+}} = cir.atomic.fetch add seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!cir.float>, !cir.float) -> !cir.float715 716 // LLVM: %[[RES:.+]] = atomicrmw fadd ptr %{{.+}}, float %{{.+}} seq_cst, align 4717 // LLVM-NEXT: store float %[[RES]], ptr %{{.+}}, align 4718 719 // OGCG: %[[RES:.+]] = atomicrmw fadd ptr %{{.+}}, float %{{.+}} seq_cst, align 4720 // OGCG-NEXT: store float %[[RES]], ptr %{{.+}}, align 4721}722 723float atomic_add_fetch_fp(float *ptr, float value) {724 // CIR-LABEL: @atomic_add_fetch_fp725 // LLVM-LABEL: @atomic_add_fetch_fp726 // OGCG-LABEL: @atomic_add_fetch_fp727 728 return __atomic_add_fetch(ptr, value, __ATOMIC_SEQ_CST);729 // CIR: %{{.+}} = cir.atomic.fetch add seq_cst %{{.+}}, %{{.+}} : (!cir.ptr<!cir.float>, !cir.float) -> !cir.float730 731 // LLVM: %[[OLD:.+]] = atomicrmw fadd ptr %{{.+}}, float %[[VAL:.+]] seq_cst, align 4732 // LLVM-NEXT: %[[RES:.+]] = fadd float %[[OLD]], %[[VAL]]733 // LLVM-NEXT: store float %[[RES]], ptr %{{.+}}, align 4734 735 // OGCG: %[[OLD:.+]] = atomicrmw fadd ptr %{{.+}}, float %[[VAL:.+]] seq_cst, align 4736 // OGCG-NEXT: %[[RES:.+]] = fadd float %[[OLD]], %[[VAL]]737 // OGCG-NEXT: store float %[[RES]], ptr %{{.+}}, align 4738}739 740float c11_atomic_fetch_sub_fp(_Atomic(float) *ptr, float value) {741 // CIR-LABEL: @c11_atomic_fetch_sub_fp742 // LLVM-LABEL: @c11_atomic_fetch_sub_fp743 // OGCG-LABEL: @c11_atomic_fetch_sub_fp744 745 return __c11_atomic_fetch_sub(ptr, value, __ATOMIC_SEQ_CST);746 // CIR: %{{.+}} = cir.atomic.fetch sub seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!cir.float>, !cir.float) -> !cir.float747 748 // LLVM: %[[RES:.+]] = atomicrmw fsub ptr %{{.+}}, float %{{.+}} seq_cst, align 4749 // LLVM-NEXT: store float %[[RES]], ptr %{{.+}}, align 4750 751 // OGCG: %[[RES:.+]] = atomicrmw fsub ptr %{{.+}}, float %{{.+}} seq_cst, align 4752 // OGCG-NEXT: store float %[[RES]], ptr %{{.+}}, align 4753}754 755int atomic_fetch_min(int *ptr, int value) {756 // CIR-LABEL: @atomic_fetch_min757 // LLVM-LABEL: @atomic_fetch_min758 // OGCG-LABEL: @atomic_fetch_min759 760 return __atomic_fetch_min(ptr, value, __ATOMIC_SEQ_CST);761 // CIR: %{{.+}} = cir.atomic.fetch min seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i762 763 // LLVM: %[[RES:.+]] = atomicrmw min ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4764 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4765 766 // OGCG: %[[RES:.+]] = atomicrmw min ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4767 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4768}769 770int atomic_min_fetch(int *ptr, int value) {771 // CIR-LABEL: @atomic_min_fetch772 // LLVM-LABEL: @atomic_min_fetch773 // OGCG-LABEL: @atomic_min_fetch774 775 return __atomic_min_fetch(ptr, value, __ATOMIC_SEQ_CST);776 // CIR: %{{.+}} = cir.atomic.fetch min seq_cst %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i777 778 // LLVM: %[[OLD:.+]] = atomicrmw min ptr %{{.+}}, i32 %[[VAL:.+]] seq_cst, align 4779 // LLVM-NEXT: %[[OLD_LESS:.+]] = icmp slt i32 %[[OLD]], %[[VAL]]780 // LLVM-NEXT: %[[RES:.+]] = select i1 %[[OLD_LESS]], i32 %[[OLD]], i32 %[[VAL]]781 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4782 783 // OGCG: %[[OLD:.+]] = atomicrmw min ptr %{{.+}}, i32 %[[VAL:.+]] seq_cst, align 4784 // OGCG-NEXT: %[[OLD_LESS:.+]] = icmp slt i32 %[[OLD]], %[[VAL]]785 // OGCG-NEXT: %[[RES:.+]] = select i1 %[[OLD_LESS]], i32 %[[OLD]], i32 %[[VAL]]786 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4787}788 789int c11_atomic_fetch_min(_Atomic(int) *ptr, int value) {790 // CIR-LABEL: @c11_atomic_fetch_min791 // LLVM-LABEL: @c11_atomic_fetch_min792 // OGCG-LABEL: @c11_atomic_fetch_min793 794 return __c11_atomic_fetch_min(ptr, value, __ATOMIC_SEQ_CST);795 // CIR: %{{.+}} = cir.atomic.fetch min seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i796 797 // LLVM: %[[RES:.+]] = atomicrmw min ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4798 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4799 800 // OGCG: %[[RES:.+]] = atomicrmw min ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4801 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4802}803 804float atomic_fetch_min_fp(float *ptr, float value) {805 // CIR-LABEL: @atomic_fetch_min_fp806 // LLVM-LABEL: @atomic_fetch_min_fp807 // OGCG-LABEL: @atomic_fetch_min_fp808 809 return __atomic_fetch_min(ptr, value, __ATOMIC_SEQ_CST);810 // CIR: %{{.+}} = cir.atomic.fetch min seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!cir.float>, !cir.float) -> !cir.float811 812 // LLVM: %[[RES:.+]] = atomicrmw fmin ptr %{{.+}}, float %{{.+}} seq_cst, align 4813 // LLVM-NEXT: store float %[[RES]], ptr %{{.+}}, align 4814 815 // OGCG: %[[RES:.+]] = atomicrmw fmin ptr %{{.+}}, float %{{.+}} seq_cst, align 4816 // OGCG-NEXT: store float %[[RES]], ptr %{{.+}}, align 4817}818 819float atomic_min_fetch_fp(float *ptr, float value) {820 // CIR-LABEL: @atomic_min_fetch_fp821 // LLVM-LABEL: @atomic_min_fetch_fp822 // OGCG-LABEL: @atomic_min_fetch_fp823 824 return __atomic_min_fetch(ptr, value, __ATOMIC_SEQ_CST);825 // CIR: %{{.+}} = cir.atomic.fetch min seq_cst %{{.+}}, %{{.+}} : (!cir.ptr<!cir.float>, !cir.float) -> !cir.float826 827 // LLVM: %[[OLD:.+]] = atomicrmw fmin ptr %{{.+}}, float %[[VAL:.+]] seq_cst, align 4828 // LLVM-NEXT: %[[RES:.+]] = call float @llvm.minnum.f32(float %[[OLD]], float %[[VAL]])829 // LLVM-NEXT: store float %[[RES]], ptr %{{.+}}, align 4830 831 // OGCG: %[[OLD:.+]] = atomicrmw fmin ptr %{{.+}}, float %[[VAL:.+]] seq_cst, align 4832 // OGCG-NEXT: %[[RES:.+]] = call float @llvm.minnum.f32(float %[[OLD]], float %[[VAL]])833 // OGCG-NEXT: store float %[[RES]], ptr %{{.+}}, align 4834}835 836float c11_atomic_fetch_min_fp(_Atomic(float) *ptr, float value) {837 // CIR-LABEL: @c11_atomic_fetch_min_fp838 // LLVM-LABEL: @c11_atomic_fetch_min_fp839 // OGCG-LABEL: @c11_atomic_fetch_min_fp840 841 return __c11_atomic_fetch_min(ptr, value, __ATOMIC_SEQ_CST);842 // CIR: %{{.+}} = cir.atomic.fetch min seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!cir.float>, !cir.float) -> !cir.float843 844 // LLVM: %[[RES:.+]] = atomicrmw fmin ptr %{{.+}}, float %{{.+}} seq_cst, align 4845 // LLVM-NEXT: store float %[[RES]], ptr %{{.+}}, align 4846 847 // OGCG: %[[RES:.+]] = atomicrmw fmin ptr %{{.+}}, float %{{.+}} seq_cst, align 4848 // OGCG-NEXT: store float %[[RES]], ptr %{{.+}}, align 4849}850 851int atomic_fetch_max(int *ptr, int value) {852 // CIR-LABEL: @atomic_fetch_max853 // LLVM-LABEL: @atomic_fetch_max854 // OGCG-LABEL: @atomic_fetch_max855 856 return __atomic_fetch_max(ptr, value, __ATOMIC_SEQ_CST);857 // CIR: %{{.+}} = cir.atomic.fetch max seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i858 859 // LLVM: %[[RES:.+]] = atomicrmw max ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4860 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4861 862 // OGCG: %[[RES:.+]] = atomicrmw max ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4863 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4864}865 866int atomic_max_fetch(int *ptr, int value) {867 // CIR-LABEL: @atomic_max_fetch868 // LLVM-LABEL: @atomic_max_fetch869 // OGCG-LABEL: @atomic_max_fetch870 871 return __atomic_max_fetch(ptr, value, __ATOMIC_SEQ_CST);872 // CIR: %{{.+}} = cir.atomic.fetch max seq_cst %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i873 874 // LLVM: %[[OLD:.+]] = atomicrmw max ptr %{{.+}}, i32 %[[VAL:.+]] seq_cst, align 4875 // LLVM-NEXT: %[[OLD_GREATER:.+]] = icmp sgt i32 %[[OLD]], %[[VAL]]876 // LLVM-NEXT: %[[RES:.+]] = select i1 %[[OLD_GREATER]], i32 %[[OLD]], i32 %[[VAL]]877 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4878 879 // OGCG: %[[OLD:.+]] = atomicrmw max ptr %{{.+}}, i32 %[[VAL:.+]] seq_cst, align 4880 // OGCG-NEXT: %[[OLD_GREATER:.+]] = icmp sgt i32 %[[OLD]], %[[VAL]]881 // OGCG-NEXT: %[[RES:.+]] = select i1 %[[OLD_GREATER]], i32 %[[OLD]], i32 %[[VAL]]882 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4883}884 885int c11_atomic_fetch_max(_Atomic(int) *ptr, int value) {886 // CIR-LABEL: @c11_atomic_fetch_max887 // LLVM-LABEL: @c11_atomic_fetch_max888 // OGCG-LABEL: @c11_atomic_fetch_max889 890 return __c11_atomic_fetch_max(ptr, value, __ATOMIC_SEQ_CST);891 // CIR: %{{.+}} = cir.atomic.fetch max seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i892 893 // LLVM: %[[RES:.+]] = atomicrmw max ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4894 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4895 896 // OGCG: %[[RES:.+]] = atomicrmw max ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4897 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4898}899 900float atomic_fetch_max_fp(float *ptr, float value) {901 // CIR-LABEL: @atomic_fetch_max_fp902 // LLVM-LABEL: @atomic_fetch_max_fp903 // OGCG-LABEL: @atomic_fetch_max_fp904 905 return __atomic_fetch_max(ptr, value, __ATOMIC_SEQ_CST);906 // CIR: %{{.+}} = cir.atomic.fetch max seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!cir.float>, !cir.float) -> !cir.float907 908 // LLVM: %[[RES:.+]] = atomicrmw fmax ptr %{{.+}}, float %{{.+}} seq_cst, align 4909 // LLVM-NEXT: store float %[[RES]], ptr %{{.+}}, align 4910 911 // OGCG: %[[RES:.+]] = atomicrmw fmax ptr %{{.+}}, float %{{.+}} seq_cst, align 4912 // OGCG-NEXT: store float %[[RES]], ptr %{{.+}}, align 4913}914 915float atomic_max_fetch_fp(float *ptr, float value) {916 // CIR-LABEL: @atomic_max_fetch_fp917 // LLVM-LABEL: @atomic_max_fetch_fp918 // OGCG-LABEL: @atomic_max_fetch_fp919 920 return __atomic_max_fetch(ptr, value, __ATOMIC_SEQ_CST);921 // CIR: %{{.+}} = cir.atomic.fetch max seq_cst %{{.+}}, %{{.+}} : (!cir.ptr<!cir.float>, !cir.float) -> !cir.float922 923 // LLVM: %[[OLD:.+]] = atomicrmw fmax ptr %{{.+}}, float %[[VAL:.+]] seq_cst, align 4924 // LLVM-NEXT: %[[RES:.+]] = call float @llvm.maxnum.f32(float %[[OLD]], float %[[VAL]])925 // LLVM-NEXT: store float %[[RES]], ptr %{{.+}}, align 4926 927 // OGCG: %[[OLD:.+]] = atomicrmw fmax ptr %{{.+}}, float %[[VAL:.+]] seq_cst, align 4928 // OGCG-NEXT: %[[RES:.+]] = call float @llvm.maxnum.f32(float %[[OLD]], float %[[VAL]])929 // OGCG-NEXT: store float %[[RES]], ptr %{{.+}}, align 4930}931 932float c11_atomic_fetch_max_fp(_Atomic(float) *ptr, float value) {933 // CIR-LABEL: @c11_atomic_fetch_max_fp934 // LLVM-LABEL: @c11_atomic_fetch_max_fp935 // OGCG-LABEL: @c11_atomic_fetch_max_fp936 937 return __c11_atomic_fetch_max(ptr, value, __ATOMIC_SEQ_CST);938 // CIR: %{{.+}} = cir.atomic.fetch max seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!cir.float>, !cir.float) -> !cir.float939 940 // LLVM: %[[RES:.+]] = atomicrmw fmax ptr %{{.+}}, float %{{.+}} seq_cst, align 4941 // LLVM-NEXT: store float %[[RES]], ptr %{{.+}}, align 4942 943 // OGCG: %[[RES:.+]] = atomicrmw fmax ptr %{{.+}}, float %{{.+}} seq_cst, align 4944 // OGCG-NEXT: store float %[[RES]], ptr %{{.+}}, align 4945}946 947int atomic_fetch_and(int *ptr, int value) {948 // CIR-LABEL: @atomic_fetch_and949 // LLVM-LABEL: @atomic_fetch_and950 // OGCG-LABEL: @atomic_fetch_and951 952 return __atomic_fetch_and(ptr, value, __ATOMIC_SEQ_CST);953 // CIR: %{{.+}} = cir.atomic.fetch and seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i954 955 // LLVM: %[[RES:.+]] = atomicrmw and ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4956 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4957 958 // OGCG: %[[RES:.+]] = atomicrmw and ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4959 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4960}961 962int atomic_and_fetch(int *ptr, int value) {963 // CIR-LABEL: @atomic_and_fetch964 // LLVM-LABEL: @atomic_and_fetch965 // OGCG-LABEL: @atomic_and_fetch966 967 return __atomic_and_fetch(ptr, value, __ATOMIC_SEQ_CST);968 // CIR: %{{.+}} = cir.atomic.fetch and seq_cst %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i969 970 // LLVM: %[[OLD:.+]] = atomicrmw and ptr %{{.+}}, i32 %[[VAL:.+]] seq_cst, align 4971 // LLVM-NEXT: %[[RES:.+]] = and i32 %[[OLD]], %[[VAL]]972 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4973 974 // OGCG: %[[OLD:.+]] = atomicrmw and ptr %{{.+}}, i32 %[[VAL:.+]] seq_cst, align 4975 // OGCG-NEXT: %[[RES:.+]] = and i32 %[[OLD]], %[[VAL]]976 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4977}978 979int c11_atomic_fetch_and(_Atomic(int) *ptr, int value) {980 // CIR-LABEL: @c11_atomic_fetch_and981 // LLVM-LABEL: @c11_atomic_fetch_and982 // OGCG-LABEL: @c11_atomic_fetch_and983 984 return __c11_atomic_fetch_and(ptr, value, __ATOMIC_SEQ_CST);985 // CIR: %{{.+}} = cir.atomic.fetch and seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i986 987 // LLVM: %[[RES:.+]] = atomicrmw and ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4988 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4989 990 // OGCG: %[[RES:.+]] = atomicrmw and ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4991 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4992}993 994int atomic_fetch_or(int *ptr, int value) {995 // CIR-LABEL: @atomic_fetch_or996 // LLVM-LABEL: @atomic_fetch_or997 // OGCG-LABEL: @atomic_fetch_or998 999 return __atomic_fetch_or(ptr, value, __ATOMIC_SEQ_CST);1000 // CIR: %{{.+}} = cir.atomic.fetch or seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i1001 1002 // LLVM: %[[RES:.+]] = atomicrmw or ptr %{{.+}}, i32 %{{.+}} seq_cst, align 41003 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 41004 1005 // OGCG: %[[RES:.+]] = atomicrmw or ptr %{{.+}}, i32 %{{.+}} seq_cst, align 41006 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 41007}1008 1009int atomic_or_fetch(int *ptr, int value) {1010 // CIR-LABEL: @atomic_or_fetch1011 // LLVM-LABEL: @atomic_or_fetch1012 // OGCG-LABEL: @atomic_or_fetch1013 1014 return __atomic_or_fetch(ptr, value, __ATOMIC_SEQ_CST);1015 // CIR: %{{.+}} = cir.atomic.fetch or seq_cst %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i1016 1017 // LLVM: %[[OLD:.+]] = atomicrmw or ptr %{{.+}}, i32 %[[VAL:.+]] seq_cst, align 41018 // LLVM-NEXT: %[[RES:.+]] = or i32 %[[OLD]], %[[VAL]]1019 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 41020 1021 // OGCG: %[[OLD:.+]] = atomicrmw or ptr %{{.+}}, i32 %[[VAL:.+]] seq_cst, align 41022 // OGCG-NEXT: %[[RES:.+]] = or i32 %[[OLD]], %[[VAL]]1023 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 41024}1025 1026int c11_atomic_fetch_or(_Atomic(int) *ptr, int value) {1027 // CIR-LABEL: @c11_atomic_fetch_or1028 // LLVM-LABEL: @c11_atomic_fetch_or1029 // OGCG-LABEL: @c11_atomic_fetch_or1030 1031 return __c11_atomic_fetch_or(ptr, value, __ATOMIC_SEQ_CST);1032 // CIR: %{{.+}} = cir.atomic.fetch or seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i1033 1034 // LLVM: %[[RES:.+]] = atomicrmw or ptr %{{.+}}, i32 %{{.+}} seq_cst, align 41035 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 41036 1037 // OGCG: %[[RES:.+]] = atomicrmw or ptr %{{.+}}, i32 %{{.+}} seq_cst, align 41038 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 41039}1040 1041int atomic_fetch_xor(int *ptr, int value) {1042 // CIR-LABEL: @atomic_fetch_xor1043 // LLVM-LABEL: @atomic_fetch_xor1044 // OGCG-LABEL: @atomic_fetch_xor1045 1046 return __atomic_fetch_xor(ptr, value, __ATOMIC_SEQ_CST);1047 // CIR: %{{.+}} = cir.atomic.fetch xor seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i1048 1049 // LLVM: %[[RES:.+]] = atomicrmw xor ptr %{{.+}}, i32 %{{.+}} seq_cst, align 41050 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 41051 1052 // OGCG: %[[RES:.+]] = atomicrmw xor ptr %{{.+}}, i32 %{{.+}} seq_cst, align 41053 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 41054}1055 1056int atomic_xor_fetch(int *ptr, int value) {1057 // CIR-LABEL: @atomic_xor_fetch1058 // LLVM-LABEL: @atomic_xor_fetch1059 // OGCG-LABEL: @atomic_xor_fetch1060 1061 return __atomic_xor_fetch(ptr, value, __ATOMIC_SEQ_CST);1062 // CIR: %{{.+}} = cir.atomic.fetch xor seq_cst %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i1063 1064 // LLVM: %[[OLD:.+]] = atomicrmw xor ptr %{{.+}}, i32 %[[VAL:.+]] seq_cst, align 41065 // LLVM-NEXT: %[[RES:.+]] = xor i32 %[[OLD]], %[[VAL]]1066 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 41067 1068 // OGCG: %[[OLD:.+]] = atomicrmw xor ptr %{{.+}}, i32 %[[VAL:.+]] seq_cst, align 41069 // OGCG-NEXT: %[[RES:.+]] = xor i32 %[[OLD]], %[[VAL]]1070 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 41071}1072 1073int c11_atomic_fetch_xor(_Atomic(int) *ptr, int value) {1074 // CIR-LABEL: @c11_atomic_fetch_xor1075 // LLVM-LABEL: @c11_atomic_fetch_xor1076 // OGCG-LABEL: @c11_atomic_fetch_xor1077 1078 return __c11_atomic_fetch_xor(ptr, value, __ATOMIC_SEQ_CST);1079 // CIR: %{{.+}} = cir.atomic.fetch xor seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i1080 1081 // LLVM: %[[RES:.+]] = atomicrmw xor ptr %{{.+}}, i32 %{{.+}} seq_cst, align 41082 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 41083 1084 // OGCG: %[[RES:.+]] = atomicrmw xor ptr %{{.+}}, i32 %{{.+}} seq_cst, align 41085 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 41086}1087 1088int atomic_fetch_nand(int *ptr, int value) {1089 // CIR-LABEL: @atomic_fetch_nand1090 // LLVM-LABEL: @atomic_fetch_nand1091 // OGCG-LABEL: @atomic_fetch_nand1092 1093 return __atomic_fetch_nand(ptr, value, __ATOMIC_SEQ_CST);1094 // CIR: %{{.+}} = cir.atomic.fetch nand seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i1095 1096 // LLVM: %[[RES:.+]] = atomicrmw nand ptr %{{.+}}, i32 %{{.+}} seq_cst, align 41097 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 41098 1099 // OGCG: %[[RES:.+]] = atomicrmw nand ptr %{{.+}}, i32 %{{.+}} seq_cst, align 41100 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 41101}1102 1103int atomic_nand_fetch(int *ptr, int value) {1104 // CIR-LABEL: @atomic_nand_fetch1105 // LLVM-LABEL: @atomic_nand_fetch1106 // OGCG-LABEL: @atomic_nand_fetch1107 1108 return __atomic_nand_fetch(ptr, value, __ATOMIC_SEQ_CST);1109 // CIR: %{{.+}} = cir.atomic.fetch nand seq_cst %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i1110 1111 // LLVM: %[[OLD:.+]] = atomicrmw nand ptr %{{.+}}, i32 %[[VAL:.+]] seq_cst, align 41112 // LLVM-NEXT: %[[TMP:.+]] = and i32 %[[OLD]], %[[VAL]]1113 // LLVM-NEXT: %[[RES:.+]] = xor i32 %[[TMP]], -11114 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 41115 1116 // OGCG: %[[OLD:.+]] = atomicrmw nand ptr %{{.+}}, i32 %[[VAL:.+]] seq_cst, align 41117 // OGCG-NEXT: %[[TMP:.+]] = and i32 %[[OLD]], %[[VAL]]1118 // OGCG-NEXT: %[[RES:.+]] = xor i32 %[[TMP]], -11119 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 41120}1121 1122int c11_atomic_fetch_nand(_Atomic(int) *ptr, int value) {1123 // CIR-LABEL: @c11_atomic_fetch_nand1124 // LLVM-LABEL: @c11_atomic_fetch_nand1125 // OGCG-LABEL: @c11_atomic_fetch_nand1126 1127 return __c11_atomic_fetch_nand(ptr, value, __ATOMIC_SEQ_CST);1128 // CIR: %{{.+}} = cir.atomic.fetch nand seq_cst fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i1129 1130 // LLVM: %[[RES:.+]] = atomicrmw nand ptr %{{.+}}, i32 %{{.+}} seq_cst, align 41131 // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 41132 1133 // OGCG: %[[RES:.+]] = atomicrmw nand ptr %{{.+}}, i32 %{{.+}} seq_cst, align 41134 // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 41135}1136 1137int atomic_load_dynamic_order(int *ptr, int order) {1138 // CIR-LABEL: atomic_load_dynamic_order1139 // LLVM-LABEL: atomic_load_dynamic_order1140 // OGCG-LABEL: atomic_load_dynamic_order1141 1142 return __atomic_load_n(ptr, order);1143 1144 // CIR: %[[PTR:.+]] = cir.load align(8) %{{.+}} : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>1145 // CIR-NEXT: %[[ORDER:.+]] = cir.load align(4) %{{.+}} : !cir.ptr<!s32i>, !s32i1146 // CIR-NEXT: cir.switch (%[[ORDER]] : !s32i) {1147 // CIR-NEXT: cir.case(default, []) {1148 // CIR-NEXT: %[[RES:.+]] = cir.load align(4) atomic(relaxed) %[[PTR]] : !cir.ptr<!s32i>, !s32i1149 // CIR-NEXT: cir.store align(4) %[[RES]], %[[RES_SLOT:.+]] : !s32i, !cir.ptr<!s32i>1150 // CIR-NEXT: cir.break1151 // CIR-NEXT: }1152 // CIR-NEXT: cir.case(anyof, [#cir.int<1> : !s32i, #cir.int<2> : !s32i]) {1153 // CIR-NEXT: %[[RES:.+]] = cir.load align(4) atomic(acquire) %[[PTR]] : !cir.ptr<!s32i>, !s32i1154 // CIR-NEXT: cir.store align(4) %[[RES]], %[[RES_SLOT]] : !s32i, !cir.ptr<!s32i>1155 // CIR-NEXT: cir.break1156 // CIR-NEXT: }1157 // CIR-NEXT: cir.case(anyof, [#cir.int<5> : !s32i]) {1158 // CIR-NEXT: %[[RES:.+]] = cir.load align(4) atomic(seq_cst) %[[PTR]] : !cir.ptr<!s32i>, !s32i1159 // CIR-NEXT: cir.store align(4) %[[RES]], %[[RES_SLOT]] : !s32i, !cir.ptr<!s32i>1160 // CIR-NEXT: cir.break1161 // CIR-NEXT: }1162 // CIR-NEXT: cir.yield1163 // CIR-NEXT: }1164 // CIR-NEXT: %{{.+}} = cir.load align(4) %[[RES_SLOT]] : !cir.ptr<!s32i>, !s32i1165 1166 // LLVM: %[[PTR:.+]] = load ptr, ptr %{{.+}}, align 81167 // LLVM-NEXT: %[[ORDER:.+]] = load i32, ptr %{{.+}}, align 41168 // LLVM-NEXT: br label %[[SWITCH_BLK:.+]]1169 // LLVM: [[SWITCH_BLK]]:1170 // LLVM-NEXT: switch i32 %[[ORDER]], label %[[DEFAULT_BLK:.+]] [1171 // LLVM-NEXT: i32 1, label %[[ACQUIRE_BLK:.+]]1172 // LLVM-NEXT: i32 2, label %[[ACQUIRE_BLK]]1173 // LLVM-NEXT: i32 5, label %[[SEQ_CST_BLK:.+]]1174 // LLVM-NEXT: ]1175 // LLVM: [[DEFAULT_BLK]]:1176 // LLVM-NEXT: %[[RES:.+]] = load atomic i32, ptr %[[PTR]] monotonic, align 41177 // LLVM-NEXT: store i32 %[[RES]], ptr %[[RES_SLOT:.+]], align 41178 // LLVM-NEXT: br label %[[CONTINUE_BLK:.+]]1179 // LLVM: [[ACQUIRE_BLK]]:1180 // LLVM-NEXT: %[[RES:.+]] = load atomic i32, ptr %[[PTR]] acquire, align 41181 // LLVM-NEXT: store i32 %[[RES]], ptr %[[RES_SLOT]], align 41182 // LLVM-NEXT: br label %[[CONTINUE_BLK]]1183 // LLVM: [[SEQ_CST_BLK]]:1184 // LLVM-NEXT: %[[RES:.+]] = load atomic i32, ptr %[[PTR]] seq_cst, align 41185 // LLVM-NEXT: store i32 %[[RES]], ptr %[[RES_SLOT]], align 41186 // LLVM-NEXT: br label %[[CONTINUE_BLK]]1187 // LLVM: [[CONTINUE_BLK]]:1188 // LLVM-NEXT: %{{.+}} = load i32, ptr %[[RES_SLOT]], align 41189 1190 // OGCG: %[[PTR:.+]] = load ptr, ptr %{{.+}}, align 81191 // OGCG-NEXT: %[[ORDER:.+]] = load i32, ptr %{{.+}}, align 41192 // OGCG-NEXT: switch i32 %[[ORDER]], label %[[DEFAULT_BLK:.+]] [1193 // OGCG-NEXT: i32 1, label %[[ACQUIRE_BLK:.+]]1194 // OGCG-NEXT: i32 2, label %[[ACQUIRE_BLK]]1195 // OGCG-NEXT: i32 5, label %[[SEQ_CST_BLK:.+]]1196 // OGCG-NEXT: ]1197 // OGCG: [[DEFAULT_BLK]]:1198 // OGCG-NEXT: %[[RES:.+]] = load atomic i32, ptr %[[PTR]] monotonic, align 41199 // OGCG-NEXT: store i32 %[[RES]], ptr %[[RES_SLOT:.+]], align 41200 // OGCG-NEXT: br label %[[CONTINUE_BLK:.+]]1201 // OGCG: [[ACQUIRE_BLK]]:1202 // OGCG-NEXT: %[[RES:.+]] = load atomic i32, ptr %[[PTR]] acquire, align 41203 // OGCG-NEXT: store i32 %[[RES]], ptr %[[RES_SLOT]], align 41204 // OGCG-NEXT: br label %[[CONTINUE_BLK]]1205 // OGCG: [[SEQ_CST_BLK]]:1206 // OGCG-NEXT: %[[RES:.+]] = load atomic i32, ptr %[[PTR]] seq_cst, align 41207 // OGCG-NEXT: store i32 %[[RES]], ptr %[[RES_SLOT]], align 41208 // OGCG-NEXT: br label %[[CONTINUE_BLK]]1209 // OGCG: [[CONTINUE_BLK]]:1210 // OGCG-NEXT: %{{.+}} = load i32, ptr %[[RES_SLOT]], align 41211}1212 1213void atomic_store_dynamic_order(int *ptr, int order) {1214 // CIR-LABEL: atomic_store_dynamic_order1215 // LLVM-LABEL: atomic_store_dynamic_order1216 // OGCG-LABEL: atomic_store_dynamic_order1217 1218 __atomic_store_n(ptr, 10, order);1219 1220 // CIR: %[[PTR:.+]] = cir.load align(8) %{{.+}} : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>1221 // CIR-NEXT: %[[ORDER:.+]] = cir.load align(4) %{{.+}} : !cir.ptr<!s32i>, !s32i1222 // CIR: cir.switch (%[[ORDER]] : !s32i) {1223 // CIR-NEXT: cir.case(default, []) {1224 // CIR-NEXT: %[[VALUE:.+]] = cir.load align(4) %{{.+}} : !cir.ptr<!s32i>, !s32i1225 // CIR-NEXT: cir.store align(4) atomic(relaxed) %[[VALUE]], %[[PTR]] : !s32i, !cir.ptr<!s32i>1226 // CIR-NEXT: cir.break1227 // CIR-NEXT: }1228 // CIR-NEXT: cir.case(anyof, [#cir.int<3> : !s32i]) {1229 // CIR-NEXT: %[[VALUE:.+]] = cir.load align(4) %{{.+}} : !cir.ptr<!s32i>, !s32i1230 // CIR-NEXT: cir.store align(4) atomic(release) %[[VALUE]], %[[PTR]] : !s32i, !cir.ptr<!s32i>1231 // CIR-NEXT: cir.break1232 // CIR-NEXT: }1233 // CIR-NEXT: cir.case(anyof, [#cir.int<5> : !s32i]) {1234 // CIR-NEXT: %[[VALUE:.+]] = cir.load align(4) %{{.+}} : !cir.ptr<!s32i>, !s32i1235 // CIR-NEXT: cir.store align(4) atomic(seq_cst) %[[VALUE]], %[[PTR]] : !s32i, !cir.ptr<!s32i>1236 // CIR-NEXT: cir.break1237 // CIR-NEXT: }1238 // CIR-NEXT: cir.yield1239 // CIR-NEXT: }1240 1241 // LLVM: %[[PTR:.+]] = load ptr, ptr %{{.+}}, align 81242 // LLVM-NEXT: %[[ORDER:.+]] = load i32, ptr %{{.+}}, align 41243 // LLVM: br label %[[SWITCH_BLK:.+]]1244 // LLVM: [[SWITCH_BLK]]:1245 // LLVM-NEXT: switch i32 %[[ORDER]], label %[[DEFAULT_BLK:.+]] [1246 // LLVM-NEXT: i32 3, label %[[RELEASE_BLK:.+]]1247 // LLVM-NEXT: i32 5, label %[[SEQ_CST_BLK:.+]]1248 // LLVM-NEXT: ]1249 // LLVM: [[DEFAULT_BLK]]:1250 // LLVM-NEXT: %[[VALUE:.+]] = load i32, ptr %{{.+}}, align 41251 // LLVM-NEXT: store atomic i32 %[[VALUE]], ptr %[[PTR]] monotonic, align 41252 // LLVM-NEXT: br label %{{.+}}1253 // LLVM: [[RELEASE_BLK]]:1254 // LLVM-NEXT: %[[VALUE:.+]] = load i32, ptr %{{.+}}, align 41255 // LLVM-NEXT: store atomic i32 %[[VALUE]], ptr %[[PTR]] release, align 41256 // LLVM-NEXT: br label %{{.+}}1257 // LLVM: [[SEQ_CST_BLK]]:1258 // LLVM-NEXT: %[[VALUE:.+]] = load i32, ptr %{{.+}}, align 41259 // LLVM-NEXT: store atomic i32 %[[VALUE]], ptr %[[PTR]] seq_cst, align 41260 // LLVM-NEXT: br label %{{.+}}1261 1262 // OGCG: %[[PTR:.+]] = load ptr, ptr %{{.+}}, align 81263 // OGCG-NEXT: %[[ORDER:.+]] = load i32, ptr %{{.+}}, align 41264 // OGCG: switch i32 %[[ORDER]], label %[[DEFAULT_BLK:.+]] [1265 // OGCG-NEXT: i32 3, label %[[RELEASE_BLK:.+]]1266 // OGCG-NEXT: i32 5, label %[[SEQ_CST_BLK:.+]]1267 // OGCG-NEXT: ]1268 // OGCG: [[DEFAULT_BLK]]:1269 // OGCG-NEXT: %[[VALUE:.+]] = load i32, ptr %{{.+}}, align 41270 // OGCG-NEXT: store atomic i32 %[[VALUE]], ptr %[[PTR]] monotonic, align 41271 // OGCG-NEXT: br label %{{.+}}1272 // OGCG: [[RELEASE_BLK]]:1273 // OGCG-NEXT: %[[VALUE:.+]] = load i32, ptr %{{.+}}, align 41274 // OGCG-NEXT: store atomic i32 %[[VALUE]], ptr %[[PTR]] release, align 41275 // OGCG-NEXT: br label %{{.+}}1276 // OGCG: [[SEQ_CST_BLK]]:1277 // OGCG-NEXT: %[[VALUE:.+]] = load i32, ptr %{{.+}}, align 41278 // OGCG-NEXT: store atomic i32 %[[VALUE]], ptr %[[PTR]] seq_cst, align 41279 // OGCG-NEXT: br label %{{.+}}1280}1281 1282int atomic_load_and_store_dynamic_order(int *ptr, int order) {1283 // CIR-LABEL: atomic_load_and_store_dynamic_order1284 // LLVM-LABEL: atomic_load_and_store_dynamic_order1285 // OGCG-LABEL: atomic_load_and_store_dynamic_order1286 1287 return __atomic_exchange_n(ptr, 20, order);1288 1289 // CIR: %[[PTR:.+]] = cir.load align(8) %{{.+}} : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>1290 // CIR-NEXT: %[[ORDER:.+]] = cir.load align(4) %{{.+}} : !cir.ptr<!s32i>, !s32i1291 // CIR: cir.switch (%[[ORDER]] : !s32i) {1292 // CIR-NEXT: cir.case(default, []) {1293 // CIR-NEXT: %[[LIT:.+]] = cir.load align(4) %{{.+}} : !cir.ptr<!s32i>, !s32i1294 // CIR-NEXT: %[[RES:.+]] = cir.atomic.xchg relaxed %[[PTR]], %[[LIT]] : (!cir.ptr<!s32i>, !s32i) -> !s32i1295 // CIR-NEXT: cir.store align(4) %[[RES]], %[[RES_SLOT:.+]] : !s32i, !cir.ptr<!s32i>1296 // CIR-NEXT: cir.break1297 // CIR-NEXT: }1298 // CIR-NEXT: cir.case(anyof, [#cir.int<1> : !s32i, #cir.int<2> : !s32i]) {1299 // CIR-NEXT: %[[LIT:.+]] = cir.load align(4) %{{.+}} : !cir.ptr<!s32i>, !s32i1300 // CIR-NEXT: %[[RES:.+]] = cir.atomic.xchg acquire %[[PTR]], %[[LIT]] : (!cir.ptr<!s32i>, !s32i) -> !s32i1301 // CIR-NEXT: cir.store align(4) %[[RES]], %[[RES_SLOT]] : !s32i, !cir.ptr<!s32i>1302 // CIR-NEXT: cir.break1303 // CIR-NEXT: }1304 // CIR-NEXT: cir.case(anyof, [#cir.int<3> : !s32i]) {1305 // CIR-NEXT: %[[LIT:.+]] = cir.load align(4) %{{.+}} : !cir.ptr<!s32i>, !s32i1306 // CIR-NEXT: %[[RES:.+]] = cir.atomic.xchg release %[[PTR]], %[[LIT]] : (!cir.ptr<!s32i>, !s32i) -> !s32i1307 // CIR-NEXT: cir.store align(4) %[[RES]], %[[RES_SLOT]] : !s32i, !cir.ptr<!s32i>1308 // CIR-NEXT: cir.break1309 // CIR-NEXT: }1310 // CIR-NEXT: cir.case(anyof, [#cir.int<4> : !s32i]) {1311 // CIR-NEXT: %[[LIT:.+]] = cir.load align(4) %{{.+}} : !cir.ptr<!s32i>, !s32i1312 // CIR-NEXT: %[[RES:.+]] = cir.atomic.xchg acq_rel %[[PTR]], %[[LIT]] : (!cir.ptr<!s32i>, !s32i) -> !s32i1313 // CIR-NEXT: cir.store align(4) %[[RES]], %[[RES_SLOT]] : !s32i, !cir.ptr<!s32i>1314 // CIR-NEXT: cir.break1315 // CIR-NEXT: }1316 // CIR-NEXT: cir.case(anyof, [#cir.int<5> : !s32i]) {1317 // CIR-NEXT: %[[LIT:.+]] = cir.load align(4) %{{.+}} : !cir.ptr<!s32i>, !s32i1318 // CIR-NEXT: %[[RES:.+]] = cir.atomic.xchg seq_cst %[[PTR]], %[[LIT]] : (!cir.ptr<!s32i>, !s32i) -> !s32i1319 // CIR-NEXT: cir.store align(4) %[[RES]], %[[RES_SLOT]] : !s32i, !cir.ptr<!s32i>1320 // CIR-NEXT: cir.break1321 // CIR-NEXT: }1322 // CIR-NEXT: cir.yield1323 // CIR-NEXT: }1324 // CIR-NEXT: %{{.+}} = cir.load align(4) %[[RES_SLOT]] : !cir.ptr<!s32i>, !s32i1325 1326 // LLVM: %[[PTR:.+]] = load ptr, ptr %{{.+}}, align 81327 // LLVM-NEXT: %[[ORDER:.+]] = load i32, ptr %{{.+}}, align 41328 // LLVM: br label %[[SWITCH_BLK:.+]]1329 // LLVM: [[SWITCH_BLK]]:1330 // LLVM-NEXT: switch i32 %[[ORDER]], label %[[DEFAULT_BLK:.+]] [1331 // LLVM-NEXT: i32 1, label %[[ACQUIRE_BLK:.+]]1332 // LLVM-NEXT: i32 2, label %[[ACQUIRE_BLK]]1333 // LLVM-NEXT: i32 3, label %[[RELEASE_BLK:.+]]1334 // LLVM-NEXT: i32 4, label %[[ACQ_REL_BLK:.+]]1335 // LLVM-NEXT: i32 5, label %[[SEQ_CST_BLK:.+]]1336 // LLVM-NEXT: ]1337 // LLVM: [[DEFAULT_BLK]]:1338 // LLVM-NEXT: %[[VALUE:.+]] = load i32, ptr %{{.+}}, align 41339 // LLVM-NEXT: %[[RES:.+]] = atomicrmw xchg ptr %[[PTR]], i32 %[[VALUE]] monotonic, align 41340 // LLVM-NEXT: store i32 %[[RES]], ptr %[[RES_SLOT:.+]], align 41341 // LLVM-NEXT: br label %[[CONTINUE_BLK:.+]]1342 // LLVM: [[ACQUIRE_BLK]]:1343 // LLVM-NEXT: %[[VALUE:.+]] = load i32, ptr %{{.+}}, align 41344 // LLVM-NEXT: %[[RES:.+]] = atomicrmw xchg ptr %[[PTR]], i32 %[[VALUE]] acquire, align 41345 // LLVM-NEXT: store i32 %[[RES]], ptr %[[RES_SLOT]], align 41346 // LLVM-NEXT: br label %[[CONTINUE_BLK]]1347 // LLVM: [[RELEASE_BLK]]:1348 // LLVM-NEXT: %[[VALUE:.+]] = load i32, ptr %{{.+}}, align 41349 // LLVM-NEXT: %[[RES:.+]] = atomicrmw xchg ptr %[[PTR]], i32 %[[VALUE]] release, align 41350 // LLVM-NEXT: store i32 %[[RES]], ptr %[[RES_SLOT]], align 41351 // LLVM-NEXT: br label %[[CONTINUE_BLK]]1352 // LLVM: [[ACQ_REL_BLK]]:1353 // LLVM-NEXT: %[[VALUE:.+]] = load i32, ptr %{{.+}}, align 41354 // LLVM-NEXT: %[[RES:.+]] = atomicrmw xchg ptr %[[PTR]], i32 %[[VALUE]] acq_rel, align 41355 // LLVM-NEXT: store i32 %[[RES]], ptr %[[RES_SLOT]], align 41356 // LLVM-NEXT: br label %[[CONTINUE_BLK]]1357 // LLVM: [[SEQ_CST_BLK]]:1358 // LLVM-NEXT: %[[VALUE:.+]] = load i32, ptr %{{.+}}, align 41359 // LLVM-NEXT: %[[RES:.+]] = atomicrmw xchg ptr %[[PTR]], i32 %[[VALUE]] seq_cst, align 41360 // LLVM-NEXT: store i32 %[[RES]], ptr %[[RES_SLOT]], align 41361 // LLVM-NEXT: br label %[[CONTINUE_BLK]]1362 // LLVM: [[CONTINUE_BLK]]:1363 // LLVM-NEXT: %{{.+}} = load i32, ptr %[[RES_SLOT]], align 41364 1365 // OGCG: %[[PTR:.+]] = load ptr, ptr %{{.+}}, align 81366 // OGCG-NEXT: %[[ORDER:.+]] = load i32, ptr %{{.+}}, align 41367 // OGCG: switch i32 %[[ORDER]], label %[[DEFAULT_BLK:.+]] [1368 // OGCG-NEXT: i32 1, label %[[ACQUIRE_BLK:.+]]1369 // OGCG-NEXT: i32 2, label %[[ACQUIRE_BLK]]1370 // OGCG-NEXT: i32 3, label %[[RELEASE_BLK:.+]]1371 // OGCG-NEXT: i32 4, label %[[ACQ_REL_BLK:.+]]1372 // OGCG-NEXT: i32 5, label %[[SEQ_CST_BLK:.+]]1373 // OGCG-NEXT: ]1374 // OGCG: [[DEFAULT_BLK]]:1375 // OGCG-NEXT: %[[VALUE:.+]] = load i32, ptr %{{.+}}, align 41376 // OGCG-NEXT: %[[RES:.+]] = atomicrmw xchg ptr %[[PTR]], i32 %[[VALUE]] monotonic, align 41377 // OGCG-NEXT: store i32 %[[RES]], ptr %[[RES_SLOT:.+]], align 41378 // OGCG-NEXT: br label %[[CONTINUE_BLK:.+]]1379 // OGCG: [[ACQUIRE_BLK]]:1380 // OGCG-NEXT: %[[VALUE:.+]] = load i32, ptr %{{.+}}, align 41381 // OGCG-NEXT: %[[RES:.+]] = atomicrmw xchg ptr %[[PTR]], i32 %[[VALUE]] acquire, align 41382 // OGCG-NEXT: store i32 %[[RES]], ptr %[[RES_SLOT]], align 41383 // OGCG-NEXT: br label %[[CONTINUE_BLK]]1384 // OGCG: [[RELEASE_BLK]]:1385 // OGCG-NEXT: %[[VALUE:.+]] = load i32, ptr %{{.+}}, align 41386 // OGCG-NEXT: %[[RES:.+]] = atomicrmw xchg ptr %[[PTR]], i32 %[[VALUE]] release, align 41387 // OGCG-NEXT: store i32 %[[RES]], ptr %[[RES_SLOT]], align 41388 // OGCG-NEXT: br label %[[CONTINUE_BLK]]1389 // OGCG: [[ACQ_REL_BLK]]:1390 // OGCG-NEXT: %[[VALUE:.+]] = load i32, ptr %{{.+}}, align 41391 // OGCG-NEXT: %[[RES:.+]] = atomicrmw xchg ptr %[[PTR]], i32 %[[VALUE]] acq_rel, align 41392 // OGCG-NEXT: store i32 %[[RES]], ptr %[[RES_SLOT]], align 41393 // OGCG-NEXT: br label %[[CONTINUE_BLK]]1394 // OGCG: [[SEQ_CST_BLK]]:1395 // OGCG-NEXT: %[[VALUE:.+]] = load i32, ptr %{{.+}}, align 41396 // OGCG-NEXT: %[[RES:.+]] = atomicrmw xchg ptr %[[PTR]], i32 %[[VALUE]] seq_cst, align 41397 // OGCG-NEXT: store i32 %[[RES]], ptr %[[RES_SLOT]], align 41398 // OGCG-NEXT: br label %[[CONTINUE_BLK]]1399 // OGCG: [[CONTINUE_BLK]]:1400 // OGCG-NEXT: %{{.+}} = load i32, ptr %[[RES_SLOT]], align 41401}1402