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>
|
2014-05-20 Jan Hubicka <hubicka@ucw.cz>
|
||||||
|
|
||||||
PR tree-optimization/60899
|
PR tree-optimization/60899
|
||||||
|
|
|
@ -2998,6 +2998,27 @@ lower_rec_simd_input_clauses (tree new_var, omp_context *ctx, int &max_vf,
|
||||||
return true;
|
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,
|
/* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
|
||||||
from the receiver (aka child) side and initializers for REFERENCE_TYPE
|
from the receiver (aka child) side and initializers for REFERENCE_TYPE
|
||||||
private variables. Initialization statements go in ILIST, while calls
|
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))
|
else if (TREE_CONSTANT (x))
|
||||||
{
|
{
|
||||||
/* For reduction with placeholder in SIMD loop,
|
/* For reduction in SIMD loop, defer adding the
|
||||||
defer adding the initialization of the reference,
|
initialization of the reference, because if we decide
|
||||||
because if we decide to use SIMD array for it,
|
to use SIMD array for it, the initilization could cause
|
||||||
the initilization could cause expansion ICE. */
|
expansion ICE. */
|
||||||
if (c_kind == OMP_CLAUSE_REDUCTION
|
if (c_kind == OMP_CLAUSE_REDUCTION && is_simd)
|
||||||
&& OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
|
|
||||||
&& is_simd)
|
|
||||||
x = NULL_TREE;
|
x = NULL_TREE;
|
||||||
else
|
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
|
But if they aren't used, we need to emit the deferred
|
||||||
initialization now. */
|
initialization now. */
|
||||||
else if (is_reference (var) && is_simd)
|
else if (is_reference (var) && is_simd)
|
||||||
{
|
handle_simd_reference (clause_loc, new_vard, ilist);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
x = lang_hooks.decls.omp_clause_default_ctor
|
x = lang_hooks.decls.omp_clause_default_ctor
|
||||||
(c, new_var, unshare_expr (x));
|
(c, new_var, unshare_expr (x));
|
||||||
if (x)
|
if (x)
|
||||||
|
@ -3573,6 +3576,13 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
|
||||||
if (code == MINUS_EXPR)
|
if (code == MINUS_EXPR)
|
||||||
code = PLUS_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
|
if (is_simd
|
||||||
&& lower_rec_simd_input_clauses (new_var, ctx, max_vf,
|
&& lower_rec_simd_input_clauses (new_var, ctx, max_vf,
|
||||||
idx, lane, ivar, lvar))
|
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);
|
x = build2 (code, TREE_TYPE (ref), ref, ivar);
|
||||||
ref = build_outer_var_ref (var, ctx);
|
ref = build_outer_var_ref (var, ctx);
|
||||||
gimplify_assign (ref, x, &llist[1]);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
if (is_reference (var) && is_simd)
|
||||||
|
handle_simd_reference (clause_loc, new_vard, ilist);
|
||||||
gimplify_assign (new_var, x, ilist);
|
gimplify_assign (new_var, x, ilist);
|
||||||
if (is_simd)
|
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>
|
2014-05-18 Uros Bizjak <ubizjak@gmail.com>
|
||||||
|
|
||||||
* libgomp.texi (Runitme Library Routines): Remove multiple @menu.
|
* libgomp.texi (Runitme Library Routines): Remove multiple @menu.
|
||||||
|
|
|
@ -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