+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
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,
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.
+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
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}