blob: 2285cca723524874aaedd95685a995fd56e3afc3 [file] [log] [blame]
Eli Friedman276b0612011-10-11 02:20:01 +00001// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-apple-darwin9 | FileCheck %s
2
Richard Smithe1b2abc2012-04-10 22:49:28 +00003// Also test serialization of atomic operations here, to avoid duplicating the
4// test.
5// RUN: %clang_cc1 %s -emit-pch -o %t -triple=i686-apple-darwin9
6// RUN: %clang_cc1 %s -include-pch %t -triple=i686-apple-darwin9 -emit-llvm -o - | FileCheck %s
7#ifndef ALREADY_INCLUDED
8#define ALREADY_INCLUDED
9
Eli Friedman276b0612011-10-11 02:20:01 +000010// Basic IRGen tests for __atomic_*
11
12// FIXME: Need to implement __atomic_is_lock_free
13
14typedef enum memory_order {
15 memory_order_relaxed, memory_order_consume, memory_order_acquire,
16 memory_order_release, memory_order_acq_rel, memory_order_seq_cst
17} memory_order;
18
19int fi1(_Atomic(int) *i) {
20 // CHECK: @fi1
21 // CHECK: load atomic i32* {{.*}} seq_cst
22 return __atomic_load(i, memory_order_seq_cst);
23}
24
25void fi2(_Atomic(int) *i) {
26 // CHECK: @fi2
27 // CHECK: store atomic i32 {{.*}} seq_cst
28 __atomic_store(i, 1, memory_order_seq_cst);
29}
30
31void fi3(_Atomic(int) *i) {
32 // CHECK: @fi3
33 // CHECK: atomicrmw and
34 __atomic_fetch_and(i, 1, memory_order_seq_cst);
35}
36
37void fi4(_Atomic(int) *i) {
38 // CHECK: @fi4
39 // CHECK: cmpxchg i32*
40 int cmp = 0;
41 __atomic_compare_exchange_strong(i, &cmp, 1, memory_order_acquire, memory_order_acquire);
42}
43
44float ff1(_Atomic(float) *d) {
45 // CHECK: @ff1
46 // CHECK: load atomic i32* {{.*}} monotonic
47 return __atomic_load(d, memory_order_relaxed);
48}
49
50void ff2(_Atomic(float) *d) {
51 // CHECK: @ff2
52 // CHECK: store atomic i32 {{.*}} release
53 __atomic_store(d, 1, memory_order_release);
54}
55
56float ff3(_Atomic(float) *d) {
57 return __atomic_exchange(d, 2, memory_order_seq_cst);
58}
59
60int* fp1(_Atomic(int*) *p) {
61 // CHECK: @fp1
62 // CHECK: load atomic i32* {{.*}} seq_cst
63 return __atomic_load(p, memory_order_seq_cst);
64}
65
66int* fp2(_Atomic(int*) *p) {
67 // CHECK: @fp2
68 // CHECK: store i32 4
69 // CHECK: atomicrmw add {{.*}} monotonic
70 return __atomic_fetch_add(p, 1, memory_order_relaxed);
71}
72
Eli Friedman2be46072011-10-14 20:59:01 +000073_Complex float fc(_Atomic(_Complex float) *c) {
Eli Friedman276b0612011-10-11 02:20:01 +000074 // CHECK: @fc
75 // CHECK: atomicrmw xchg i64*
76 return __atomic_exchange(c, 2, memory_order_seq_cst);
77}
78
79typedef struct X { int x; } X;
80X fs(_Atomic(X) *c) {
81 // CHECK: @fs
82 // CHECK: atomicrmw xchg i32*
83 return __atomic_exchange(c, (X){2}, memory_order_seq_cst);
84}
Eli Friedman454b57a2011-10-17 21:44:23 +000085
86int lock_free() {
87 // CHECK: @lock_free
88 // CHECK: ret i32 1
89 return __atomic_is_lock_free(sizeof(_Atomic(int)));
Eli Friedman7f20c7c2011-10-17 21:48:31 +000090}
David Chisnall3a7d69b2012-03-29 18:01:11 +000091
92// Tests for atomic operations on big values. These should call the functions
93// defined here:
94// http://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary#The_Library_interface
95
96struct foo {
97 int big[128];
98};
99
100_Atomic(struct foo) bigAtomic;
101
102void structAtomicStore() {
103 // CHECK: @structAtomicStore
104 struct foo f = {0};
105 __atomic_store(&bigAtomic, f, 5);
David Chisnall882784d2012-03-29 18:41:08 +0000106 // CHECK: call void @__atomic_store(i32 512, i8* bitcast (%struct.foo* @bigAtomic to i8*),
David Chisnall3a7d69b2012-03-29 18:01:11 +0000107}
108void structAtomicLoad() {
109 // CHECK: @structAtomicLoad
110 struct foo f = __atomic_load(&bigAtomic, 5);
David Chisnall882784d2012-03-29 18:41:08 +0000111 // CHECK: call void @__atomic_load(i32 512, i8* bitcast (%struct.foo* @bigAtomic to i8*),
David Chisnall3a7d69b2012-03-29 18:01:11 +0000112}
113struct foo structAtomicExchange() {
114 // CHECK: @structAtomicExchange
115 struct foo f = {0};
116 return __atomic_exchange(&bigAtomic, f, 5);
David Chisnall882784d2012-03-29 18:41:08 +0000117 // CHECK: call void @__atomic_exchange(i32 512, i8* bitcast (%struct.foo* @bigAtomic to i8*),
David Chisnall3a7d69b2012-03-29 18:01:11 +0000118}
119int structAtomicCmpExchange() {
120 // CHECK: @structAtomicCmpExchange
121 struct foo f = {0};
122 struct foo g = {0};
123 g.big[12] = 12;
124 return __atomic_compare_exchange_strong(&bigAtomic, &f, g, 5, 5);
David Chisnall882784d2012-03-29 18:41:08 +0000125 // CHECK: call zeroext i1 @__atomic_compare_exchange(i32 512, i8* bitcast (%struct.foo* @bigAtomic to i8*),
David Chisnall3a7d69b2012-03-29 18:01:11 +0000126}
Richard Smithe1b2abc2012-04-10 22:49:28 +0000127
128#endif