optabs: ensure atomic_load/stores have compiler barriers
authorAlexander Monakov <amonakov@ispras.ru>
Mon, 4 Sep 2017 10:16:37 +0000 (13:16 +0300)
committerAlexander Monakov <amonakov@gcc.gnu.org>
Mon, 4 Sep 2017 10:16:37 +0000 (13:16 +0300)
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

gcc/ChangeLog
gcc/optabs.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/atomic/pr80640-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/atomic/pr81316.c [new file with mode: 0644]

index 50d5e26f96a9848aa0dc107fc204db80c41bfba7..5102356fcd4936cb8a649f535a5fd50f70226061 100644 (file)
@@ -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
index b7f1e2c6491ba2a922a0ae9b00eeca9abc78962c..b65707080eee32385e370580a3039e034b6f66ca 100644 (file)
@@ -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.
index 0d9e44798e6e66e86d4812c9d8dc1414b4eec3f3..20b24b6faafa10e4e070574a7ac64409ba2d63df 100644 (file)
@@ -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 (file)
index 0000000..a735054
--- /dev/null
@@ -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 (file)
index 0000000..ef10095
--- /dev/null
@@ -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;
+}