diff options
Diffstat (limited to 'test/CodeGen/atomic-ops.c')
-rw-r--r-- | test/CodeGen/atomic-ops.c | 143 |
1 files changed, 134 insertions, 9 deletions
diff --git a/test/CodeGen/atomic-ops.c b/test/CodeGen/atomic-ops.c index c94f14023e..24692c7585 100644 --- a/test/CodeGen/atomic-ops.c +++ b/test/CodeGen/atomic-ops.c @@ -22,23 +22,80 @@ int fi1(_Atomic(int) *i) { return __c11_atomic_load(i, memory_order_seq_cst); } +int fi1a(int *i) { + // CHECK: @fi1a + // CHECK: load atomic i32* {{.*}} seq_cst + int v; + __atomic_load(i, &v, memory_order_seq_cst); + return v; +} + +int fi1b(int *i) { + // CHECK: @fi1b + // CHECK: load atomic i32* {{.*}} seq_cst + return __atomic_load_n(i, memory_order_seq_cst); +} + void fi2(_Atomic(int) *i) { // CHECK: @fi2 // CHECK: store atomic i32 {{.*}} seq_cst __c11_atomic_store(i, 1, memory_order_seq_cst); } -void fi3(_Atomic(int) *i) { +void fi2a(int *i) { + // CHECK: @fi2a + // CHECK: store atomic i32 {{.*}} seq_cst + int v = 1; + __atomic_store(i, &v, memory_order_seq_cst); +} + +void fi2b(int *i) { + // CHECK: @fi2b + // CHECK: store atomic i32 {{.*}} seq_cst + __atomic_store_n(i, 1, memory_order_seq_cst); +} + +int fi3(_Atomic(int) *i) { // CHECK: @fi3 // CHECK: atomicrmw and - __c11_atomic_fetch_and(i, 1, memory_order_seq_cst); + // CHECK-NOT: and + return __c11_atomic_fetch_and(i, 1, memory_order_seq_cst); +} + +int fi3a(int *i) { + // CHECK: @fi3a + // CHECK: atomicrmw xor + // CHECK-NOT: xor + return __atomic_fetch_xor(i, 1, memory_order_seq_cst); +} + +int fi3b(int *i) { + // CHECK: @fi3b + // CHECK: atomicrmw add + // CHECK: add + return __atomic_add_fetch(i, 1, memory_order_seq_cst); +} + +_Bool fi4(_Atomic(int) *i) { + // CHECK: @fi4 + // CHECK: cmpxchg i32* + int cmp = 0; + return __c11_atomic_compare_exchange_strong(i, &cmp, 1, memory_order_acquire, memory_order_acquire); +} + +_Bool fi4a(int *i) { + // CHECK: @fi4 + // CHECK: cmpxchg i32* + int cmp = 0; + int desired = 1; + return __atomic_compare_exchange(i, &cmp, &desired, 0, memory_order_acquire, memory_order_acquire); } -void fi4(_Atomic(int) *i) { +_Bool fi4b(int *i) { // CHECK: @fi4 // CHECK: cmpxchg i32* int cmp = 0; - __c11_atomic_compare_exchange_strong(i, &cmp, 1, memory_order_acquire, memory_order_acquire); + return __atomic_compare_exchange_n(i, &cmp, 1, 1, memory_order_acquire, memory_order_acquire); } float ff1(_Atomic(float) *d) { @@ -70,6 +127,13 @@ int* fp2(_Atomic(int*) *p) { return __c11_atomic_fetch_add(p, 1, memory_order_relaxed); } +int *fp2a(int **p) { + // CHECK: @fp2a + // CHECK: store i32 4 + // CHECK: atomicrmw sub {{.*}} monotonic + return __atomic_fetch_sub(p, 1, memory_order_relaxed); +} + _Complex float fc(_Atomic(_Complex float) *c) { // CHECK: @fc // CHECK: atomicrmw xchg i64* @@ -83,6 +147,20 @@ X fs(_Atomic(X) *c) { return __c11_atomic_exchange(c, (X){2}, memory_order_seq_cst); } +X fsa(X *c, X *d) { + // CHECK: @fsa + // CHECK: atomicrmw xchg i32* + X ret; + __atomic_exchange(c, d, &ret, memory_order_seq_cst); + return ret; +} + +_Bool fsb(_Bool *c) { + // CHECK: @fsb + // CHECK: atomicrmw xchg i8* + return __atomic_exchange_n(c, 1, memory_order_seq_cst); +} + int lock_free() { // CHECK: @lock_free // CHECK: ret i32 1 @@ -96,33 +174,80 @@ int lock_free() { struct foo { int big[128]; }; +struct bar { + char c[3]; +}; +struct bar smallThing, thing1, thing2; +struct foo bigThing; _Atomic(struct foo) bigAtomic; void structAtomicStore() { // CHECK: @structAtomicStore struct foo f = {0}; __c11_atomic_store(&bigAtomic, f, 5); - // CHECK: call void @__atomic_store(i32 512, i8* bitcast (%struct.foo* @bigAtomic to i8*), + // CHECK: call void @__atomic_store(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*), + + struct bar b = {0}; + __atomic_store(&smallThing, &b, 5); + // CHECK: call void @__atomic_store(i32 3, i8* {{.*}} @smallThing + + __atomic_store(&bigThing, &f, 5); + // CHECK: call void @__atomic_store(i32 512, i8* {{.*}} @bigThing } void structAtomicLoad() { // CHECK: @structAtomicLoad struct foo f = __c11_atomic_load(&bigAtomic, 5); - // CHECK: call void @__atomic_load(i32 512, i8* bitcast (%struct.foo* @bigAtomic to i8*), + // CHECK: call void @__atomic_load(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*), + + struct bar b; + __atomic_load(&smallThing, &b, 5); + // CHECK: call void @__atomic_load(i32 3, i8* {{.*}} @smallThing + + __atomic_load(&bigThing, &f, 5); + // CHECK: call void @__atomic_load(i32 512, i8* {{.*}} @bigThing } struct foo structAtomicExchange() { // CHECK: @structAtomicExchange struct foo f = {0}; + struct foo old; + __atomic_exchange(&f, &bigThing, &old, 5); + // CHECK: call void @__atomic_exchange(i32 512, {{.*}}, i8* bitcast ({{.*}} @bigThing to i8*), + return __c11_atomic_exchange(&bigAtomic, f, 5); - // CHECK: call void @__atomic_exchange(i32 512, i8* bitcast (%struct.foo* @bigAtomic to i8*), + // CHECK: call void @__atomic_exchange(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*), } int structAtomicCmpExchange() { // CHECK: @structAtomicCmpExchange + _Bool x = __atomic_compare_exchange(&smallThing, &thing1, &thing2, 1, 5, 5); + // CHECK: call zeroext i1 @__atomic_compare_exchange(i32 3, {{.*}} @smallThing{{.*}} @thing1{{.*}} @thing2 + struct foo f = {0}; struct foo g = {0}; g.big[12] = 12; - return __c11_atomic_compare_exchange_strong(&bigAtomic, &f, g, 5, 5); - // CHECK: call zeroext i1 @__atomic_compare_exchange(i32 512, i8* bitcast (%struct.foo* @bigAtomic to i8*), + return x & __c11_atomic_compare_exchange_strong(&bigAtomic, &f, g, 5, 5); + // CHECK: call zeroext i1 @__atomic_compare_exchange(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*), +} + +// Check that no atomic operations are used in any initialisation of _Atomic +// types. +_Atomic(int) atomic_init_i = 42; + +// CHECK: @atomic_init_foo +void atomic_init_foo() +{ + // CHECK-NOT: } + // CHECK-NOT: atomic + // CHECK: store + _Atomic(int) j = 12; + + // CHECK-NOT: } + // CHECK-NOT: atomic + // CHECK: store + __c11_atomic_init(&j, 42); + + // CHECK-NOT: atomic + // CHECK: } } #endif |