14967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// RUN: %clang_cc1 %s -emit-llvm -o - -ffreestanding -ffake-address-space-map -triple=i686-apple-darwin9 | FileCheck %s
287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// REQUIRES: x86-registered-target
3276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman
4e1b2abc2ed3f2c98985b06b4ad01c977bd584020Richard Smith// Also test serialization of atomic operations here, to avoid duplicating the
5e1b2abc2ed3f2c98985b06b4ad01c977bd584020Richard Smith// test.
64967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// RUN: %clang_cc1 %s -emit-pch -o %t -ffreestanding -ffake-address-space-map -triple=i686-apple-darwin9
74967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// RUN: %clang_cc1 %s -include-pch %t -ffreestanding -ffake-address-space-map -triple=i686-apple-darwin9 -emit-llvm -o - | FileCheck %s
8e1b2abc2ed3f2c98985b06b4ad01c977bd584020Richard Smith#ifndef ALREADY_INCLUDED
9e1b2abc2ed3f2c98985b06b4ad01c977bd584020Richard Smith#define ALREADY_INCLUDED
10e1b2abc2ed3f2c98985b06b4ad01c977bd584020Richard Smith
11176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#include <stdatomic.h>
12276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman
13176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// Basic IRGen tests for __c11_atomic_* and GNU __atomic_*
14276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman
15276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedmanint fi1(_Atomic(int) *i) {
16c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @fi1
173ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK: load atomic i32, i32* {{.*}} seq_cst
18fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith  return __c11_atomic_load(i, memory_order_seq_cst);
19276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman}
20276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman
21ff34d401ff385ef7173ca612432b4ea717fff690Richard Smithint fi1a(int *i) {
22c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @fi1a
233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK: load atomic i32, i32* {{.*}} seq_cst
24ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  int v;
25ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  __atomic_load(i, &v, memory_order_seq_cst);
26ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  return v;
27ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith}
28ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith
29ff34d401ff385ef7173ca612432b4ea717fff690Richard Smithint fi1b(int *i) {
30c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @fi1b
313ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK: load atomic i32, i32* {{.*}} seq_cst
32ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  return __atomic_load_n(i, memory_order_seq_cst);
33ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith}
34ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith
35176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesint fi1c(atomic_int *i) {
36176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-LABEL: @fi1c
373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK: load atomic i32, i32* {{.*}} seq_cst
38176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return atomic_load(i);
39176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
40176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
41276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedmanvoid fi2(_Atomic(int) *i) {
42c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @fi2
43276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman  // CHECK: store atomic i32 {{.*}} seq_cst
44fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith  __c11_atomic_store(i, 1, memory_order_seq_cst);
45276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman}
46276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman
47ff34d401ff385ef7173ca612432b4ea717fff690Richard Smithvoid fi2a(int *i) {
48c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @fi2a
49ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK: store atomic i32 {{.*}} seq_cst
50ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  int v = 1;
51ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  __atomic_store(i, &v, memory_order_seq_cst);
52ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith}
53ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith
54ff34d401ff385ef7173ca612432b4ea717fff690Richard Smithvoid fi2b(int *i) {
55c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @fi2b
56ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK: store atomic i32 {{.*}} seq_cst
57ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  __atomic_store_n(i, 1, memory_order_seq_cst);
58ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith}
59ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith
60176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid fi2c(atomic_int *i) {
61176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-LABEL: @fi2c
62176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK: store atomic i32 {{.*}} seq_cst
63176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  atomic_store(i, 1);
64176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
65176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
66ff34d401ff385ef7173ca612432b4ea717fff690Richard Smithint fi3(_Atomic(int) *i) {
67c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @fi3
68276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman  // CHECK: atomicrmw and
69ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK-NOT: and
70ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  return __c11_atomic_fetch_and(i, 1, memory_order_seq_cst);
71ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith}
72ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith
73ff34d401ff385ef7173ca612432b4ea717fff690Richard Smithint fi3a(int *i) {
74c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @fi3a
75ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK: atomicrmw xor
76ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK-NOT: xor
77ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  return __atomic_fetch_xor(i, 1, memory_order_seq_cst);
78ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith}
79ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith
80ff34d401ff385ef7173ca612432b4ea717fff690Richard Smithint fi3b(int *i) {
81c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @fi3b
82ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK: atomicrmw add
83ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK: add
84ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  return __atomic_add_fetch(i, 1, memory_order_seq_cst);
8551b92401c9f95023a2ef27064fd5a60fd99175f5Richard Smith}
8651b92401c9f95023a2ef27064fd5a60fd99175f5Richard Smith
8751b92401c9f95023a2ef27064fd5a60fd99175f5Richard Smithint fi3c(int *i) {
88c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @fi3c
8951b92401c9f95023a2ef27064fd5a60fd99175f5Richard Smith  // CHECK: atomicrmw nand
9051b92401c9f95023a2ef27064fd5a60fd99175f5Richard Smith  // CHECK-NOT: and
9151b92401c9f95023a2ef27064fd5a60fd99175f5Richard Smith  return __atomic_fetch_nand(i, 1, memory_order_seq_cst);
9251b92401c9f95023a2ef27064fd5a60fd99175f5Richard Smith}
9351b92401c9f95023a2ef27064fd5a60fd99175f5Richard Smith
9451b92401c9f95023a2ef27064fd5a60fd99175f5Richard Smithint fi3d(int *i) {
95c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @fi3d
9651b92401c9f95023a2ef27064fd5a60fd99175f5Richard Smith  // CHECK: atomicrmw nand
9751b92401c9f95023a2ef27064fd5a60fd99175f5Richard Smith  // CHECK: and
9851b92401c9f95023a2ef27064fd5a60fd99175f5Richard Smith  // CHECK: xor
9951b92401c9f95023a2ef27064fd5a60fd99175f5Richard Smith  return __atomic_nand_fetch(i, 1, memory_order_seq_cst);
100ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith}
101ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith
102176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesint fi3e(atomic_int *i) {
103176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-LABEL: @fi3e
104176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK: atomicrmw or
105176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NOT: {{ or }}
106176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return atomic_fetch_or(i, 1);
107176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
108176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
109b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainarint fi3f(int *i) {
110b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // CHECK-LABEL: @fi3f
111b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // CHECK-NOT: store volatile
112b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // CHECK: atomicrmw or
113b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  // CHECK-NOT: {{ or }}
114b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  return __atomic_fetch_or(i, (short)1, memory_order_seq_cst);
115b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar}
116b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
117ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith_Bool fi4(_Atomic(int) *i) {
118176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-LABEL: @fi4(
119c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // 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]+]]
120c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 0
121c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 1
122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]]
123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: store i32 [[OLD]]
124ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  int cmp = 0;
125ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  return __c11_atomic_compare_exchange_strong(i, &cmp, 1, memory_order_acquire, memory_order_acquire);
126ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith}
127ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith
128ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith_Bool fi4a(int *i) {
129176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-LABEL: @fi4a
130c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // 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]+]]
131c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 0
132c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 1
133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]]
134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: store i32 [[OLD]]
135ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  int cmp = 0;
136ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  int desired = 1;
137ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  return __atomic_compare_exchange(i, &cmp, &desired, 0, memory_order_acquire, memory_order_acquire);
138276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman}
139276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman
140ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith_Bool fi4b(int *i) {
141176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-LABEL: @fi4b(
142c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // 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]+]]
143c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 0
144c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 1
145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]]
146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: store i32 [[OLD]]
147276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman  int cmp = 0;
148ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  return __atomic_compare_exchange_n(i, &cmp, 1, 1, memory_order_acquire, memory_order_acquire);
149276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman}
150276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman
151176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines_Bool fi4c(atomic_int *i) {
152176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-LABEL: @fi4c
153176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK: cmpxchg i32*
154176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int cmp = 0;
155176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return atomic_compare_exchange_strong(i, &cmp, 1);
156176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
157176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#define _AS1 __attribute__((address_space(1)))
1594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar_Bool fi4d(_Atomic(int) *i, int _AS1 *ptr2) {
1604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // CHECK-LABEL: @fi4d(
1614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // CHECK: [[EXPECTED:%[.0-9A-Z_a-z]+]] = load i32, i32 addrspace(1)* %{{[0-9]+}}
1624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // CHECK: cmpxchg i32* %{{[0-9]+}}, i32 [[EXPECTED]], i32 %{{[0-9]+}} acquire acquire
1634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return __c11_atomic_compare_exchange_strong(i, ptr2, 1, memory_order_acquire, memory_order_acquire);
1644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
1654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
166276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedmanfloat ff1(_Atomic(float) *d) {
167c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @ff1
1683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK: load atomic i32, i32* {{.*}} monotonic
169fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith  return __c11_atomic_load(d, memory_order_relaxed);
170276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman}
171276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman
172276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedmanvoid ff2(_Atomic(float) *d) {
173c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @ff2
174276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman  // CHECK: store atomic i32 {{.*}} release
175fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith  __c11_atomic_store(d, 1, memory_order_release);
176276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman}
177276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman
178276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedmanfloat ff3(_Atomic(float) *d) {
179fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith  return __c11_atomic_exchange(d, 2, memory_order_seq_cst);
180276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman}
181276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman
182176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstruct S {
183176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  double x;
184176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines};
185176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
186176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstruct S fd1(struct S *a) {
187176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-LABEL: @fd1
188176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK: [[RETVAL:%.*]] = alloca %struct.S, align 4
189176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK: [[RET:%.*]]    = alloca %struct.S, align 4
190176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK: [[CAST:%.*]]   = bitcast %struct.S* [[RET]] to i64*
19187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // CHECK: [[CALL:%.*]]   = call i64 @__atomic_load_8(
192176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK: store i64 [[CALL]], i64* [[CAST]], align 4
193176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  struct S ret;
194176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __atomic_load(a, &ret, memory_order_seq_cst);
195176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return ret;
196176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
197176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
198176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid fd2(struct S *a, struct S *b) {
199176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-LABEL: @fd2
200176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK:      [[A_ADDR:%.*]] = alloca %struct.S*, align 4
201176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: [[B_ADDR:%.*]] = alloca %struct.S*, align 4
202176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: store %struct.S* %a, %struct.S** [[A_ADDR]], align 4
203176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: store %struct.S* %b, %struct.S** [[B_ADDR]], align 4
2043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-NEXT: [[LOAD_A_PTR:%.*]] = load %struct.S*, %struct.S** [[A_ADDR]], align 4
2053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-NEXT: [[LOAD_B_PTR:%.*]] = load %struct.S*, %struct.S** [[B_ADDR]], align 4
20687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // CHECK-NEXT: [[COERCED_A_TMP:%.*]] = bitcast %struct.S* [[LOAD_A_PTR]] to i64*
207176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: [[COERCED_B:%.*]] = bitcast %struct.S* [[LOAD_B_PTR]] to i64*
20887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // CHECK-NEXT: [[COERCED_A:%.*]] = bitcast i64* [[COERCED_A_TMP]] to i8*
2093ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-NEXT: [[LOAD_B:%.*]] = load i64, i64* [[COERCED_B]], align 4
210176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: call void @__atomic_store_8(i8* [[COERCED_A]], i64 [[LOAD_B]],
211176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: ret void
212176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __atomic_store(a, b, memory_order_seq_cst);
213176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
214176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
215176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid fd3(struct S *a, struct S *b, struct S *c) {
216176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-LABEL: @fd3
217176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK:      [[A_ADDR:%.*]] = alloca %struct.S*, align 4
218176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: [[B_ADDR:%.*]] = alloca %struct.S*, align 4
219176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: [[C_ADDR:%.*]] = alloca %struct.S*, align 4
220176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: store %struct.S* %a, %struct.S** [[A_ADDR]], align 4
221176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: store %struct.S* %b, %struct.S** [[B_ADDR]], align 4
222176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: store %struct.S* %c, %struct.S** [[C_ADDR]], align 4
2233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-NEXT: [[LOAD_A_PTR:%.*]] = load %struct.S*, %struct.S** [[A_ADDR]], align 4
2243ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-NEXT: [[LOAD_B_PTR:%.*]] = load %struct.S*, %struct.S** [[B_ADDR]], align 4
2253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-NEXT: [[LOAD_C_PTR:%.*]] = load %struct.S*, %struct.S** [[C_ADDR]], align 4
22687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // CHECK-NEXT: [[COERCED_A_TMP:%.*]] = bitcast %struct.S* [[LOAD_A_PTR]] to i64*
227176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: [[COERCED_B:%.*]] = bitcast %struct.S* [[LOAD_B_PTR]] to i64*
22887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // CHECK-NEXT: [[COERCED_C:%.*]] = bitcast %struct.S* [[LOAD_C_PTR]] to i64*
22987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // CHECK-NEXT: [[COERCED_A:%.*]] = bitcast i64* [[COERCED_A_TMP]] to i8*
2303ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-NEXT: [[LOAD_B:%.*]] = load i64, i64* [[COERCED_B]], align 4
231176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: [[CALL:%.*]] = call i64 @__atomic_exchange_8(i8* [[COERCED_A]], i64 [[LOAD_B]],
232176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: store i64 [[CALL]], i64* [[COERCED_C]], align 4
233176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
234176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  __atomic_exchange(a, b, c, memory_order_seq_cst);
235176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
236176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
237176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines_Bool fd4(struct S *a, struct S *b, struct S *c) {
238176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-LABEL: @fd4
239176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK:      [[A_ADDR:%.*]] = alloca %struct.S*, align 4
240176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: [[B_ADDR:%.*]] = alloca %struct.S*, align 4
241176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: [[C_ADDR:%.*]] = alloca %struct.S*, align 4
242176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK:      store %struct.S* %a, %struct.S** [[A_ADDR]], align 4
243176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: store %struct.S* %b, %struct.S** [[B_ADDR]], align 4
244176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: store %struct.S* %c, %struct.S** [[C_ADDR]], align 4
2453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-NEXT: [[LOAD_A_PTR:%.*]] = load %struct.S*, %struct.S** [[A_ADDR]], align 4
2463ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-NEXT: [[LOAD_B_PTR:%.*]] = load %struct.S*, %struct.S** [[B_ADDR]], align 4
2473ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-NEXT: [[LOAD_C_PTR:%.*]] = load %struct.S*, %struct.S** [[C_ADDR]], align 4
24887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // CHECK-NEXT: [[COERCED_A_TMP:%.*]] = bitcast %struct.S* [[LOAD_A_PTR]] to i64*
24987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // CHECK-NEXT: [[COERCED_B_TMP:%.*]] = bitcast %struct.S* [[LOAD_B_PTR]] to i64*
250176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: [[COERCED_C:%.*]] = bitcast %struct.S* [[LOAD_C_PTR]] to i64*
25187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // CHECK-NEXT: [[COERCED_A:%.*]] = bitcast i64* [[COERCED_A_TMP]] to i8*
25287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // CHECK-NEXT: [[COERCED_B:%.*]] = bitcast i64* [[COERCED_B_TMP]] to i8*
2533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-NEXT: [[LOAD_C:%.*]] = load i64, i64* [[COERCED_C]], align 4
254176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: [[CALL:%.*]] = call zeroext i1 @__atomic_compare_exchange_8(i8* [[COERCED_A]], i8* [[COERCED_B]], i64 [[LOAD_C]]
255176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // CHECK-NEXT: ret i1 [[CALL]]
256176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return __atomic_compare_exchange(a, b, c, 1, 5, 5);
257176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
258176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
259276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedmanint* fp1(_Atomic(int*) *p) {
260c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @fp1
2613ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK: load atomic i32, i32* {{.*}} seq_cst
262fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith  return __c11_atomic_load(p, memory_order_seq_cst);
263276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman}
264276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman
265276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedmanint* fp2(_Atomic(int*) *p) {
266c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @fp2
267276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman  // CHECK: store i32 4
268276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman  // CHECK: atomicrmw add {{.*}} monotonic
269fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith  return __c11_atomic_fetch_add(p, 1, memory_order_relaxed);
270276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman}
271276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman
272ff34d401ff385ef7173ca612432b4ea717fff690Richard Smithint *fp2a(int **p) {
273c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @fp2a
274ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK: store i32 4
275ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK: atomicrmw sub {{.*}} monotonic
2762c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  // Note, the GNU builtins do not multiply by sizeof(T)!
2772c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  return __atomic_fetch_sub(p, 4, memory_order_relaxed);
278ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith}
279ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith
2802be460723940f8184ec36529b6f6ddf59c04e411Eli Friedman_Complex float fc(_Atomic(_Complex float) *c) {
281c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @fc
282276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman  // CHECK: atomicrmw xchg i64*
283fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith  return __c11_atomic_exchange(c, 2, memory_order_seq_cst);
284276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman}
285276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman
286276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedmantypedef struct X { int x; } X;
287276b061970939293f1abaf694bd3ef05b2cbda79Eli FriedmanX fs(_Atomic(X) *c) {
288c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @fs
289276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman  // CHECK: atomicrmw xchg i32*
290fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith  return __c11_atomic_exchange(c, (X){2}, memory_order_seq_cst);
291276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman}
292454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman
293ff34d401ff385ef7173ca612432b4ea717fff690Richard SmithX fsa(X *c, X *d) {
294c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @fsa
295ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK: atomicrmw xchg i32*
296ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  X ret;
297ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  __atomic_exchange(c, d, &ret, memory_order_seq_cst);
298ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  return ret;
299ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith}
300ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith
301ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith_Bool fsb(_Bool *c) {
302c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @fsb
303ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK: atomicrmw xchg i8*
304ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  return __atomic_exchange_n(c, 1, memory_order_seq_cst);
305ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith}
306ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith
3072c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smithchar flag1;
3082c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smithvolatile char flag2;
3092c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smithvoid test_and_set() {
3102c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  // CHECK: atomicrmw xchg i8* @flag1, i8 1 seq_cst
3112c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  __atomic_test_and_set(&flag1, memory_order_seq_cst);
3122c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  // CHECK: atomicrmw volatile xchg i8* @flag2, i8 1 acquire
3132c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  __atomic_test_and_set(&flag2, memory_order_acquire);
3142c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  // CHECK: store atomic volatile i8 0, i8* @flag2 release
3152c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  __atomic_clear(&flag2, memory_order_release);
3162c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  // CHECK: store atomic i8 0, i8* @flag1 seq_cst
3172c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  __atomic_clear(&flag1, memory_order_seq_cst);
3182c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith}
3192c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith
3202c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smithstruct Sixteen {
3212c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  char c[16];
3222c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith} sixteen;
3232c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smithstruct Seventeen {
3242c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  char c[17];
3252c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith} seventeen;
3262c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith
32787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarstruct Incomplete;
32887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
3292c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smithint lock_free(struct Incomplete *incomplete) {
330c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @lock_free
3312c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith
3322c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  // CHECK: call i32 @__atomic_is_lock_free(i32 3, i8* null)
3332c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  __c11_atomic_is_lock_free(3);
3342c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith
3352c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  // CHECK: call i32 @__atomic_is_lock_free(i32 16, i8* {{.*}}@sixteen{{.*}})
3362c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  __atomic_is_lock_free(16, &sixteen);
3372c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith
3382c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  // CHECK: call i32 @__atomic_is_lock_free(i32 17, i8* {{.*}}@seventeen{{.*}})
3392c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  __atomic_is_lock_free(17, &seventeen);
3402c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith
3412c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  // CHECK: call i32 @__atomic_is_lock_free(i32 4, {{.*}})
3422c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  __atomic_is_lock_free(4, incomplete);
3432c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith
3442c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  char cs[20];
3452c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  // CHECK: call i32 @__atomic_is_lock_free(i32 4, {{.*}})
3462c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  __atomic_is_lock_free(4, cs+1);
3472c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith
3482c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  // CHECK-NOT: call
3492c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  __atomic_always_lock_free(3, 0);
3502c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  __atomic_always_lock_free(16, 0);
3512c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  __atomic_always_lock_free(17, 0);
3522c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  __atomic_always_lock_free(16, &sixteen);
3532c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  __atomic_always_lock_free(17, &seventeen);
3542c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith
3552c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  int n;
3562c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith  __atomic_is_lock_free(4, &n);
3572c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith
358454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman  // CHECK: ret i32 1
359fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith  return __c11_atomic_is_lock_free(sizeof(_Atomic(int)));
3607f20c7c44e1bdee69177fd0d2499d3b53e928cdbEli Friedman}
3613a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnall
3623a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnall// Tests for atomic operations on big values.  These should call the functions
3633a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnall// defined here:
3643a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnall// http://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary#The_Library_interface
3653a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnall
3663a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnallstruct foo {
3673a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnall  int big[128];
3683a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnall};
369ff34d401ff385ef7173ca612432b4ea717fff690Richard Smithstruct bar {
370ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  char c[3];
371ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith};
3723a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnall
373ff34d401ff385ef7173ca612432b4ea717fff690Richard Smithstruct bar smallThing, thing1, thing2;
374ff34d401ff385ef7173ca612432b4ea717fff690Richard Smithstruct foo bigThing;
3753a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnall_Atomic(struct foo) bigAtomic;
3763a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnall
3773a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnallvoid structAtomicStore() {
378c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @structAtomicStore
3793a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnall  struct foo f = {0};
380ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  struct bar b = {0};
381ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  __atomic_store(&smallThing, &b, 5);
382ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK: call void @__atomic_store(i32 3, i8* {{.*}} @smallThing
383ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith
384ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  __atomic_store(&bigThing, &f, 5);
385ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK: call void @__atomic_store(i32 512, i8* {{.*}} @bigThing
3863a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnall}
3873a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnallvoid structAtomicLoad() {
388c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @structAtomicLoad
389ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  struct bar b;
390ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  __atomic_load(&smallThing, &b, 5);
391ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK: call void @__atomic_load(i32 3, i8* {{.*}} @smallThing
392ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith
393538bbe597b935a74d95c668ad209536753f13481Fariborz Jahanian  struct foo f = {0};
394ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  __atomic_load(&bigThing, &f, 5);
395ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK: call void @__atomic_load(i32 512, i8* {{.*}} @bigThing
3963a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnall}
3973a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnallstruct foo structAtomicExchange() {
398c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @structAtomicExchange
3993a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnall  struct foo f = {0};
400ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  struct foo old;
401ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  __atomic_exchange(&f, &bigThing, &old, 5);
402ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK: call void @__atomic_exchange(i32 512, {{.*}}, i8* bitcast ({{.*}} @bigThing to i8*),
403ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith
404fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith  return __c11_atomic_exchange(&bigAtomic, f, 5);
405ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK: call void @__atomic_exchange(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*),
4063a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnall}
4073a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnallint structAtomicCmpExchange() {
408c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-LABEL: @structAtomicCmpExchange
4090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK: %[[x_mem:.*]] = alloca i8
410ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  _Bool x = __atomic_compare_exchange(&smallThing, &thing1, &thing2, 1, 5, 5);
4110e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK: %[[call1:.*]] = call zeroext i1 @__atomic_compare_exchange(i32 3, {{.*}} @smallThing{{.*}} @thing1{{.*}} @thing2
4120e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK: %[[zext1:.*]] = zext i1 %[[call1]] to i8
4130e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK: store i8 %[[zext1]], i8* %[[x_mem]], align 1
4143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK: %[[x:.*]] = load i8, i8* %[[x_mem]]
4150e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK: %[[x_bool:.*]] = trunc i8 %[[x]] to i1
4160e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK: %[[conv1:.*]] = zext i1 %[[x_bool]] to i32
417ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith
4183a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnall  struct foo f = {0};
4193a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnall  struct foo g = {0};
4203a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnall  g.big[12] = 12;
421ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  return x & __c11_atomic_compare_exchange_strong(&bigAtomic, &f, g, 5, 5);
4220e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK: %[[call2:.*]] = call zeroext i1 @__atomic_compare_exchange(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*),
4230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK: %[[conv2:.*]] = zext i1 %[[call2]] to i32
4240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK: %[[and:.*]] = and i32 %[[conv1]], %[[conv2]]
4250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK: ret i32 %[[and]]
426ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith}
427ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith
428ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith// Check that no atomic operations are used in any initialisation of _Atomic
429ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith// types.
430ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith_Atomic(int) atomic_init_i = 42;
431ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith
432c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines// CHECK-LABEL: @atomic_init_foo
433ff34d401ff385ef7173ca612432b4ea717fff690Richard Smithvoid atomic_init_foo()
434ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith{
435ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK-NOT: }
436ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK-NOT: atomic
437ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK: store
438ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  _Atomic(int) j = 12;
439ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith
440ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK-NOT: }
441ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK-NOT: atomic
442ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK: store
443ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  __c11_atomic_init(&j, 42);
444ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith
445ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK-NOT: atomic
446ff34d401ff385ef7173ca612432b4ea717fff690Richard Smith  // CHECK: }
4473a7d69bf666140e45ea7d75b6887d4b67eecd68eDavid Chisnall}
448e1b2abc2ed3f2c98985b06b4ad01c977bd584020Richard Smith
449651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-LABEL: @failureOrder
450651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid failureOrder(_Atomic(int) *ptr, int *ptr2) {
451651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  __c11_atomic_compare_exchange_strong(ptr, ptr2, 43, memory_order_acquire, memory_order_relaxed);
452651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: cmpxchg i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} acquire monotonic
453651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
454651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  __c11_atomic_compare_exchange_weak(ptr, ptr2, 43, memory_order_seq_cst, memory_order_acquire);
455c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: cmpxchg weak i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} seq_cst acquire
456651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
457651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Unknown ordering: conservatively pick strongest valid option (for now!).
458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  __atomic_compare_exchange(ptr2, ptr2, ptr2, 0, memory_order_acq_rel, *ptr2);
459651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: cmpxchg i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} acq_rel acquire
460651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
461651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Undefined behaviour: don't really care what that last ordering is so leave
462651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // it out:
463651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  __atomic_compare_exchange_n(ptr2, ptr2, 43, 1, memory_order_seq_cst, 42);
464c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: cmpxchg weak i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} seq_cst
465651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
466651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
467651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-LABEL: @generalFailureOrder
468651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid generalFailureOrder(_Atomic(int) *ptr, int *ptr2, int success, int fail) {
469651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  __c11_atomic_compare_exchange_strong(ptr, ptr2, 42, success, fail);
470651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: switch i32 {{.*}}, label %[[MONOTONIC:[0-9a-zA-Z._]+]] [
471651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK-NEXT: i32 1, label %[[ACQUIRE:[0-9a-zA-Z._]+]]
472651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK-NEXT: i32 2, label %[[ACQUIRE]]
473651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK-NEXT: i32 3, label %[[RELEASE:[0-9a-zA-Z._]+]]
474651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK-NEXT: i32 4, label %[[ACQREL:[0-9a-zA-Z._]+]]
475651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK-NEXT: i32 5, label %[[SEQCST:[0-9a-zA-Z._]+]]
476651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
477651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: [[MONOTONIC]]
478651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: switch {{.*}}, label %[[MONOTONIC_MONOTONIC:[0-9a-zA-Z._]+]] [
479651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK-NEXT: ]
480651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
481651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: [[ACQUIRE]]
482651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: switch {{.*}}, label %[[ACQUIRE_MONOTONIC:[0-9a-zA-Z._]+]] [
483651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK-NEXT: i32 1, label %[[ACQUIRE_ACQUIRE:[0-9a-zA-Z._]+]]
484651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK-NEXT: i32 2, label %[[ACQUIRE_ACQUIRE:[0-9a-zA-Z._]+]]
485651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK-NEXT: ]
486651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
487651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: [[RELEASE]]
488651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: switch {{.*}}, label %[[RELEASE_MONOTONIC:[0-9a-zA-Z._]+]] [
489651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK-NEXT: ]
490651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
491651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: [[ACQREL]]
492651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: switch {{.*}}, label %[[ACQREL_MONOTONIC:[0-9a-zA-Z._]+]] [
493651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK-NEXT: i32 1, label %[[ACQREL_ACQUIRE:[0-9a-zA-Z._]+]]
494651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK-NEXT: i32 2, label %[[ACQREL_ACQUIRE:[0-9a-zA-Z._]+]]
495651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK-NEXT: ]
496651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
497651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: [[SEQCST]]
498651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: switch {{.*}}, label %[[SEQCST_MONOTONIC:[0-9a-zA-Z._]+]] [
499651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK-NEXT: i32 1, label %[[SEQCST_ACQUIRE:[0-9a-zA-Z._]+]]
500651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK-NEXT: i32 2, label %[[SEQCST_ACQUIRE:[0-9a-zA-Z._]+]]
501651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK-NEXT: i32 5, label %[[SEQCST_SEQCST:[0-9a-zA-Z._]+]]
502651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK-NEXT: ]
503651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
504651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: [[MONOTONIC_MONOTONIC]]
505651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: cmpxchg {{.*}} monotonic monotonic
506651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: br
507651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
508651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: [[ACQUIRE_MONOTONIC]]
509651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: cmpxchg {{.*}} acquire monotonic
510651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: br
511651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
512651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: [[ACQUIRE_ACQUIRE]]
513651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: cmpxchg {{.*}} acquire acquire
514651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: br
515651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
516651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: [[ACQREL_MONOTONIC]]
517651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: cmpxchg {{.*}} acq_rel monotonic
518651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: br
519651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
520651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: [[ACQREL_ACQUIRE]]
521651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: cmpxchg {{.*}} acq_rel acquire
522651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: br
523651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
524651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: [[SEQCST_MONOTONIC]]
525651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: cmpxchg {{.*}} seq_cst monotonic
526651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: br
527651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
528651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: [[SEQCST_ACQUIRE]]
529651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: cmpxchg {{.*}} seq_cst acquire
530651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: br
531651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
532651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: [[SEQCST_SEQCST]]
533651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: cmpxchg {{.*}} seq_cst seq_cst
534651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // CHECK: br
535ee1ea80a9091050c6d0a21be9d06a5f97d3ea715Eli Friedman}
536ee1ea80a9091050c6d0a21be9d06a5f97d3ea715Eli Friedman
537c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesvoid generalWeakness(int *ptr, int *ptr2, _Bool weak) {
538c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  __atomic_compare_exchange_n(ptr, ptr2, 42, weak, memory_order_seq_cst, memory_order_seq_cst);
539c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: switch i1 {{.*}}, label %[[WEAK:[0-9a-zA-Z._]+]] [
540c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-NEXT: i1 false, label %[[STRONG:[0-9a-zA-Z._]+]]
541c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
542c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: [[STRONG]]
543c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-NOT: br
544c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: cmpxchg {{.*}} seq_cst seq_cst
545c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: br
546c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
547c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: [[WEAK]]
548c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK-NOT: br
549c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: cmpxchg weak {{.*}} seq_cst seq_cst
550c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: br
551c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines}
552c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
553c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines// Having checked the flow in the previous two cases, we'll trust clang to
554c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines// combine them sanely.
555c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesvoid EMIT_ALL_THE_THINGS(int *ptr, int *ptr2, int new, _Bool weak, int success, int fail) {
556c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  __atomic_compare_exchange(ptr, ptr2, &new, weak, success, fail);
557c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
558c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: = cmpxchg {{.*}} monotonic monotonic
559c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: = cmpxchg weak {{.*}} monotonic monotonic
560c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: = cmpxchg {{.*}} acquire monotonic
561c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: = cmpxchg {{.*}} acquire acquire
562c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: = cmpxchg weak {{.*}} acquire monotonic
563c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: = cmpxchg weak {{.*}} acquire acquire
564c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: = cmpxchg {{.*}} release monotonic
565c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: = cmpxchg weak {{.*}} release monotonic
566c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: = cmpxchg {{.*}} acq_rel monotonic
567c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: = cmpxchg {{.*}} acq_rel acquire
568c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: = cmpxchg weak {{.*}} acq_rel monotonic
569c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: = cmpxchg weak {{.*}} acq_rel acquire
570c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: = cmpxchg {{.*}} seq_cst monotonic
571c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: = cmpxchg {{.*}} seq_cst acquire
572c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: = cmpxchg {{.*}} seq_cst seq_cst
573c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: = cmpxchg weak {{.*}} seq_cst monotonic
574c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: = cmpxchg weak {{.*}} seq_cst acquire
575c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // CHECK: = cmpxchg weak {{.*}} seq_cst seq_cst
576c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines}
577c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
5780e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesint PR21643() {
5790e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  return __atomic_or_fetch((int __attribute__((address_space(257))) *)0x308, 1,
5800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                           __ATOMIC_RELAXED);
5810e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK: %[[atomictmp:.*]] = alloca i32, align 4
5820e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK: %[[atomicdst:.*]] = alloca i32, align 4
5830e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK: store i32 1, i32* %[[atomictmp]]
5843ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK: %[[one:.*]] = load i32, i32* %[[atomictmp]], align 4
5850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK: %[[old:.*]] = atomicrmw or i32 addrspace(257)* inttoptr (i32 776 to i32 addrspace(257)*), i32 %[[one]] monotonic
5860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK: %[[new:.*]] = or i32 %[[old]], %[[one]]
5870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK: store i32 %[[new]], i32* %[[atomicdst]], align 4
5883ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK: %[[ret:.*]] = load i32, i32* %[[atomicdst]], align 4
5890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK: ret i32 %[[ret]]
5900e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
5910e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
5920e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesint PR17306_1(volatile _Atomic(int) *i) {
5930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK-LABEL: @PR17306_1
5940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK:      %[[i_addr:.*]] = alloca i32
5950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK-NEXT: %[[atomicdst:.*]] = alloca i32
5960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK-NEXT: store i32* %i, i32** %[[i_addr]]
5973ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-NEXT: %[[addr:.*]] = load i32*, i32** %[[i_addr]]
5983ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-NEXT: %[[res:.*]] = load atomic volatile i32, i32* %[[addr]] seq_cst
5990e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK-NEXT: store i32 %[[res]], i32* %[[atomicdst]]
6003ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-NEXT: %[[retval:.*]] = load i32, i32* %[[atomicdst]]
6010e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK-NEXT: ret i32 %[[retval]]
6020e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  return __c11_atomic_load(i, memory_order_seq_cst);
6030e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
6040e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
6050e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesint PR17306_2(volatile int *i, int value) {
6060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK-LABEL: @PR17306_2
6070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK:      %[[i_addr:.*]] = alloca i32*
6080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK-NEXT: %[[value_addr:.*]] = alloca i32
6090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK-NEXT: %[[atomictmp:.*]] = alloca i32
6100e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK-NEXT: %[[atomicdst:.*]] = alloca i32
6110e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK-NEXT: store i32* %i, i32** %[[i_addr]]
6120e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK-NEXT: store i32 %value, i32* %[[value_addr]]
6133ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-NEXT: %[[i_lval:.*]] = load i32*, i32** %[[i_addr]]
6143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-NEXT: %[[value:.*]] = load i32, i32* %[[value_addr]]
6150e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK-NEXT: store i32 %[[value]], i32* %[[atomictmp]]
6163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-NEXT: %[[value_lval:.*]] = load i32, i32* %[[atomictmp]]
6170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK-NEXT: %[[old_val:.*]] = atomicrmw volatile add i32* %[[i_lval]], i32 %[[value_lval]] seq_cst
6180e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK-NEXT: %[[new_val:.*]] = add i32 %[[old_val]], %[[value_lval]]
6190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK-NEXT: store i32 %[[new_val]], i32* %[[atomicdst]]
6203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK-NEXT: %[[retval:.*]] = load i32, i32* %[[atomicdst]]
6210e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK-NEXT: ret i32 %[[retval]]
6220e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  return __atomic_add_fetch(i, value, memory_order_seq_cst);
6230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
6240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
625e1b2abc2ed3f2c98985b06b4ad01c977bd584020Richard Smith#endif
626