Hi!

When expanding #pragma omp atomic or reduction merging using
expand_omp_atomic_pipeline loop, we start by fetching the initial value
using normal memory read and only in the second and following iteration
use the one from the atomic compare and exchange.  The initial value
is just an optimization, it is better if it is what we'll want to use,
but if it is something different, except perhaps for floating point
exceptions it shouldn't really matter what exact value we load.
This patch uses __atomic_load_N with MEMMODEL_RELAXED instead of
normal load.

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

2014-01-13  Jakub Jelinek  <ja...@redhat.com>

        PR libgomp/59194
        * omp-low.c (expand_omp_atomic_pipeline): Expand the initial
        load as __atomic_load_N if possible.

--- gcc/omp-low.c.jj    2014-01-08 17:45:05.000000000 +0100
+++ gcc/omp-low.c       2014-01-10 21:12:22.498276852 +0100
@@ -7536,12 +7536,21 @@ expand_omp_atomic_pipeline (basic_block
       loadedi = loaded_val;
     }
 
+  fncode = (enum built_in_function) (BUILT_IN_ATOMIC_LOAD_N + index + 1);
+  tree loaddecl = builtin_decl_explicit (fncode);
+  if (loaddecl)
+    initial
+      = fold_convert (TREE_TYPE (TREE_TYPE (iaddr)),
+                     build_call_expr (loaddecl, 2, iaddr,
+                                      build_int_cst (NULL_TREE,
+                                                     MEMMODEL_RELAXED)));
+  else
+    initial = build2 (MEM_REF, TREE_TYPE (TREE_TYPE (iaddr)), iaddr,
+                     build_int_cst (TREE_TYPE (iaddr), 0));
+
   initial
-    = force_gimple_operand_gsi (&si,
-                               build2 (MEM_REF, TREE_TYPE (TREE_TYPE (iaddr)),
-                                       iaddr,
-                                       build_int_cst (TREE_TYPE (iaddr), 0)),
-                               true, NULL_TREE, true, GSI_SAME_STMT);
+    = force_gimple_operand_gsi (&si, initial, true, NULL_TREE, true,
+                               GSI_SAME_STMT);
 
   /* Move the value to the LOADEDI temporary.  */
   if (gimple_in_ssa_p (cfun))

        Jakub

Reply via email to