diff options
author | Alexander Monakov <amonakov@ispras.ru> | 2017-08-28 13:58:45 +0300 |
---|---|---|
committer | Alexander Monakov <amonakov@gcc.gnu.org> | 2017-08-28 13:58:45 +0300 |
commit | 5e5ccf0d20b1104a1ec084f1de4dbbc312e9540e (patch) | |
tree | 6bf7d946daf2fa68b3387a59f7b4ffce4b0f597b | |
parent | bf498b07586693bd0751a7aed15be59cd3f96206 (diff) | |
download | gcc-5e5ccf0d20b1104a1ec084f1de4dbbc312e9540e.zip gcc-5e5ccf0d20b1104a1ec084f1de4dbbc312e9540e.tar.gz gcc-5e5ccf0d20b1104a1ec084f1de4dbbc312e9540e.tar.bz2 |
optabs: ensure mem_thread_fence is a compiler barrier
PR target/80640
* doc/md.texi (mem_thread_fence): Remove mention of mode. Rewrite.
* optabs.c (expand_mem_thread_fence): Emit a compiler barrier when
using targetm.gen_mem_thread_fence.
testsuite/
* gcc.dg/atomic/pr80640.c: New testcase.
From-SVN: r251377
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/doc/md.texi | 16 | ||||
-rw-r--r-- | gcc/optabs.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/atomic/pr80640.c | 34 |
5 files changed, 67 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b1070d9..c79a0e8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-08-28 Alexander Monakov <amonakov@ispras.ru> + + PR target/80640 + * doc/md.texi (mem_thread_fence): Remove mention of mode. Rewrite. + * optabs.c (expand_mem_thread_fence): Emit a compiler barrier when + using targetm.gen_mem_thread_fence. + 2017-08-27 Uros Bizjak <ubizjak@gmail.com> PR target/81995 diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index ea95920..64a137e 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -7044,14 +7044,20 @@ If these patterns are not defined, attempts will be made to use counterparts. If none of these are available a compare-and-swap loop will be used. -@cindex @code{mem_thread_fence@var{mode}} instruction pattern -@item @samp{mem_thread_fence@var{mode}} +@cindex @code{mem_thread_fence} instruction pattern +@item @samp{mem_thread_fence} This pattern emits code required to implement a thread fence with memory model semantics. Operand 0 is the memory model to be used. -If this pattern is not specified, all memory models except -@code{__ATOMIC_RELAXED} will result in issuing a @code{sync_synchronize} -barrier pattern. +For the @code{__ATOMIC_RELAXED} model no instructions need to be issued +and this expansion is not invoked. + +The compiler always emits a compiler memory barrier regardless of what +expanding this pattern produced. + +If this pattern is not defined, the compiler falls back to expanding the +@code{memory_barrier} pattern, then to emitting @code{__sync_synchronize} +library call, and finally to just placing a compiler memory barrier. @cindex @code{mem_signal_fence@var{mode}} instruction pattern @item @samp{mem_signal_fence@var{mode}} diff --git a/gcc/optabs.c b/gcc/optabs.c index a990065..71b74dd 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -6297,17 +6297,19 @@ expand_asm_memory_barrier (void) void expand_mem_thread_fence (enum memmodel model) { + if (is_mm_relaxed (model)) + return; if (targetm.have_mem_thread_fence ()) - emit_insn (targetm.gen_mem_thread_fence (GEN_INT (model))); - else if (!is_mm_relaxed (model)) { - if (targetm.have_memory_barrier ()) - emit_insn (targetm.gen_memory_barrier ()); - else if (synchronize_libfunc != NULL_RTX) - emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0); - else - expand_asm_memory_barrier (); + emit_insn (targetm.gen_mem_thread_fence (GEN_INT (model))); + expand_asm_memory_barrier (); } + else if (targetm.have_memory_barrier ()) + emit_insn (targetm.gen_memory_barrier ()); + else if (synchronize_libfunc != NULL_RTX) + emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0); + else + expand_asm_memory_barrier (); } /* This routine will either emit the mem_signal_fence pattern or issue a diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d4bcd42..a3687c4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-08-28 Alexander Monakov <amonakov@ispras.ru> + + PR target/80640 + * gcc.dg/atomic/pr80640.c: New testcase. + 2017-08-27 Uros Bizjak <ubizjak@gmail.com> PR target/81995 diff --git a/gcc/testsuite/gcc.dg/atomic/pr80640.c b/gcc/testsuite/gcc.dg/atomic/pr80640.c new file mode 100644 index 0000000..fd17978 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/pr80640.c @@ -0,0 +1,34 @@ +/* { dg-do run } */ +/* { dg-options "-pthread" } */ +/* { dg-require-effective-target pthread } */ + +#include <pthread.h> + +static volatile int sem1; +static volatile int sem2; + +static void *f(void *va) +{ + void **p = va; + if (*p) return *p; + sem1 = 1; + while (!sem2); + __atomic_thread_fence(__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_thread_fence(__ATOMIC_RELEASE); + sem2 = 1; + pthread_join(thr, &p); + return !p; +} |