diff options
author | Alexander Monakov <amonakov@ispras.ru> | 2017-09-04 13:16:37 +0300 |
---|---|---|
committer | Alexander Monakov <amonakov@gcc.gnu.org> | 2017-09-04 13:16:37 +0300 |
commit | d8c40eff56f69877b33c697ded756d50fde90c27 (patch) | |
tree | e4a696a0929438cfbf6c366ebc3ea949267a4f51 | |
parent | 1fda57cb2dc323c7d387ab0df9de708c0889be0d (diff) | |
download | gcc-d8c40eff56f69877b33c697ded756d50fde90c27.zip gcc-d8c40eff56f69877b33c697ded756d50fde90c27.tar.gz gcc-d8c40eff56f69877b33c697ded756d50fde90c27.tar.bz2 |
optabs: ensure atomic_load/stores have compiler barriers
PR rtl-optimization/57448
PR target/67458
PR target/81316
* optabs.c (expand_atomic_load): Place compiler memory barriers if
using atomic_load pattern.
(expand_atomic_store): Likewise.
testsuite/
* gcc.dg/atomic/pr80640-2.c: New testcase.
* gcc.dg/atomic/pr81316.c: New testcase.
From-SVN: r251643
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/optabs.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/atomic/pr80640-2.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/atomic/pr81316.c | 29 |
5 files changed, 96 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 50d5e26..5102356 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2017-09-04 Alexander Monakov <amonakov@ispras.ru> + + PR rtl-optimization/57448 + PR target/67458 + PR target/81316 + * optabs.c (expand_atomic_load): Place compiler memory barriers if + using atomic_load pattern. + (expand_atomic_store): Likewise. + 2017-09-04 Jakub Jelinek <jakub@redhat.com> PR sanitizer/81981 diff --git a/gcc/optabs.c b/gcc/optabs.c index b7f1e2c..b657070 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -6344,12 +6344,20 @@ expand_atomic_load (rtx target, rtx mem, enum memmodel model) if (icode != CODE_FOR_nothing) { struct expand_operand ops[3]; + rtx_insn *last = get_last_insn (); + if (is_mm_seq_cst (model)) + expand_asm_memory_barrier (); create_output_operand (&ops[0], target, mode); create_fixed_operand (&ops[1], mem); create_integer_operand (&ops[2], model); if (maybe_expand_insn (icode, 3, ops)) - return ops[0].value; + { + if (!is_mm_relaxed (model)) + expand_asm_memory_barrier (); + return ops[0].value; + } + delete_insns_since (last); } /* If the size of the object is greater than word size on this target, @@ -6394,11 +6402,19 @@ expand_atomic_store (rtx mem, rtx val, enum memmodel model, bool use_release) icode = direct_optab_handler (atomic_store_optab, mode); if (icode != CODE_FOR_nothing) { + rtx_insn *last = get_last_insn (); + if (!is_mm_relaxed (model)) + expand_asm_memory_barrier (); create_fixed_operand (&ops[0], mem); create_input_operand (&ops[1], val, mode); create_integer_operand (&ops[2], model); if (maybe_expand_insn (icode, 3, ops)) - return const0_rtx; + { + if (is_mm_seq_cst (model)) + expand_asm_memory_barrier (); + return const0_rtx; + } + delete_insns_since (last); } /* If using __sync_lock_release is a viable alternative, try it. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0d9e447..20b24b6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2017-09-04 Alexander Monakov <amonakov@ispras.ru> + + PR rtl-optimization/57448 + PR target/67458 + PR target/81316 + * gcc.dg/atomic/pr80640-2.c: New testcase. + * gcc.dg/atomic/pr81316.c: New testcase. + 2017-09-04 Tom de Vries <tom@codesourcery.com> PR tree-optimization/82052 diff --git a/gcc/testsuite/gcc.dg/atomic/pr80640-2.c b/gcc/testsuite/gcc.dg/atomic/pr80640-2.c new file mode 100644 index 0000000..a735054 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/pr80640-2.c @@ -0,0 +1,32 @@ +/* { dg-do run } */ +/* { dg-options "-pthread" } */ +/* { dg-require-effective-target pthread } */ + +#include <pthread.h> + +static volatile int sem1; +static _Atomic int sem2; + +static void *f(void *va) +{ + void **p = va; + if (*p) return *p; + sem1 = 1; + while (!__atomic_load_n(&sem2, __ATOMIC_ACQUIRE)); + // GCC used to RTL-CSE this and the first load, causing 0 to be returned + return *p; +} + +int main() +{ + void *p = 0; + pthread_t thr; + if (pthread_create(&thr, 0, f, &p)) + return 2; + while (!sem1); + __atomic_thread_fence(__ATOMIC_ACQUIRE); + p = &p; + __atomic_store_n(&sem2, 1, __ATOMIC_RELEASE); + pthread_join(thr, &p); + return !p; +} diff --git a/gcc/testsuite/gcc.dg/atomic/pr81316.c b/gcc/testsuite/gcc.dg/atomic/pr81316.c new file mode 100644 index 0000000..ef10095 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/pr81316.c @@ -0,0 +1,29 @@ +/* { dg-do run } */ +/* { dg-options "-pthread" } */ +/* { dg-require-effective-target pthread } */ + +#include <pthread.h> +#include <stdlib.h> + +static _Atomic int sem1; + +static void *f(void *va) +{ + void **p = va; + while (!__atomic_load_n(&sem1, __ATOMIC_ACQUIRE)); + exit(!*p); +} + +int main(int argc) +{ + void *p = 0; + pthread_t thr; + if (pthread_create(&thr, 0, f, &p)) + return 2; + // GCC used to RTL-DSE this store + p = &p; + __atomic_store_n(&sem1, 1, __ATOMIC_RELEASE); + int r = -1; + while (r < 0) asm("":"+r"(r)); + return r; +} |