diff mbox

Fix __atomic to not implement atomic loads with CAS.

Message ID 20170206192422.GL1849@tucnak
State New
Headers show

Commit Message

Jakub Jelinek Feb. 6, 2017, 7:24 p.m. UTC
On Wed, Feb 01, 2017 at 06:26:04PM +0100, Torvald Riegel wrote:
> On Mon, 2017-01-30 at 19:54 +0100, Torvald Riegel wrote:
> > This patch fixes the __atomic builtins to not implement supposedly
> > lock-free atomic loads based on just a compare-and-swap operation.
> 
> After an off-list OK by Jakub, I have committed this as r245098.
> Jakub will take care of the OpenMP side in a follow-up patch.

Here it is.  It is an ABI change for -fopenmp -mcx16 on x86_64, but -mcx16
used to be ABI incompatible with -mno-cx16, and it affects mostly just
__int128 and long double atomics.

Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk.

2017-02-06  Jakub Jelinek  <jakub@redhat.com>

	* omp-expand.c (oxpand_omp_atomic_fetch_op,
	expand_omp_atomic_pipeline): Return false if can_atomic_load_p is
	false.



	Jakub
diff mbox

Patch

--- gcc/omp-expand.c.jj	2017-01-25 17:17:52.000000000 +0100
+++ gcc/omp-expand.c	2017-02-06 13:41:22.703372812 +0100
@@ -6241,7 +6241,7 @@  expand_omp_atomic_fetch_op (basic_block
      matter is that (with the exception of i486 vs i586 and xadd) all targets
      that support any atomic operaton optab also implements compare-and-swap.
      Let optabs.c take care of expanding any compare-and-swap loop.  */
-  if (!can_compare_and_swap_p (imode, true))
+  if (!can_compare_and_swap_p (imode, true) || !can_atomic_load_p (imode))
     return false;
 
   gsi = gsi_last_bb (load_bb);
@@ -6318,7 +6318,8 @@  expand_omp_atomic_pipeline (basic_block
   type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
   itype = TREE_TYPE (TREE_TYPE (cmpxchg));
 
-  if (!can_compare_and_swap_p (TYPE_MODE (itype), true))
+  if (!can_compare_and_swap_p (TYPE_MODE (itype), true)
+      || !can_atomic_load_p (TYPE_MODE (itype)))
     return false;
 
   /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD.  */