This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[committed] Fix #pragma omp atomic/atomic reductions (PR libgomp/59194)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 13 Jan 2014 09:01:00 +0100
- Subject: [committed] Fix #pragma omp atomic/atomic reductions (PR libgomp/59194)
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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 <jakub@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