mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-18 08:23:50 +08:00
re PR middle-end/61252 (Invalid code produced for omp simd reduction(min:var) where var is reference)
PR middle-end/61252 * omp-low.c (handle_simd_reference): New function. (lower_rec_input_clauses): Use it. Defer adding reference initialization even for reduction without placeholder if in simd, handle it properly later on. * testsuite/libgomp.c++/simd-9.C: New test. From-SVN: r210679
This commit is contained in:
parent
c3d96270fc
commit
decaaec811
@ -1,3 +1,11 @@
|
||||
2014-05-21 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/61252
|
||||
* omp-low.c (handle_simd_reference): New function.
|
||||
(lower_rec_input_clauses): Use it. Defer adding reference
|
||||
initialization even for reduction without placeholder if in simd,
|
||||
handle it properly later on.
|
||||
|
||||
2014-05-20 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
PR tree-optimization/60899
|
||||
|
@ -2998,6 +2998,27 @@ lower_rec_simd_input_clauses (tree new_var, omp_context *ctx, int &max_vf,
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Helper function of lower_rec_input_clauses. For a reference
|
||||
in simd reduction, add an underlying variable it will reference. */
|
||||
|
||||
static void
|
||||
handle_simd_reference (location_t loc, tree new_vard, gimple_seq *ilist)
|
||||
{
|
||||
tree z = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_vard)));
|
||||
if (TREE_CONSTANT (z))
|
||||
{
|
||||
const char *name = NULL;
|
||||
if (DECL_NAME (new_vard))
|
||||
name = IDENTIFIER_POINTER (DECL_NAME (new_vard));
|
||||
|
||||
z = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_vard)), name);
|
||||
gimple_add_tmp_var (z);
|
||||
TREE_ADDRESSABLE (z) = 1;
|
||||
z = build_fold_addr_expr_loc (loc, z);
|
||||
gimplify_assign (new_vard, z, ilist);
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
|
||||
from the receiver (aka child) side and initializers for REFERENCE_TYPE
|
||||
private variables. Initialization statements go in ILIST, while calls
|
||||
@ -3189,13 +3210,11 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
|
||||
}
|
||||
else if (TREE_CONSTANT (x))
|
||||
{
|
||||
/* For reduction with placeholder in SIMD loop,
|
||||
defer adding the initialization of the reference,
|
||||
because if we decide to use SIMD array for it,
|
||||
the initilization could cause expansion ICE. */
|
||||
if (c_kind == OMP_CLAUSE_REDUCTION
|
||||
&& OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
|
||||
&& is_simd)
|
||||
/* For reduction in SIMD loop, defer adding the
|
||||
initialization of the reference, because if we decide
|
||||
to use SIMD array for it, the initilization could cause
|
||||
expansion ICE. */
|
||||
if (c_kind == OMP_CLAUSE_REDUCTION && is_simd)
|
||||
x = NULL_TREE;
|
||||
else
|
||||
{
|
||||
@ -3524,23 +3543,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
|
||||
But if they aren't used, we need to emit the deferred
|
||||
initialization now. */
|
||||
else if (is_reference (var) && is_simd)
|
||||
{
|
||||
tree z
|
||||
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_vard)));
|
||||
if (TREE_CONSTANT (z))
|
||||
{
|
||||
const char *name = NULL;
|
||||
if (DECL_NAME (var))
|
||||
name = IDENTIFIER_POINTER (DECL_NAME (new_vard));
|
||||
|
||||
z = create_tmp_var_raw
|
||||
(TREE_TYPE (TREE_TYPE (new_vard)), name);
|
||||
gimple_add_tmp_var (z);
|
||||
TREE_ADDRESSABLE (z) = 1;
|
||||
z = build_fold_addr_expr_loc (clause_loc, z);
|
||||
gimplify_assign (new_vard, z, ilist);
|
||||
}
|
||||
}
|
||||
handle_simd_reference (clause_loc, new_vard, ilist);
|
||||
x = lang_hooks.decls.omp_clause_default_ctor
|
||||
(c, new_var, unshare_expr (x));
|
||||
if (x)
|
||||
@ -3573,6 +3576,13 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
|
||||
if (code == MINUS_EXPR)
|
||||
code = PLUS_EXPR;
|
||||
|
||||
tree new_vard = new_var;
|
||||
if (is_simd && is_reference (var))
|
||||
{
|
||||
gcc_assert (TREE_CODE (new_var) == MEM_REF);
|
||||
new_vard = TREE_OPERAND (new_var, 0);
|
||||
gcc_assert (DECL_P (new_vard));
|
||||
}
|
||||
if (is_simd
|
||||
&& lower_rec_simd_input_clauses (new_var, ctx, max_vf,
|
||||
idx, lane, ivar, lvar))
|
||||
@ -3584,9 +3594,18 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
|
||||
x = build2 (code, TREE_TYPE (ref), ref, ivar);
|
||||
ref = build_outer_var_ref (var, ctx);
|
||||
gimplify_assign (ref, x, &llist[1]);
|
||||
|
||||
if (new_vard != new_var)
|
||||
{
|
||||
SET_DECL_VALUE_EXPR (new_vard,
|
||||
build_fold_addr_expr (lvar));
|
||||
DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_reference (var) && is_simd)
|
||||
handle_simd_reference (clause_loc, new_vard, ilist);
|
||||
gimplify_assign (new_var, x, ilist);
|
||||
if (is_simd)
|
||||
{
|
||||
|
@ -1,3 +1,8 @@
|
||||
2014-05-21 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/61252
|
||||
* testsuite/libgomp.c++/simd-9.C: New test.
|
||||
|
||||
2014-05-18 Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
* libgomp.texi (Runitme Library Routines): Remove multiple @menu.
|
||||
|
52
libgomp/testsuite/libgomp.c++/simd-9.C
Normal file
52
libgomp/testsuite/libgomp.c++/simd-9.C
Normal file
@ -0,0 +1,52 @@
|
||||
// { dg-do run }
|
||||
// { dg-options "-O2" }
|
||||
// { dg-additional-options "-msse2" { target sse2_runtime } }
|
||||
// { dg-additional-options "-mavx" { target avx_runtime } }
|
||||
|
||||
extern "C" void abort ();
|
||||
int a[1024] __attribute__((aligned (32))) = { 1 };
|
||||
#pragma omp declare reduction (foo:int:omp_out += omp_in) \
|
||||
initializer (omp_priv = 0)
|
||||
|
||||
__attribute__((noinline, noclone)) void
|
||||
foo (int &u, int &v)
|
||||
{
|
||||
int i;
|
||||
#pragma omp simd aligned(a : 32) reduction(foo:u) reduction(+:v)
|
||||
for (i = 0; i < 1024; i++)
|
||||
{
|
||||
int x = a[i];
|
||||
u += x;
|
||||
v += x;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noinline, noclone)) void
|
||||
bar (int &u, int &v)
|
||||
{
|
||||
int i;
|
||||
#pragma omp simd aligned(a : 32) reduction(foo:u) reduction(+:v) \
|
||||
safelen(1)
|
||||
for (i = 0; i < 1024; i++)
|
||||
{
|
||||
int x = a[i];
|
||||
u += x;
|
||||
v += x;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 1024; i++)
|
||||
a[i] = (i & 31) + (i / 128);
|
||||
int u = 0, v = 0;
|
||||
foo (u, v);
|
||||
if (u != 19456 || v != 19456)
|
||||
abort ();
|
||||
u = 0; v = 0;
|
||||
bar (u, v);
|
||||
if (u != 19456 || v != 19456)
|
||||
abort ();
|
||||
}
|
Loading…
Reference in New Issue
Block a user