From 7585d94ffefc0c1c80d5cb191b461fb18e124553 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 17 Dec 2015 01:33:41 +0000 Subject: [PATCH] PR c/68868 - atomic_init emits an unnecessary fence gcc/ChangeLog * ginclude/stdatomic.h (atomic_init): Use atomic_store instead of plain assignment. gcc/testsuite/ChangeLog * testsuite/gcc.dg/atomic/stdatomic-init.c: New test. From-SVN: r231733 --- gcc/ChangeLog | 6 ++ gcc/ginclude/stdatomic.h | 10 +-- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.dg/atomic/stdatomic-init.c | 121 +++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-init.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d7607d7..8e51a47 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-12-16 Martin Sebor + + PR c/68868 + * ginclude/stdatomic.h (atomic_init): Use atomic_store instead + of plain assignment. + 2015-12-15 Michael Meissner PR target/68805 diff --git a/gcc/ginclude/stdatomic.h b/gcc/ginclude/stdatomic.h index eb3b4d6..d77b569 100644 --- a/gcc/ginclude/stdatomic.h +++ b/gcc/ginclude/stdatomic.h @@ -77,12 +77,10 @@ typedef _Atomic __UINTMAX_TYPE__ atomic_uintmax_t; #define ATOMIC_VAR_INIT(VALUE) (VALUE) -#define atomic_init(PTR, VAL) \ - do \ - { \ - *(PTR) = (VAL); \ - } \ - while (0) + +/* Initialize an atomic object pointed to by PTR with VAL. */ +#define atomic_init(PTR, VAL) \ + atomic_store_explicit (PTR, VAL, __ATOMIC_RELAXED) #define kill_dependency(Y) \ __extension__ \ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cc87798..14ea413 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-12-16 Martin Sebor + + PR c/68868 + * testsuite/gcc.dg/atomic/stdatomic-init.c: New test. + 2015-12-15 Michael Meissner PR target/68805 diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-init.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-init.c new file mode 100644 index 0000000..78f55c0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-init.c @@ -0,0 +1,121 @@ +/* Test the atomic_init generic function. Verify that __atomic_store_N + is called with the last argument of memory_order_relaxed (i.e., 0) + for each invocation of the atomic_init() macro in the test and that + there are no calls to __atomic_store_N with a non-zero last argument. */ +/* { dg-do compile } */ +/* { dg-options "-fdump-tree-gimple -std=c11 -pedantic-errors" } */ +/* { dg-final { scan-tree-dump-times "__atomic_store_. \\(\[^\n\r]*, 0\\)" 54 "gimple" } } */ +/* { dg-final { scan-tree-dump-not "__atomic_store_. \\(\[^\n\r]*, \[1-5\]\\)" "gimple" } } */ + +#include + +struct Atomic { + /* Volatile to prevent re-initialization from being optimized away. */ + volatile atomic_bool b; + volatile atomic_char c; + volatile atomic_schar sc; + volatile atomic_uchar uc; + volatile atomic_short ss; + volatile atomic_ushort us; + volatile atomic_int si; + volatile atomic_uint ui; + volatile atomic_long sl; + volatile atomic_ulong ul; + volatile atomic_llong sll; + volatile atomic_ullong ull; + volatile atomic_size_t sz; +}; + +struct Value { + _Bool b; + char c; + signed char sc; + unsigned char uc; + short ss; + unsigned short us; + int si; + unsigned int ui; + long sl; + unsigned long ul; + long long sll; + unsigned long long ull; + __SIZE_TYPE__ sz; +}; + +/* Exercise the atomic_init() macro with a literal argument. */ + +void atomic_init_lit (struct Atomic *pa) +{ + atomic_init (&pa->b, 0); + atomic_init (&pa->b, 1); + + atomic_init (&pa->c, 'x'); + atomic_init (&pa->c, 0); + atomic_init (&pa->c, 1); + atomic_init (&pa->c, 255); + + atomic_init (&pa->sc, (signed char)'x'); + atomic_init (&pa->sc, (signed char)0); + atomic_init (&pa->sc, (signed char)1); + atomic_init (&pa->sc, (signed char)__SCHAR_MAX__); + + atomic_init (&pa->uc, (unsigned char)'x'); + atomic_init (&pa->uc, (unsigned char)0); + atomic_init (&pa->uc, (unsigned char)1); + atomic_init (&pa->sc, (unsigned char)__SCHAR_MAX__); + + atomic_init (&pa->ss, (signed short)0); + atomic_init (&pa->ss, (signed short)1); + atomic_init (&pa->ss, (signed short)__SHRT_MAX__); + + atomic_init (&pa->us, (unsigned short)0); + atomic_init (&pa->us, (unsigned short)1); + atomic_init (&pa->us, (unsigned short)__SHRT_MAX__); + + atomic_init (&pa->si, (signed int)0); + atomic_init (&pa->si, (signed int)1); + atomic_init (&pa->si, (signed int)__INT_MAX__); + + atomic_init (&pa->ui, (unsigned int)0); + atomic_init (&pa->ui, (unsigned int)1); + atomic_init (&pa->ui, (unsigned int)__INT_MAX__); + + atomic_init (&pa->sl, (signed long)0); + atomic_init (&pa->sl, (signed long)1); + atomic_init (&pa->sl, (signed long)__LONG_MAX__); + + atomic_init (&pa->ul, (unsigned long)0); + atomic_init (&pa->ul, (unsigned long)1); + atomic_init (&pa->ul, (unsigned long)__LONG_MAX__); + + atomic_init (&pa->sll, (signed long long)0); + atomic_init (&pa->sll, (signed long long)1); + atomic_init (&pa->sll, (signed long long)__LONG_LONG_MAX__); + + atomic_init (&pa->ull, (unsigned long long)0); + atomic_init (&pa->ull, (unsigned long long)1); + atomic_init (&pa->ull, (unsigned long long)__LONG_LONG_MAX__); + + atomic_init (&pa->sz, 0); + atomic_init (&pa->sz, 1); + atomic_init (&pa->sz, __SIZE_MAX__); +} + +/* Exercise the atomic_init() macro with an lvalue argument. */ + +void atomic_init_lval (struct Atomic *pa, const struct Value *pv) +{ + atomic_init (&pa->b, pv->b); + atomic_init (&pa->c, pv->c); + atomic_init (&pa->sc, pv->sc); + atomic_init (&pa->uc, pv->uc); + atomic_init (&pa->ss, pv->ss); + atomic_init (&pa->us, pv->us); + atomic_init (&pa->si, pv->si); + atomic_init (&pa->ui, pv->ui); + atomic_init (&pa->sl, pv->sl); + atomic_init (&pa->ul, pv->ul); + atomic_init (&pa->sll, pv->sll); + atomic_init (&pa->ull, pv->ull); + atomic_init (&pa->sz, pv->sz); +} -- 2.7.4