diff options
Diffstat (limited to 'clang/test')
-rw-r--r-- | clang/test/CodeGen/atomic-ops.c | 56 | ||||
-rw-r--r-- | clang/test/Sema/atomic-ops.c | 84 |
2 files changed, 127 insertions, 13 deletions
diff --git a/clang/test/CodeGen/atomic-ops.c b/clang/test/CodeGen/atomic-ops.c index 24692c75854..a8de19d1b57 100644 --- a/clang/test/CodeGen/atomic-ops.c +++ b/clang/test/CodeGen/atomic-ops.c @@ -7,9 +7,7 @@ #ifndef ALREADY_INCLUDED #define ALREADY_INCLUDED -// Basic IRGen tests for __c11_atomic_* - -// FIXME: Need to implement __c11_atomic_is_lock_free +// Basic IRGen tests for __c11_atomic_* and GNU __atomic_* typedef enum memory_order { memory_order_relaxed, memory_order_consume, memory_order_acquire, @@ -131,7 +129,8 @@ int *fp2a(int **p) { // CHECK: @fp2a // CHECK: store i32 4 // CHECK: atomicrmw sub {{.*}} monotonic - return __atomic_fetch_sub(p, 1, memory_order_relaxed); + // Note, the GNU builtins do not multiply by sizeof(T)! + return __atomic_fetch_sub(p, 4, memory_order_relaxed); } _Complex float fc(_Atomic(_Complex float) *c) { @@ -161,8 +160,55 @@ _Bool fsb(_Bool *c) { return __atomic_exchange_n(c, 1, memory_order_seq_cst); } -int lock_free() { +char flag1; +volatile char flag2; +void test_and_set() { + // CHECK: atomicrmw xchg i8* @flag1, i8 1 seq_cst + __atomic_test_and_set(&flag1, memory_order_seq_cst); + // CHECK: atomicrmw volatile xchg i8* @flag2, i8 1 acquire + __atomic_test_and_set(&flag2, memory_order_acquire); + // CHECK: store atomic volatile i8 0, i8* @flag2 release + __atomic_clear(&flag2, memory_order_release); + // CHECK: store atomic i8 0, i8* @flag1 seq_cst + __atomic_clear(&flag1, memory_order_seq_cst); +} + +struct Sixteen { + char c[16]; +} sixteen; +struct Seventeen { + char c[17]; +} seventeen; + +int lock_free(struct Incomplete *incomplete) { // CHECK: @lock_free + + // CHECK: call i32 @__atomic_is_lock_free(i32 3, i8* null) + __c11_atomic_is_lock_free(3); + + // CHECK: call i32 @__atomic_is_lock_free(i32 16, i8* {{.*}}@sixteen{{.*}}) + __atomic_is_lock_free(16, &sixteen); + + // CHECK: call i32 @__atomic_is_lock_free(i32 17, i8* {{.*}}@seventeen{{.*}}) + __atomic_is_lock_free(17, &seventeen); + + // CHECK: call i32 @__atomic_is_lock_free(i32 4, {{.*}}) + __atomic_is_lock_free(4, incomplete); + + char cs[20]; + // CHECK: call i32 @__atomic_is_lock_free(i32 4, {{.*}}) + __atomic_is_lock_free(4, cs+1); + + // CHECK-NOT: call + __atomic_always_lock_free(3, 0); + __atomic_always_lock_free(16, 0); + __atomic_always_lock_free(17, 0); + __atomic_always_lock_free(16, &sixteen); + __atomic_always_lock_free(17, &seventeen); + + int n; + __atomic_is_lock_free(4, &n); + // CHECK: ret i32 1 return __c11_atomic_is_lock_free(sizeof(_Atomic(int))); } diff --git a/clang/test/Sema/atomic-ops.c b/clang/test/Sema/atomic-ops.c index 0e5634f1d58..f769271631b 100644 --- a/clang/test/Sema/atomic-ops.c +++ b/clang/test/Sema/atomic-ops.c @@ -1,14 +1,7 @@ -// RUN: %clang_cc1 %s -verify -fsyntax-only +// RUN: %clang_cc1 %s -verify -fsyntax-only -triple=i686-linux-gnu // Basic parsing/Sema tests for __c11_atomic_* -// FIXME: Need to implement: -// __c11_atomic_is_lock_free -// __atomic_is_lock_free -// __atomic_always_lock_free -// __atomic_test_and_set -// __atomic_clear - typedef enum memory_order { memory_order_relaxed, memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel, memory_order_seq_cst @@ -16,6 +9,73 @@ typedef enum memory_order { struct S { char c[3]; }; +_Static_assert(__GCC_ATOMIC_BOOL_LOCK_FREE == 2, ""); +_Static_assert(__GCC_ATOMIC_CHAR_LOCK_FREE == 2, ""); +_Static_assert(__GCC_ATOMIC_CHAR16_T_LOCK_FREE == 2, ""); +_Static_assert(__GCC_ATOMIC_CHAR32_T_LOCK_FREE == 2, ""); +_Static_assert(__GCC_ATOMIC_WCHAR_T_LOCK_FREE == 2, ""); +_Static_assert(__GCC_ATOMIC_SHORT_LOCK_FREE == 2, ""); +_Static_assert(__GCC_ATOMIC_INT_LOCK_FREE == 2, ""); +_Static_assert(__GCC_ATOMIC_LONG_LOCK_FREE == 2, ""); +_Static_assert(__GCC_ATOMIC_LLONG_LOCK_FREE == 1, ""); +_Static_assert(__GCC_ATOMIC_POINTER_LOCK_FREE == 2, ""); + +_Static_assert(__c11_atomic_is_lock_free(1), ""); +_Static_assert(__c11_atomic_is_lock_free(2), ""); +_Static_assert(__c11_atomic_is_lock_free(3), ""); // expected-error {{not an integral constant expression}} +_Static_assert(__c11_atomic_is_lock_free(4), ""); +_Static_assert(__c11_atomic_is_lock_free(8), ""); +_Static_assert(__c11_atomic_is_lock_free(16), ""); // expected-error {{not an integral constant expression}} +_Static_assert(__c11_atomic_is_lock_free(17), ""); // expected-error {{not an integral constant expression}} + +_Static_assert(__atomic_is_lock_free(1, 0), ""); +_Static_assert(__atomic_is_lock_free(2, 0), ""); +_Static_assert(__atomic_is_lock_free(3, 0), ""); // expected-error {{not an integral constant expression}} +_Static_assert(__atomic_is_lock_free(4, 0), ""); +_Static_assert(__atomic_is_lock_free(8, 0), ""); +_Static_assert(__atomic_is_lock_free(16, 0), ""); // expected-error {{not an integral constant expression}} +_Static_assert(__atomic_is_lock_free(17, 0), ""); // expected-error {{not an integral constant expression}} + +char i8; +short i16; +int i32; +int __attribute__((vector_size(8))) i64; +struct Incomplete *incomplete; + +_Static_assert(__atomic_is_lock_free(1, &i8), ""); +_Static_assert(__atomic_is_lock_free(1, &i64), ""); +_Static_assert(__atomic_is_lock_free(2, &i8), ""); // expected-error {{not an integral constant expression}} +_Static_assert(__atomic_is_lock_free(2, &i16), ""); +_Static_assert(__atomic_is_lock_free(2, &i64), ""); +_Static_assert(__atomic_is_lock_free(4, &i16), ""); // expected-error {{not an integral constant expression}} +_Static_assert(__atomic_is_lock_free(4, &i32), ""); +_Static_assert(__atomic_is_lock_free(4, &i64), ""); +_Static_assert(__atomic_is_lock_free(8, &i32), ""); // expected-error {{not an integral constant expression}} +_Static_assert(__atomic_is_lock_free(8, &i64), ""); + +_Static_assert(__atomic_always_lock_free(1, 0), ""); +_Static_assert(__atomic_always_lock_free(2, 0), ""); +_Static_assert(!__atomic_always_lock_free(3, 0), ""); +_Static_assert(__atomic_always_lock_free(4, 0), ""); +_Static_assert(__atomic_always_lock_free(8, 0), ""); +_Static_assert(!__atomic_always_lock_free(16, 0), ""); +_Static_assert(!__atomic_always_lock_free(17, 0), ""); + +_Static_assert(__atomic_always_lock_free(1, incomplete), ""); +_Static_assert(!__atomic_always_lock_free(2, incomplete), ""); +_Static_assert(!__atomic_always_lock_free(4, incomplete), ""); + +_Static_assert(__atomic_always_lock_free(1, &i8), ""); +_Static_assert(__atomic_always_lock_free(1, &i64), ""); +_Static_assert(!__atomic_always_lock_free(2, &i8), ""); +_Static_assert(__atomic_always_lock_free(2, &i16), ""); +_Static_assert(__atomic_always_lock_free(2, &i64), ""); +_Static_assert(!__atomic_always_lock_free(4, &i16), ""); +_Static_assert(__atomic_always_lock_free(4, &i32), ""); +_Static_assert(__atomic_always_lock_free(4, &i64), ""); +_Static_assert(!__atomic_always_lock_free(8, &i32), ""); +_Static_assert(__atomic_always_lock_free(8, &i64), ""); + void f(_Atomic(int) *i, _Atomic(int*) *p, _Atomic(float) *d, int *I, int **P, float *D, struct S *s1, struct S *s2) { __c11_atomic_init(I, 5); // expected-error {{pointer to _Atomic}} @@ -94,4 +154,12 @@ void f(_Atomic(int) *i, _Atomic(int*) *p, _Atomic(float) *d, _Bool cmpexch_7 = __atomic_compare_exchange(I, I, 5, 1, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{passing 'int' to parameter of type 'int *'}} _Bool cmpexch_8 = __atomic_compare_exchange(I, P, I, 0, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{; dereference with *}} _Bool cmpexch_9 = __atomic_compare_exchange(I, I, I, 0, memory_order_seq_cst, memory_order_seq_cst); + + const volatile int flag_k = 0; + volatile int flag = 0; + (void)(int)__atomic_test_and_set(&flag_k, memory_order_seq_cst); // expected-warning {{passing 'const volatile int *' to parameter of type 'volatile void *'}} + (void)(int)__atomic_test_and_set(&flag, memory_order_seq_cst); + __atomic_clear(&flag_k, memory_order_seq_cst); // expected-warning {{passing 'const volatile int *' to parameter of type 'volatile void *'}} + __atomic_clear(&flag, memory_order_seq_cst); + (int)__atomic_clear(&flag, memory_order_seq_cst); // expected-error {{operand of type 'void'}} } |