re PR target/65697 (__atomic memory barriers not strong enough for __sync builtins)
[gcc.git] / gcc / config / arm / arm.c
index 56677634ee01acdc0db317b4e08fa9e1b8c8a9e3..c2dce95e611e29c31f95d1b02acceb34e0dbe29d 100644 (file)
@@ -27614,6 +27614,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));
@@ -27622,6 +27624,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);
@@ -27662,7 +27669,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))