aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Monakov <amonakov@ispras.ru>2017-08-28 13:58:45 +0300
committerAlexander Monakov <amonakov@gcc.gnu.org>2017-08-28 13:58:45 +0300
commit5e5ccf0d20b1104a1ec084f1de4dbbc312e9540e (patch)
tree6bf7d946daf2fa68b3387a59f7b4ffce4b0f597b
parentbf498b07586693bd0751a7aed15be59cd3f96206 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/doc/md.texi16
-rw-r--r--gcc/optabs.c18
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/atomic/pr80640.c34
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;
+}