13a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis// RUN: %clang_cc1 %s -emit-llvm -o - -ffreestanding -triple=i686-apple-darwin9 | FileCheck %s
23a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis// REQUIRES: x86-registered-target
33a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis
43a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis// Also test serialization of atomic operations here, to avoid duplicating the
53a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis// test.
63a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis// RUN: %clang_cc1 %s -emit-pch -o %t -ffreestanding -triple=i686-apple-darwin9
73a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis// RUN: %clang_cc1 %s -include-pch %t -ffreestanding -triple=i686-apple-darwin9 -emit-llvm -o - | FileCheck %s
83a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis#ifndef ALREADY_INCLUDED
93a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis#define ALREADY_INCLUDED
10fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner
113a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis#include <stdatomic.h>
123a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis
133a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis// Basic IRGen tests for __c11_atomic_* and GNU __atomic_*
143a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis
15ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCallint fi1(_Atomic(int) *i) {
16ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall  // CHECK-LABEL: @fi1
17ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall  // CHECK: load atomic i32, i32* {{.*}} seq_cst
18ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall  return __c11_atomic_load(i, memory_order_seq_cst);
193a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis}
203a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis
213a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davisint fi1a(int *i) {
220bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-LABEL: @fi1a
2393d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK: load atomic i32, i32* {{.*}} seq_cst
243a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis  int v;
2514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  __atomic_load(i, &v, memory_order_seq_cst);
2693d557bc1867b7d7b102f87290194b4be7932c92John McCall  return v;
270502a224984a26087ea4d64e8e5d2dd4dca432f6John McCall}
280bab0cdab751248ca389a5592bcb70eac5d39260John McCall
2993d557bc1867b7d7b102f87290194b4be7932c92John McCallint fi1b(int *i) {
303a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis  // CHECK-LABEL: @fi1b
313a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis  // CHECK: load atomic i32, i32* {{.*}} seq_cst
3293d557bc1867b7d7b102f87290194b4be7932c92John McCall  return __atomic_load_n(i, memory_order_seq_cst);
333a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis}
343a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis
35071cc7deffad608165b1ddd5263e8bf181861520Charles Davisint fi1c(atomic_int *i) {
360bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-LABEL: @fi1c
379cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  // CHECK: load atomic i32, i32* {{.*}} seq_cst
3893d557bc1867b7d7b102f87290194b4be7932c92John McCall  return atomic_load(i);
39babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall}
400bab0cdab751248ca389a5592bcb70eac5d39260John McCall
410bab0cdab751248ca389a5592bcb70eac5d39260John McCallvoid fi2(_Atomic(int) *i) {
429cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  // CHECK-LABEL: @fi2
430bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: store atomic i32 {{.*}} seq_cst
449cb2cee212d708220c52249ceac4cdd9f2b8aeb0John McCall  __c11_atomic_store(i, 1, memory_order_seq_cst);
459cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner}
460bab0cdab751248ca389a5592bcb70eac5d39260John McCall
470bab0cdab751248ca389a5592bcb70eac5d39260John McCallvoid fi2a(int *i) {
480bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-LABEL: @fi2a
490bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: store atomic i32 {{.*}} seq_cst
500bab0cdab751248ca389a5592bcb70eac5d39260John McCall  int v = 1;
516ec278d1a354517e20f13a877481453ee7940c78John McCall  __atomic_store(i, &v, memory_order_seq_cst);
526ec278d1a354517e20f13a877481453ee7940c78John McCall}
536ec278d1a354517e20f13a877481453ee7940c78John McCall
541e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCallvoid fi2b(int *i) {
553a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis  // CHECK-LABEL: @fi2b
56babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK: store atomic i32 {{.*}} seq_cst
5714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  __atomic_store_n(i, 1, memory_order_seq_cst);
5893d557bc1867b7d7b102f87290194b4be7932c92John McCall}
59f16aa103d3afd42fbca2ab346f191bf745cec092John McCall
60cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCallvoid fi2c(atomic_int *i) {
619cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  // CHECK-LABEL: @fi2c
620bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: store atomic i32 {{.*}} seq_cst
6393d557bc1867b7d7b102f87290194b4be7932c92John McCall  atomic_store(i, 1);
6493d557bc1867b7d7b102f87290194b4be7932c92John McCall}
6593d557bc1867b7d7b102f87290194b4be7932c92John McCall
6693d557bc1867b7d7b102f87290194b4be7932c92John McCallint fi3(_Atomic(int) *i) {
673023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall  // CHECK-LABEL: @fi3
686c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall  // CHECK: atomicrmw and
696c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall  // CHECK-NOT: and
706c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall  return __c11_atomic_fetch_and(i, 1, memory_order_seq_cst);
716c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall}
726c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall
730bab0cdab751248ca389a5592bcb70eac5d39260John McCallint fi3a(int *i) {
740bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-LABEL: @fi3a
750bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: atomicrmw xor
76cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  // CHECK-NOT: xor
770bab0cdab751248ca389a5592bcb70eac5d39260John McCall  return __atomic_fetch_xor(i, 1, memory_order_seq_cst);
780bab0cdab751248ca389a5592bcb70eac5d39260John McCall}
79cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall
800bab0cdab751248ca389a5592bcb70eac5d39260John McCallint fi3b(int *i) {
81cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  // CHECK-LABEL: @fi3b
82755d8497e39071aa24acc173ff07083e3256b8f8John McCall  // CHECK: atomicrmw add
835808ce43f8d7e71f5acacc9ca320268c4f37565aJohn McCall  // CHECK: add
845808ce43f8d7e71f5acacc9ca320268c4f37565aJohn McCall  return __atomic_add_fetch(i, 1, memory_order_seq_cst);
85875ab10245d3bf37252dd822aa1616bb0a391095John McCall}
860bab0cdab751248ca389a5592bcb70eac5d39260John McCall
870bab0cdab751248ca389a5592bcb70eac5d39260John McCallint fi3c(int *i) {
880bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-LABEL: @fi3c
890bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: atomicrmw nand
900bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-NOT: and
91e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  return __atomic_fetch_nand(i, 1, memory_order_seq_cst);
920bab0cdab751248ca389a5592bcb70eac5d39260John McCall}
930bab0cdab751248ca389a5592bcb70eac5d39260John McCall
940bab0cdab751248ca389a5592bcb70eac5d39260John McCallint fi3d(int *i) {
954c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK-LABEL: @fi3d
964c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK: atomicrmw nand
974c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK: and
984c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK: xor
994c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  return __atomic_nand_fetch(i, 1, memory_order_seq_cst);
1004c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall}
1014c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall
1024c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCallint fi3e(atomic_int *i) {
1034c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK-LABEL: @fi3e
1044c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK: atomicrmw or
1054c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK-NOT: {{ or }}
1064c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  return atomic_fetch_or(i, 1);
1074c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall}
1084c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall
1094c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCallint fi3f(int *i) {
1104c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK-LABEL: @fi3f
1111e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall  // CHECK-NOT: store volatile
1126ec278d1a354517e20f13a877481453ee7940c78John McCall  // CHECK: atomicrmw or
1131e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall  // CHECK-NOT: {{ or }}
1141e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall  return __atomic_fetch_or(i, (short)1, memory_order_seq_cst);
1151e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall}
1166ec278d1a354517e20f13a877481453ee7940c78John McCall
1171e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall_Bool fi4(_Atomic(int) *i) {
1181e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall  // CHECK-LABEL: @fi4(
1196ec278d1a354517e20f13a877481453ee7940c78John McCall  // CHECK: [[PAIR:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]]
1201e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall  // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 0
1211e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall  // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 1
1225cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall  // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]]
1233030eb82593097502469a8b3fc26112c79c75605John McCall  // CHECK: store i32 [[OLD]]
1243030eb82593097502469a8b3fc26112c79c75605John McCall  int cmp = 0;
1253a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis  return __c11_atomic_compare_exchange_strong(i, &cmp, 1, memory_order_acquire, memory_order_acquire);
126ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall}
127ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall
128ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall_Bool fi4a(int *i) {
129babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-LABEL: @fi4a
1304c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK: [[PAIR:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]]
1314c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 0
1324c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 1
1334c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]]
1344c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK: store i32 [[OLD]]
1354c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  int cmp = 0;
1364c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  int desired = 1;
1374c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  return __atomic_compare_exchange(i, &cmp, &desired, 0, memory_order_acquire, memory_order_acquire);
1384c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall}
1394c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall
1404c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall_Bool fi4b(int *i) {
1414c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK-LABEL: @fi4b(
1424c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK: [[PAIR:%[.0-9A-Z_a-z]+]] = cmpxchg weak i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]]
1434c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 0
1444c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 1
1454c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]]
1464c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK: store i32 [[OLD]]
1474c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  int cmp = 0;
1484c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  return __atomic_compare_exchange_n(i, &cmp, 1, 1, memory_order_acquire, memory_order_acquire);
1496ec278d1a354517e20f13a877481453ee7940c78John McCall}
1501e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall
1511e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall_Bool fi4c(atomic_int *i) {
1521e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall  // CHECK-LABEL: @fi4c
1536ec278d1a354517e20f13a877481453ee7940c78John McCall  // CHECK: cmpxchg i32*
1541e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall  int cmp = 0;
1551e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall  return atomic_compare_exchange_strong(i, &cmp, 1);
1566ec278d1a354517e20f13a877481453ee7940c78John McCall}
1571e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall
1581e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCallfloat ff1(_Atomic(float) *d) {
1594c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK-LABEL: @ff1
1604c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK: load atomic i32, i32* {{.*}} monotonic
1614c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  return __c11_atomic_load(d, memory_order_relaxed);
1624c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall}
1634c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall
1644c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCallvoid ff2(_Atomic(float) *d) {
1654c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK-LABEL: @ff2
1664c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  // CHECK: store atomic i32 {{.*}} release
1674c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall  __c11_atomic_store(d, 1, memory_order_release);
168ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall}
1693a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis
1703a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davisfloat ff3(_Atomic(float) *d) {
171071cc7deffad608165b1ddd5263e8bf181861520Charles Davis  return __c11_atomic_exchange(d, 2, memory_order_seq_cst);
1723a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis}
1733a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis
1743a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davisstruct S {
175ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall  double x;
176ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall};
177ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall
178ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCallstruct S fd1(struct S *a) {
1799cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  // CHECK-LABEL: @fd1
1800bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: [[RETVAL:%.*]] = alloca %struct.S, align 4
1810bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: [[RET:%.*]]    = alloca %struct.S, align 4
1820bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: [[CAST:%.*]]   = bitcast %struct.S* [[RET]] to i64*
1837650d95a1a616ea300f37126a8dfc93dc19a662aChris Lattner  // CHECK: [[CALL:%.*]]   = call i64 @__atomic_load_8(
184875ab10245d3bf37252dd822aa1616bb0a391095John McCall  // CHECK: store i64 [[CALL]], i64* [[CAST]], align 4
185875ab10245d3bf37252dd822aa1616bb0a391095John McCall  struct S ret;
186babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  __atomic_load(a, &ret, memory_order_seq_cst);
187babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  return ret;
188babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall}
189babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall
190babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCallvoid fd2(struct S *a, struct S *b) {
191babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-LABEL: @fd2
192babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK:      [[A_ADDR:%.*]] = alloca %struct.S*, align 4
193babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-NEXT: [[B_ADDR:%.*]] = alloca %struct.S*, align 4
194babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-NEXT: store %struct.S* %a, %struct.S** [[A_ADDR]], align 4
195babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-NEXT: store %struct.S* %b, %struct.S** [[B_ADDR]], align 4
196babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-NEXT: [[LOAD_A_PTR:%.*]] = load %struct.S*, %struct.S** [[A_ADDR]], align 4
197babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-NEXT: [[LOAD_B_PTR:%.*]] = load %struct.S*, %struct.S** [[B_ADDR]], align 4
198babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-NEXT: [[COERCED_A_TMP:%.*]] = bitcast %struct.S* [[LOAD_A_PTR]] to i64*
199babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-NEXT: [[COERCED_B:%.*]] = bitcast %struct.S* [[LOAD_B_PTR]] to i64*
200babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-NEXT: [[COERCED_A:%.*]] = bitcast i64* [[COERCED_A_TMP]] to i8*
201babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-NEXT: [[LOAD_B:%.*]] = load i64, i64* [[COERCED_B]], align 4
202babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-NEXT: call void @__atomic_store_8(i8* [[COERCED_A]], i64 [[LOAD_B]],
203babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-NEXT: ret void
204babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  __atomic_store(a, b, memory_order_seq_cst);
205babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall}
20693d557bc1867b7d7b102f87290194b4be7932c92John McCall
20793d557bc1867b7d7b102f87290194b4be7932c92John McCallvoid fd3(struct S *a, struct S *b, struct S *c) {
20893d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-LABEL: @fd3
20993d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK:      [[A_ADDR:%.*]] = alloca %struct.S*, align 4
21093d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: [[B_ADDR:%.*]] = alloca %struct.S*, align 4
21193d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: [[C_ADDR:%.*]] = alloca %struct.S*, align 4
21293d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: store %struct.S* %a, %struct.S** [[A_ADDR]], align 4
21393d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: store %struct.S* %b, %struct.S** [[B_ADDR]], align 4
21493d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: store %struct.S* %c, %struct.S** [[C_ADDR]], align 4
21593d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: [[LOAD_A_PTR:%.*]] = load %struct.S*, %struct.S** [[A_ADDR]], align 4
21693d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: [[LOAD_B_PTR:%.*]] = load %struct.S*, %struct.S** [[B_ADDR]], align 4
21793d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: [[LOAD_C_PTR:%.*]] = load %struct.S*, %struct.S** [[C_ADDR]], align 4
21893d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: [[COERCED_A_TMP:%.*]] = bitcast %struct.S* [[LOAD_A_PTR]] to i64*
21993d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: [[COERCED_B:%.*]] = bitcast %struct.S* [[LOAD_B_PTR]] to i64*
22093d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: [[COERCED_C:%.*]] = bitcast %struct.S* [[LOAD_C_PTR]] to i64*
22193d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: [[COERCED_A:%.*]] = bitcast i64* [[COERCED_A_TMP]] to i8*
2220bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-NEXT: [[LOAD_B:%.*]] = load i64, i64* [[COERCED_B]], align 4
223babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-NEXT: [[CALL:%.*]] = call i64 @__atomic_exchange_8(i8* [[COERCED_A]], i64 [[LOAD_B]],
22493d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: store i64 [[CALL]], i64* [[COERCED_C]], align 4
225babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall
226babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  __atomic_exchange(a, b, c, memory_order_seq_cst);
227babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall}
228babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall
229d608cdb7c044365cf4e8764ade1e11e99c176078John McCall_Bool fd4(struct S *a, struct S *b, struct S *c) {
230d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK-LABEL: @fd4
231babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK:      [[A_ADDR:%.*]] = alloca %struct.S*, align 4
232babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-NEXT: [[B_ADDR:%.*]] = alloca %struct.S*, align 4
233babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-NEXT: [[C_ADDR:%.*]] = alloca %struct.S*, align 4
234babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK:      store %struct.S* %a, %struct.S** [[A_ADDR]], align 4
235babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-NEXT: store %struct.S* %b, %struct.S** [[B_ADDR]], align 4
23693d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: store %struct.S* %c, %struct.S** [[C_ADDR]], align 4
23793d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: [[LOAD_A_PTR:%.*]] = load %struct.S*, %struct.S** [[A_ADDR]], align 4
23893d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: [[LOAD_B_PTR:%.*]] = load %struct.S*, %struct.S** [[B_ADDR]], align 4
239babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-NEXT: [[LOAD_C_PTR:%.*]] = load %struct.S*, %struct.S** [[C_ADDR]], align 4
240babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-NEXT: [[COERCED_A_TMP:%.*]] = bitcast %struct.S* [[LOAD_A_PTR]] to i64*
241babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-NEXT: [[COERCED_B_TMP:%.*]] = bitcast %struct.S* [[LOAD_B_PTR]] to i64*
24293d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: [[COERCED_C:%.*]] = bitcast %struct.S* [[LOAD_C_PTR]] to i64*
24393d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: [[COERCED_A:%.*]] = bitcast i64* [[COERCED_A_TMP]] to i8*
244d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK-NEXT: [[COERCED_B:%.*]] = bitcast i64* [[COERCED_B_TMP]] to i8*
24593d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: [[LOAD_C:%.*]] = load i64, i64* [[COERCED_C]], align 4
24693d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: [[CALL:%.*]] = call zeroext i1 @__atomic_compare_exchange_8(i8* [[COERCED_A]], i8* [[COERCED_B]], i64 [[LOAD_C]]
24793d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-NEXT: ret i1 [[CALL]]
248babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  return __atomic_compare_exchange(a, b, c, 1, 5, 5);
249babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall}
250babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall
251babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCallint* fp1(_Atomic(int*) *p) {
252babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-LABEL: @fp1
253babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK: load atomic i32, i32* {{.*}} seq_cst
25493d557bc1867b7d7b102f87290194b4be7932c92John McCall  return __c11_atomic_load(p, memory_order_seq_cst);
25593d557bc1867b7d7b102f87290194b4be7932c92John McCall}
25693d557bc1867b7d7b102f87290194b4be7932c92John McCall
25793d557bc1867b7d7b102f87290194b4be7932c92John McCallint* fp2(_Atomic(int*) *p) {
258babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-LABEL: @fp2
25993d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK: store i32 4
26093d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK: atomicrmw add {{.*}} monotonic
26193d557bc1867b7d7b102f87290194b4be7932c92John McCall  return __c11_atomic_fetch_add(p, 1, memory_order_relaxed);
26293d557bc1867b7d7b102f87290194b4be7932c92John McCall}
26393d557bc1867b7d7b102f87290194b4be7932c92John McCall
264babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCallint *fp2a(int **p) {
26593d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-LABEL: @fp2a
26693d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK: store i32 4
267babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK: atomicrmw sub {{.*}} monotonic
268babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // Note, the GNU builtins do not multiply by sizeof(T)!
269babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  return __atomic_fetch_sub(p, 4, memory_order_relaxed);
27093d557bc1867b7d7b102f87290194b4be7932c92John McCall}
27193d557bc1867b7d7b102f87290194b4be7932c92John McCall
27293d557bc1867b7d7b102f87290194b4be7932c92John McCall_Complex float fc(_Atomic(_Complex float) *c) {
273babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-LABEL: @fc
27493d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK: atomicrmw xchg i64*
27593d557bc1867b7d7b102f87290194b4be7932c92John McCall  return __c11_atomic_exchange(c, 2, memory_order_seq_cst);
27693d557bc1867b7d7b102f87290194b4be7932c92John McCall}
27793d557bc1867b7d7b102f87290194b4be7932c92John McCall
27893d557bc1867b7d7b102f87290194b4be7932c92John McCalltypedef struct X { int x; } X;
27993d557bc1867b7d7b102f87290194b4be7932c92John McCallX fs(_Atomic(X) *c) {
280babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall  // CHECK-LABEL: @fs
28193d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK: atomicrmw xchg i32*
28293d557bc1867b7d7b102f87290194b4be7932c92John McCall  return __c11_atomic_exchange(c, (X){2}, memory_order_seq_cst);
28393d557bc1867b7d7b102f87290194b4be7932c92John McCall}
284bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad
28593d557bc1867b7d7b102f87290194b4be7932c92John McCallX fsa(X *c, X *d) {
28693d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK-LABEL: @fsa
28793d557bc1867b7d7b102f87290194b4be7932c92John McCall  // CHECK: atomicrmw xchg i32*
28893d557bc1867b7d7b102f87290194b4be7932c92John McCall  X ret;
2893023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall  __atomic_exchange(c, d, &ret, memory_order_seq_cst);
2906c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall  return ret;
2916c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall}
2926c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall
2936c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall_Bool fsb(_Bool *c) {
2946c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall  // CHECK-LABEL: @fsb
2956c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall  // CHECK: atomicrmw xchg i8*
2966c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall  return __atomic_exchange_n(c, 1, memory_order_seq_cst);
2976c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall}
2986c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall
2996c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCallchar flag1;
3006c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCallvolatile char flag2;
3016c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCallvoid test_and_set() {
3026c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall  // CHECK: atomicrmw xchg i8* @flag1, i8 1 seq_cst
3036c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall  __atomic_test_and_set(&flag1, memory_order_seq_cst);
3046c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall  // CHECK: atomicrmw volatile xchg i8* @flag2, i8 1 acquire
3056c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall  __atomic_test_and_set(&flag2, memory_order_acquire);
3066c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall  // CHECK: store atomic volatile i8 0, i8* @flag2 release
3076c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall  __atomic_clear(&flag2, memory_order_release);
3086c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall  // CHECK: store atomic i8 0, i8* @flag1 seq_cst
3096c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall  __atomic_clear(&flag1, memory_order_seq_cst);
310eede61a83e90f3cb03ef8665b67d648dccd6ce42Douglas Gregor}
311eede61a83e90f3cb03ef8665b67d648dccd6ce42Douglas Gregor
3126c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCallstruct Sixteen {
3136c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall  char c[16];
3146c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall} sixteen;
3153023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCallstruct Seventeen {
3160bab0cdab751248ca389a5592bcb70eac5d39260John McCall  char c[17];
3170bab0cdab751248ca389a5592bcb70eac5d39260John McCall} seventeen;
3180bab0cdab751248ca389a5592bcb70eac5d39260John McCall
3190bab0cdab751248ca389a5592bcb70eac5d39260John McCallstruct Incomplete;
3200bab0cdab751248ca389a5592bcb70eac5d39260John McCall
3210bab0cdab751248ca389a5592bcb70eac5d39260John McCallint lock_free(struct Incomplete *incomplete) {
3220bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-LABEL: @lock_free
3230bab0cdab751248ca389a5592bcb70eac5d39260John McCall
3240bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: call i32 @__atomic_is_lock_free(i32 3, i8* null)
3250bab0cdab751248ca389a5592bcb70eac5d39260John McCall  __c11_atomic_is_lock_free(3);
3260bab0cdab751248ca389a5592bcb70eac5d39260John McCall
3270bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: call i32 @__atomic_is_lock_free(i32 16, i8* {{.*}}@sixteen{{.*}})
3280bab0cdab751248ca389a5592bcb70eac5d39260John McCall  __atomic_is_lock_free(16, &sixteen);
3290bab0cdab751248ca389a5592bcb70eac5d39260John McCall
3300bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: call i32 @__atomic_is_lock_free(i32 17, i8* {{.*}}@seventeen{{.*}})
3310bab0cdab751248ca389a5592bcb70eac5d39260John McCall  __atomic_is_lock_free(17, &seventeen);
3320bab0cdab751248ca389a5592bcb70eac5d39260John McCall
3330bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: call i32 @__atomic_is_lock_free(i32 4, {{.*}})
3340bab0cdab751248ca389a5592bcb70eac5d39260John McCall  __atomic_is_lock_free(4, incomplete);
335d608cdb7c044365cf4e8764ade1e11e99c176078John McCall
3360bab0cdab751248ca389a5592bcb70eac5d39260John McCall  char cs[20];
3370bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: call i32 @__atomic_is_lock_free(i32 4, {{.*}})
3380bab0cdab751248ca389a5592bcb70eac5d39260John McCall  __atomic_is_lock_free(4, cs+1);
3392de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
3402de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  // CHECK-NOT: call
3413023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall  __atomic_always_lock_free(3, 0);
342d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  __atomic_always_lock_free(16, 0);
3430bab0cdab751248ca389a5592bcb70eac5d39260John McCall  __atomic_always_lock_free(17, 0);
344d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  __atomic_always_lock_free(16, &sixteen);
3453023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall  __atomic_always_lock_free(17, &seventeen);
3463023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall
3473023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall  int n;
3483023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall  __atomic_is_lock_free(4, &n);
3493023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall
3503023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall  // CHECK: ret i32 1
3513023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall  return __c11_atomic_is_lock_free(sizeof(_Atomic(int)));
3523023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall}
3533023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall
3543023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall// Tests for atomic operations on big values.  These should call the functions
3552de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall// defined here:
3563023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall// http://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary#The_Library_interface
357dec0984fce504a39a7f085774fb67cfd9957be58Jeffrey Yasskin
3583023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCallstruct foo {
359dec0984fce504a39a7f085774fb67cfd9957be58Jeffrey Yasskin  int big[128];
3603023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall};
361dec0984fce504a39a7f085774fb67cfd9957be58Jeffrey Yasskinstruct bar {
3623023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall  char c[3];
363d608cdb7c044365cf4e8764ade1e11e99c176078John McCall};
364d608cdb7c044365cf4e8764ade1e11e99c176078John McCall
365d608cdb7c044365cf4e8764ade1e11e99c176078John McCallstruct bar smallThing, thing1, thing2;
366d608cdb7c044365cf4e8764ade1e11e99c176078John McCallstruct foo bigThing;
367d608cdb7c044365cf4e8764ade1e11e99c176078John McCall_Atomic(struct foo) bigAtomic;
368875ab10245d3bf37252dd822aa1616bb0a391095John McCall
3690bab0cdab751248ca389a5592bcb70eac5d39260John McCallvoid structAtomicStore() {
3700bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-LABEL: @structAtomicStore
3710bab0cdab751248ca389a5592bcb70eac5d39260John McCall  struct foo f = {0};
3720bab0cdab751248ca389a5592bcb70eac5d39260John McCall  struct bar b = {0};
3730bab0cdab751248ca389a5592bcb70eac5d39260John McCall  __atomic_store(&smallThing, &b, 5);
3740bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: call void @__atomic_store(i32 3, i8* {{.*}} @smallThing
3750bab0cdab751248ca389a5592bcb70eac5d39260John McCall
3760bab0cdab751248ca389a5592bcb70eac5d39260John McCall  __atomic_store(&bigThing, &f, 5);
3770bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: call void @__atomic_store(i32 512, i8* {{.*}} @bigThing
3780bab0cdab751248ca389a5592bcb70eac5d39260John McCall}
3790bab0cdab751248ca389a5592bcb70eac5d39260John McCallvoid structAtomicLoad() {
3800bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-LABEL: @structAtomicLoad
3810bab0cdab751248ca389a5592bcb70eac5d39260John McCall  struct bar b;
3820bab0cdab751248ca389a5592bcb70eac5d39260John McCall  __atomic_load(&smallThing, &b, 5);
3830bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: call void @__atomic_load(i32 3, i8* {{.*}} @smallThing
384d608cdb7c044365cf4e8764ade1e11e99c176078John McCall
385d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  struct foo f = {0};
386d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  __atomic_load(&bigThing, &f, 5);
387d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: call void @__atomic_load(i32 512, i8* {{.*}} @bigThing
388d608cdb7c044365cf4e8764ade1e11e99c176078John McCall}
389d608cdb7c044365cf4e8764ade1e11e99c176078John McCallstruct foo structAtomicExchange() {
390d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK-LABEL: @structAtomicExchange
391e14add4a275318e7a9cafd3a01f79fb15a5a08bcJohn McCall  struct foo f = {0};
392d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  struct foo old;
393d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  __atomic_exchange(&f, &bigThing, &old, 5);
3940bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: call void @__atomic_exchange(i32 512, {{.*}}, i8* bitcast ({{.*}} @bigThing to i8*),
395d608cdb7c044365cf4e8764ade1e11e99c176078John McCall
3960bab0cdab751248ca389a5592bcb70eac5d39260John McCall  return __c11_atomic_exchange(&bigAtomic, f, 5);
397d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: call void @__atomic_exchange(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*),
398e14add4a275318e7a9cafd3a01f79fb15a5a08bcJohn McCall}
3993023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCallint structAtomicCmpExchange() {
400cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  // CHECK-LABEL: @structAtomicCmpExchange
401cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  // CHECK: %[[x_mem:.*]] = alloca i8
4020bab0cdab751248ca389a5592bcb70eac5d39260John McCall  _Bool x = __atomic_compare_exchange(&smallThing, &thing1, &thing2, 1, 5, 5);
4030bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: %[[call1:.*]] = call zeroext i1 @__atomic_compare_exchange(i32 3, {{.*}} @smallThing{{.*}} @thing1{{.*}} @thing2
404cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  // CHECK: %[[zext1:.*]] = zext i1 %[[call1]] to i8
405cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  // CHECK: store i8 %[[zext1]], i8* %[[x_mem]], align 1
406cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  // CHECK: %[[x:.*]] = load i8, i8* %[[x_mem]]
407cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  // CHECK: %[[x_bool:.*]] = trunc i8 %[[x]] to i1
408cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  // CHECK: %[[conv1:.*]] = zext i1 %[[x_bool]] to i32
409cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall
4102de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  struct foo f = {0};
411cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  struct foo g = {0};
412cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  g.big[12] = 12;
413cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  return x & __c11_atomic_compare_exchange_strong(&bigAtomic, &f, g, 5, 5);
414cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  // CHECK: %[[call2:.*]] = call zeroext i1 @__atomic_compare_exchange(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*),
415cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  // CHECK: %[[conv2:.*]] = zext i1 %[[call2]] to i32
416cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  // CHECK: %[[and:.*]] = and i32 %[[conv1]], %[[conv2]]
417cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  // CHECK: ret i32 %[[and]]
418cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall}
419cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall
420cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall// Check that no atomic operations are used in any initialisation of _Atomic
421cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall// types.
422cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall_Atomic(int) atomic_init_i = 42;
423cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall
424cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall// CHECK-LABEL: @atomic_init_foo
425cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCallvoid atomic_init_foo()
4260bab0cdab751248ca389a5592bcb70eac5d39260John McCall{
4270bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-NOT: }
4280bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-NOT: atomic
4290bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: store
4300bab0cdab751248ca389a5592bcb70eac5d39260John McCall  _Atomic(int) j = 12;
4310bab0cdab751248ca389a5592bcb70eac5d39260John McCall
4320bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-NOT: }
4330bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-NOT: atomic
4340bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: store
4350bab0cdab751248ca389a5592bcb70eac5d39260John McCall  __c11_atomic_init(&j, 42);
4360bab0cdab751248ca389a5592bcb70eac5d39260John McCall
4370bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-NOT: atomic
4380bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: }
4390bab0cdab751248ca389a5592bcb70eac5d39260John McCall}
4400bab0cdab751248ca389a5592bcb70eac5d39260John McCall
4410bab0cdab751248ca389a5592bcb70eac5d39260John McCall// CHECK-LABEL: @failureOrder
4420bab0cdab751248ca389a5592bcb70eac5d39260John McCallvoid failureOrder(_Atomic(int) *ptr, int *ptr2) {
4430bab0cdab751248ca389a5592bcb70eac5d39260John McCall  __c11_atomic_compare_exchange_strong(ptr, ptr2, 43, memory_order_acquire, memory_order_relaxed);
4440bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: cmpxchg i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} acquire monotonic
4450bab0cdab751248ca389a5592bcb70eac5d39260John McCall
4460bab0cdab751248ca389a5592bcb70eac5d39260John McCall  __c11_atomic_compare_exchange_weak(ptr, ptr2, 43, memory_order_seq_cst, memory_order_acquire);
4470bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: cmpxchg weak i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} seq_cst acquire
4480bab0cdab751248ca389a5592bcb70eac5d39260John McCall
4490bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // Unknown ordering: conservatively pick strongest valid option (for now!).
4500bab0cdab751248ca389a5592bcb70eac5d39260John McCall  __atomic_compare_exchange(ptr2, ptr2, ptr2, 0, memory_order_acq_rel, *ptr2);
4510bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: cmpxchg i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} acq_rel acquire
4520bab0cdab751248ca389a5592bcb70eac5d39260John McCall
4530bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // Undefined behaviour: don't really care what that last ordering is so leave
4540bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // it out:
4550bab0cdab751248ca389a5592bcb70eac5d39260John McCall  __atomic_compare_exchange_n(ptr2, ptr2, 43, 1, memory_order_seq_cst, 42);
4560bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: cmpxchg weak i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} seq_cst
4570bab0cdab751248ca389a5592bcb70eac5d39260John McCall}
4580bab0cdab751248ca389a5592bcb70eac5d39260John McCall
4590bab0cdab751248ca389a5592bcb70eac5d39260John McCall// CHECK-LABEL: @generalFailureOrder
460875ab10245d3bf37252dd822aa1616bb0a391095John McCallvoid generalFailureOrder(_Atomic(int) *ptr, int *ptr2, int success, int fail) {
461875ab10245d3bf37252dd822aa1616bb0a391095John McCall  __c11_atomic_compare_exchange_strong(ptr, ptr2, 42, success, fail);
4620bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: switch i32 {{.*}}, label %[[MONOTONIC:[0-9a-zA-Z._]+]] [
463875ab10245d3bf37252dd822aa1616bb0a391095John McCall  // CHECK-NEXT: i32 1, label %[[ACQUIRE:[0-9a-zA-Z._]+]]
464875ab10245d3bf37252dd822aa1616bb0a391095John McCall  // CHECK-NEXT: i32 2, label %[[ACQUIRE]]
465875ab10245d3bf37252dd822aa1616bb0a391095John McCall  // CHECK-NEXT: i32 3, label %[[RELEASE:[0-9a-zA-Z._]+]]
466875ab10245d3bf37252dd822aa1616bb0a391095John McCall  // CHECK-NEXT: i32 4, label %[[ACQREL:[0-9a-zA-Z._]+]]
467cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  // CHECK-NEXT: i32 5, label %[[SEQCST:[0-9a-zA-Z._]+]]
468cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall
4690bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: [[MONOTONIC]]
4700bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: switch {{.*}}, label %[[MONOTONIC_MONOTONIC:[0-9a-zA-Z._]+]] [
4710bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-NEXT: ]
4720bab0cdab751248ca389a5592bcb70eac5d39260John McCall
4730bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: [[ACQUIRE]]
4740bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: switch {{.*}}, label %[[ACQUIRE_MONOTONIC:[0-9a-zA-Z._]+]] [
475c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  // CHECK-NEXT: i32 1, label %[[ACQUIRE_ACQUIRE:[0-9a-zA-Z._]+]]
476cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  // CHECK-NEXT: i32 2, label %[[ACQUIRE_ACQUIRE:[0-9a-zA-Z._]+]]
477cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  // CHECK-NEXT: ]
478cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall
479cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  // CHECK: [[RELEASE]]
4800bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: switch {{.*}}, label %[[RELEASE_MONOTONIC:[0-9a-zA-Z._]+]] [
4810bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-NEXT: ]
4820bab0cdab751248ca389a5592bcb70eac5d39260John McCall
4830bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: [[ACQREL]]
4840bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: switch {{.*}}, label %[[ACQREL_MONOTONIC:[0-9a-zA-Z._]+]] [
4850bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-NEXT: i32 1, label %[[ACQREL_ACQUIRE:[0-9a-zA-Z._]+]]
4860bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-NEXT: i32 2, label %[[ACQREL_ACQUIRE:[0-9a-zA-Z._]+]]
487d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK-NEXT: ]
488d608cdb7c044365cf4e8764ade1e11e99c176078John McCall
489d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: [[SEQCST]]
490c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  // CHECK: switch {{.*}}, label %[[SEQCST_MONOTONIC:[0-9a-zA-Z._]+]] [
491cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  // CHECK-NEXT: i32 1, label %[[SEQCST_ACQUIRE:[0-9a-zA-Z._]+]]
492cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall  // CHECK-NEXT: i32 2, label %[[SEQCST_ACQUIRE:[0-9a-zA-Z._]+]]
4935808ce43f8d7e71f5acacc9ca320268c4f37565aJohn McCall  // CHECK-NEXT: i32 5, label %[[SEQCST_SEQCST:[0-9a-zA-Z._]+]]
4945808ce43f8d7e71f5acacc9ca320268c4f37565aJohn McCall  // CHECK-NEXT: ]
4955808ce43f8d7e71f5acacc9ca320268c4f37565aJohn McCall
4960bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: [[MONOTONIC_MONOTONIC]]
4970bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: cmpxchg {{.*}} monotonic monotonic
4980bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: br
4995808ce43f8d7e71f5acacc9ca320268c4f37565aJohn McCall
5000bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: [[ACQUIRE_MONOTONIC]]
5010bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: cmpxchg {{.*}} acquire monotonic
502755d8497e39071aa24acc173ff07083e3256b8f8John McCall  // CHECK: br
503d608cdb7c044365cf4e8764ade1e11e99c176078John McCall
504d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: [[ACQUIRE_ACQUIRE]]
505875ab10245d3bf37252dd822aa1616bb0a391095John McCall  // CHECK: cmpxchg {{.*}} acquire acquire
506d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: br
5070bab0cdab751248ca389a5592bcb70eac5d39260John McCall
508875ab10245d3bf37252dd822aa1616bb0a391095John McCall  // CHECK: [[ACQREL_MONOTONIC]]
509d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: cmpxchg {{.*}} acq_rel monotonic
510d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: br
511d608cdb7c044365cf4e8764ade1e11e99c176078John McCall
512d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: [[ACQREL_ACQUIRE]]
513875ab10245d3bf37252dd822aa1616bb0a391095John McCall  // CHECK: cmpxchg {{.*}} acq_rel acquire
5141246ba6f6801390ffc0e1d4b83a2b45e72283b8fKen Dyck  // CHECK: br
5151246ba6f6801390ffc0e1d4b83a2b45e72283b8fKen Dyck
5161246ba6f6801390ffc0e1d4b83a2b45e72283b8fKen Dyck  // CHECK: [[SEQCST_MONOTONIC]]
5171246ba6f6801390ffc0e1d4b83a2b45e72283b8fKen Dyck  // CHECK: cmpxchg {{.*}} seq_cst monotonic
518d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: br
519d608cdb7c044365cf4e8764ade1e11e99c176078John McCall
520d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: [[SEQCST_ACQUIRE]]
521d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: cmpxchg {{.*}} seq_cst acquire
522d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: br
523d608cdb7c044365cf4e8764ade1e11e99c176078John McCall
524d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: [[SEQCST_SEQCST]]
525d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: cmpxchg {{.*}} seq_cst seq_cst
526d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: br
527d608cdb7c044365cf4e8764ade1e11e99c176078John McCall}
528d608cdb7c044365cf4e8764ade1e11e99c176078John McCall
529d608cdb7c044365cf4e8764ade1e11e99c176078John McCallvoid generalWeakness(int *ptr, int *ptr2, _Bool weak) {
530d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  __atomic_compare_exchange_n(ptr, ptr2, 42, weak, memory_order_seq_cst, memory_order_seq_cst);
531d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: switch i1 {{.*}}, label %[[WEAK:[0-9a-zA-Z._]+]] [
532d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK-NEXT: i1 false, label %[[STRONG:[0-9a-zA-Z._]+]]
533d608cdb7c044365cf4e8764ade1e11e99c176078John McCall
534d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: [[STRONG]]
535d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK-NOT: br
536d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: cmpxchg {{.*}} seq_cst seq_cst
537755d8497e39071aa24acc173ff07083e3256b8f8John McCall  // CHECK: br
538755d8497e39071aa24acc173ff07083e3256b8f8John McCall
539755d8497e39071aa24acc173ff07083e3256b8f8John McCall  // CHECK: [[WEAK]]
540755d8497e39071aa24acc173ff07083e3256b8f8John McCall  // CHECK-NOT: br
541755d8497e39071aa24acc173ff07083e3256b8f8John McCall  // CHECK: cmpxchg weak {{.*}} seq_cst seq_cst
542755d8497e39071aa24acc173ff07083e3256b8f8John McCall  // CHECK: br
543755d8497e39071aa24acc173ff07083e3256b8f8John McCall}
544d608cdb7c044365cf4e8764ade1e11e99c176078John McCall
545755d8497e39071aa24acc173ff07083e3256b8f8John McCall// Having checked the flow in the previous two cases, we'll trust clang to
546755d8497e39071aa24acc173ff07083e3256b8f8John McCall// combine them sanely.
547755d8497e39071aa24acc173ff07083e3256b8f8John McCallvoid EMIT_ALL_THE_THINGS(int *ptr, int *ptr2, int new, _Bool weak, int success, int fail) {
548d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  __atomic_compare_exchange(ptr, ptr2, &new, weak, success, fail);
549755d8497e39071aa24acc173ff07083e3256b8f8John McCall
550d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: = cmpxchg {{.*}} monotonic monotonic
551379b5155b4566f63679e1da6b0ceb5fdfa2aec6dJohn McCall  // CHECK: = cmpxchg weak {{.*}} monotonic monotonic
552d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: = cmpxchg {{.*}} acquire monotonic
553d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: = cmpxchg {{.*}} acquire acquire
554d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK: = cmpxchg weak {{.*}} acquire monotonic
555c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner  // CHECK: = cmpxchg weak {{.*}} acquire acquire
556875ab10245d3bf37252dd822aa1616bb0a391095John McCall  // CHECK: = cmpxchg {{.*}} release monotonic
557875ab10245d3bf37252dd822aa1616bb0a391095John McCall  // CHECK: = cmpxchg weak {{.*}} release monotonic
558e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK: = cmpxchg {{.*}} acq_rel monotonic
559e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK: = cmpxchg {{.*}} acq_rel acquire
560e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK: = cmpxchg weak {{.*}} acq_rel monotonic
561e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK: = cmpxchg weak {{.*}} acq_rel acquire
562e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK: = cmpxchg {{.*}} seq_cst monotonic
5630bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: = cmpxchg {{.*}} seq_cst acquire
5640bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: = cmpxchg {{.*}} seq_cst seq_cst
5650bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: = cmpxchg weak {{.*}} seq_cst monotonic
5660bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: = cmpxchg weak {{.*}} seq_cst acquire
5670bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK: = cmpxchg weak {{.*}} seq_cst seq_cst
568e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall}
569e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall
570e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCallint PR21643() {
571e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  return __atomic_or_fetch((int __attribute__((address_space(257))) *)0x308, 1,
572e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall                           __ATOMIC_RELAXED);
573e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK: %[[atomictmp:.*]] = alloca i32, align 4
574e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK: %[[atomicdst:.*]] = alloca i32, align 4
575e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK: store i32 1, i32* %[[atomictmp]]
576e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK: %[[one:.*]] = load i32, i32* %[[atomictmp]], align 4
577e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK: %[[old:.*]] = atomicrmw or i32 addrspace(257)* inttoptr (i32 776 to i32 addrspace(257)*), i32 %[[one]] monotonic
578e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK: %[[new:.*]] = or i32 %[[old]], %[[one]]
579e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK: store i32 %[[new]], i32* %[[atomicdst]], align 4
580e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK: %[[ret:.*]] = load i32, i32* %[[atomicdst]], align 4
581e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK: ret i32 %[[ret]]
5820bab0cdab751248ca389a5592bcb70eac5d39260John McCall}
5830bab0cdab751248ca389a5592bcb70eac5d39260John McCall
5840bab0cdab751248ca389a5592bcb70eac5d39260John McCallint PR17306_1(volatile _Atomic(int) *i) {
5850bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-LABEL: @PR17306_1
5860bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK:      %[[i_addr:.*]] = alloca i32
5870bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-NEXT: %[[atomicdst:.*]] = alloca i32
5880bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-NEXT: store i32* %i, i32** %[[i_addr]]
589de719f7131e1ece5c9d6b5ffe21b83286d29f10fJohn McCall  // CHECK-NEXT: %[[addr:.*]] = load i32*, i32** %[[i_addr]]
5900bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-NEXT: %[[res:.*]] = load atomic volatile i32, i32* %[[addr]] seq_cst
591de719f7131e1ece5c9d6b5ffe21b83286d29f10fJohn McCall  // CHECK-NEXT: store i32 %[[res]], i32* %[[atomicdst]]
592de719f7131e1ece5c9d6b5ffe21b83286d29f10fJohn McCall  // CHECK-NEXT: %[[retval:.*]] = load i32, i32* %[[atomicdst]]
593de719f7131e1ece5c9d6b5ffe21b83286d29f10fJohn McCall  // CHECK-NEXT: ret i32 %[[retval]]
5940bab0cdab751248ca389a5592bcb70eac5d39260John McCall  return __c11_atomic_load(i, memory_order_seq_cst);
5950bab0cdab751248ca389a5592bcb70eac5d39260John McCall}
5960bab0cdab751248ca389a5592bcb70eac5d39260John McCall
5970bab0cdab751248ca389a5592bcb70eac5d39260John McCallint PR17306_2(volatile int *i, int value) {
5980bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK-LABEL: @PR17306_2
5990bab0cdab751248ca389a5592bcb70eac5d39260John McCall  // CHECK:      %[[i_addr:.*]] = alloca i32*
600e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK-NEXT: %[[value_addr:.*]] = alloca i32
601e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK-NEXT: %[[atomictmp:.*]] = alloca i32
602e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK-NEXT: %[[atomicdst:.*]] = alloca i32
603e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK-NEXT: store i32* %i, i32** %[[i_addr]]
604e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK-NEXT: store i32 %value, i32* %[[value_addr]]
605e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK-NEXT: %[[i_lval:.*]] = load i32*, i32** %[[i_addr]]
606e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK-NEXT: %[[value:.*]] = load i32, i32* %[[value_addr]]
607e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK-NEXT: store i32 %[[value]], i32* %[[atomictmp]]
608e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK-NEXT: %[[value_lval:.*]] = load i32, i32* %[[atomictmp]]
609e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK-NEXT: %[[old_val:.*]] = atomicrmw volatile add i32* %[[i_lval]], i32 %[[value_lval]] seq_cst
610e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK-NEXT: %[[new_val:.*]] = add i32 %[[old_val]], %[[value_lval]]
611e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  // CHECK-NEXT: store i32 %[[new_val]], i32* %[[atomicdst]]
612d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK-NEXT: %[[retval:.*]] = load i32, i32* %[[atomicdst]]
613d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // CHECK-NEXT: ret i32 %[[retval]]
614e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall  return __atomic_add_fetch(i, value, memory_order_seq_cst);
615e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall}
616e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall
617e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall#endif
618e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall