This is the ARM version of the patches to strengthen memory barriers for the __sync builtins on ARMv8 targets (https://gcc.gnu.org/ml/gcc-patches/2015-05/msg01989.html).
This patch changes the code generated for __sync_type_compare_and_swap to remove the acquire-barrier from the load and end the operation with a fence. This also strengthens the acquire barrier generated for __sync_lock_test_and_set which, like compare-and-swap, is implemented as a form of atomic exchange. Tested as part of a series for arm-none-linux-gnueabihf with check-gcc. Ok for trunk? Matthew gcc/ 2015-06-22 Matthew Wahab <matthew.wa...@arm.com> PR Target/65697 * config/armc/arm.c (arm_split_compare_and_swap): For ARMv8, replace an initial acquire barrier with a final full barrier.
From ddb9a45acda7bb64d91c446bc40afe4b78fcc1e1 Mon Sep 17 00:00:00 2001 From: Matthew Wahab <matthew.wa...@arm.com> Date: Fri, 22 May 2015 13:36:39 +0100 Subject: [PATCH 2/3] [ARM] Strengthen barriers for compare-and-swap builtin. Change-Id: I43381b2ea88492f807d85a73d233369334c99881 --- gcc/config/arm/arm.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 94118f4..4610ff6 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -27603,6 +27603,8 @@ arm_split_compare_and_swap (rtx operands[]) scratch = operands[7]; mode = GET_MODE (mem); + bool is_armv8_sync = arm_arch8 && is_mm_sync (mod_s); + bool use_acquire = TARGET_HAVE_LDACQ && !(is_mm_relaxed (mod_s) || is_mm_consume (mod_s) || is_mm_release (mod_s)); @@ -27611,6 +27613,11 @@ arm_split_compare_and_swap (rtx operands[]) && !(is_mm_relaxed (mod_s) || is_mm_consume (mod_s) || is_mm_acquire (mod_s)); + /* For ARMv8, the load-acquire is too weak for __sync memory orders. Instead, + a full barrier is emitted after the store-release. */ + if (is_armv8_sync) + use_acquire = false; + /* Checks whether a barrier is needed and emits one accordingly. */ if (!(use_acquire || use_release)) arm_pre_atomic_barrier (mod_s); @@ -27651,7 +27658,8 @@ arm_split_compare_and_swap (rtx operands[]) emit_label (label2); /* Checks whether a barrier is needed and emits one accordingly. */ - if (!(use_acquire || use_release)) + if (is_armv8_sync + || !(use_acquire || use_release)) arm_post_atomic_barrier (mod_s); if (is_mm_relaxed (mod_f)) -- 1.9.1