re PR middle-end/59150 (ICE: in expand_one_var, at cfgexpand.c:1242 with -fopenmp)

PR middle-end/59150
	* omp-low.c (lower_rec_input_clause): For reduction with placeholder
	of references to constant size types in simd loops, defer emitting
	initializer for the new_var, emit it later on only if not using
	SIMD arrays for it.

	* g++.dg/gomp/pr59150.C: New test.

From-SVN: r205411
This commit is contained in:
Jakub Jelinek 2013-11-26 21:38:59 +01:00 committed by Jakub Jelinek
parent 01dde9b0e9
commit 4ceffa27ee
4 changed files with 81 additions and 10 deletions

View File

@ -1,5 +1,11 @@
2013-11-26 Jakub Jelinek <jakub@redhat.com>
PR middle-end/59150
* omp-low.c (lower_rec_input_clause): For reduction with placeholder
of references to constant size types in simd loops, defer emitting
initializer for the new_var, emit it later on only if not using
SIMD arrays for it.
PR middle-end/59152
* omp-low.c (expand_omp_for_static_chunk): Don't set loop->latch
for the inner loop if collapse_bb is non-NULL.

View File

@ -3185,15 +3185,26 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
}
else if (TREE_CONSTANT (x))
{
const char *name = NULL;
if (DECL_NAME (var))
name = IDENTIFIER_POINTER (DECL_NAME (new_var));
/* 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)
x = NULL_TREE;
else
{
const char *name = NULL;
if (DECL_NAME (var))
name = IDENTIFIER_POINTER (DECL_NAME (new_var));
x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
name);
gimple_add_tmp_var (x);
TREE_ADDRESSABLE (x) = 1;
x = build_fold_addr_expr_loc (clause_loc, x);
x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
name);
gimple_add_tmp_var (x);
TREE_ADDRESSABLE (x) = 1;
x = build_fold_addr_expr_loc (clause_loc, x);
}
}
else
{
@ -3201,8 +3212,11 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
x = build_call_expr_loc (clause_loc, atmp, 1, x);
}
x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
gimplify_assign (new_var, x, ilist);
if (x)
{
x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
gimplify_assign (new_var, x, ilist);
}
new_var = build_simple_mem_ref_loc (clause_loc, new_var);
}
@ -3500,6 +3514,29 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
}
break;
}
/* If this is a reference to constant size reduction var
with placeholder, we haven't emitted the initializer
for it because it is undesirable if SIMD arrays are used.
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);
}
}
x = lang_hooks.decls.omp_clause_default_ctor
(c, new_var, unshare_expr (x));
if (x)

View File

@ -1,5 +1,8 @@
2013-11-26 Jakub Jelinek <jakub@redhat.com>
PR middle-end/59150
* g++.dg/gomp/pr59150.C: New test.
PR middle-end/59152
* c-c++-common/gomp/pr59152.c: New test.

View File

@ -0,0 +1,25 @@
// PR middle-end/59150
// { dg-do compile }
// { dg-options "-O -fopenmp-simd -fno-tree-ccp -fno-tree-copy-prop -fno-tree-dce" }
#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
int
foo ()
{
int i, v, &u = v;
#pragma omp simd reduction (foo:u)
for (i = 0; i < 1024; i++)
u = i;
return u;
}
int
bar ()
{
int i, v, &u = v;
#pragma omp simd reduction (foo:u) safelen(1)
for (i = 0; i < 1024; i++)
u = i;
return u;
}