re PR middle-end/66429 (ICE in expand_GOMP_SIMD_LAST_LANE)

PR middle-end/66429
	* omp-low.c (expand_omp_taskreg): Use child_cfun instead of
	DECL_STRUCT_FUNCTION (child_fn).  Or in has_simduid_loops
	and has_force_vectorize_loops flags from cfun into
	child_cfun.
	(expand_omp_simd): For broken loop, set cfun->has_simduid_loops
	if simduid is non-NULL.
	* tree-pass.h (make_pass_simduid_cleanup): New prototype.
	* passes.def (pass_simduid_cleanup): Add new pass after loop
	passes.
	* tree-vectorizer.c (adjust_simduid_builtins): Remove one unnecessary
	indirection from htab argument's type.
	(shrink_simd_arrays): New function.
	(vectorize_loops): Use it.  Adjust adjust_simduid_builtins caller.
	Don't call adjust_simduid_builtins if there are no loops.
	(pass_data_simduid_cleanup, pass_simduid_cleanup): New variables.
	(pass_simduid_cleanup::execute): New method.
	(make_pass_simduid_cleanup): New function.

	* c-c++-common/gomp/pr66429.c: New test.

From-SVN: r224568
This commit is contained in:
Jakub Jelinek 2015-06-17 19:59:25 +02:00 committed by Jakub Jelinek
parent f6e3667f97
commit 8c8b9f3265
7 changed files with 176 additions and 38 deletions

View File

@ -1,3 +1,24 @@
2015-06-17 Jakub Jelinek <jakub@redhat.com>
PR middle-end/66429
* omp-low.c (expand_omp_taskreg): Use child_cfun instead of
DECL_STRUCT_FUNCTION (child_fn). Or in has_simduid_loops
and has_force_vectorize_loops flags from cfun into
child_cfun.
(expand_omp_simd): For broken loop, set cfun->has_simduid_loops
if simduid is non-NULL.
* tree-pass.h (make_pass_simduid_cleanup): New prototype.
* passes.def (pass_simduid_cleanup): Add new pass after loop
passes.
* tree-vectorizer.c (adjust_simduid_builtins): Remove one unnecessary
indirection from htab argument's type.
(shrink_simd_arrays): New function.
(vectorize_loops): Use it. Adjust adjust_simduid_builtins caller.
Don't call adjust_simduid_builtins if there are no loops.
(pass_data_simduid_cleanup, pass_simduid_cleanup): New variables.
(pass_simduid_cleanup::execute): New method.
(make_pass_simduid_cleanup): New function.
2017-06-17 Andrew MacLeod <amacleod@redhat.com>
* tree-core.h (tree_target_option): Make opts field a pointer to a

View File

@ -5587,7 +5587,9 @@ expand_omp_taskreg (struct omp_region *region)
vec_safe_truncate (child_cfun->local_decls, dstidx);
/* Inform the callgraph about the new function. */
DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
child_cfun->curr_properties = cfun->curr_properties;
child_cfun->has_simduid_loops |= cfun->has_simduid_loops;
child_cfun->has_force_vectorize_loops |= cfun->has_force_vectorize_loops;
cgraph_node *node = cgraph_node::get_create (child_fn);
node->parallelized_function = 1;
cgraph_node::add_new_function (child_fn, true);
@ -7836,6 +7838,8 @@ expand_omp_simd (struct omp_region *region, struct omp_for_data *fd)
cfun->has_force_vectorize_loops = true;
}
}
else if (simduid)
cfun->has_simduid_loops = true;
}

View File

@ -270,6 +270,7 @@ along with GCC; see the file COPYING3. If not see
PUSH_INSERT_PASSES_WITHIN (pass_tree_no_loop)
NEXT_PASS (pass_slp_vectorize);
POP_INSERT_PASSES ()
NEXT_PASS (pass_simduid_cleanup);
NEXT_PASS (pass_lower_vector_ssa);
NEXT_PASS (pass_cse_reciprocals);
NEXT_PASS (pass_reassoc);

View File

@ -1,3 +1,8 @@
2015-06-17 Jakub Jelinek <jakub@redhat.com>
PR middle-end/66429
* c-c++-common/gomp/pr66429.c: New test.
2015-06-17 David Malcolm <dmalcolm@redhat.com>
* jit.dg/test-error-accessing-field-in-other-struct.c: Rename to...

View File

@ -0,0 +1,41 @@
/* PR middle-end/66429 */
/* { dg-do compile } */
/* { dg-options "-O2 -fopenmp" } */
float b[10][15][10];
__attribute__ ((noreturn)) void
noreturn (void)
{
for (;;);
}
__attribute__ ((noinline, noclone)) void
foo (int n)
{
int i;
#pragma omp parallel for simd schedule(static, 32) collapse(3)
for (i = 0; i < 10; i++)
for (int j = n; j < 8; j++)
for (long k = -10; k < 10; k++)
{
b[i][j][k] += 16;
noreturn ();
b[i][j][k] -= 32;
}
}
__attribute__ ((noinline, noclone)) void
bar (void)
{
int i;
#pragma omp parallel for simd schedule(static, 32)
for (i = 0; i < 10; i++)
{
b[0][0][i] += 16;
noreturn ();
b[0][0][i] -= 32;
}
}

View File

@ -372,6 +372,7 @@ extern gimple_opt_pass *make_pass_graphite_transforms (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_if_conversion (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_loop_distribution (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_vectorize (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_simduid_cleanup (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_slp_vectorize (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_complete_unroll (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_complete_unrolli (gcc::context *ctxt);

View File

@ -168,7 +168,7 @@ simd_array_to_simduid::equal (const simd_array_to_simduid *p1,
into their corresponding constants. */
static void
adjust_simduid_builtins (hash_table<simduid_to_vf> **htab)
adjust_simduid_builtins (hash_table<simduid_to_vf> *htab)
{
basic_block bb;
@ -200,10 +200,12 @@ adjust_simduid_builtins (hash_table<simduid_to_vf> **htab)
gcc_assert (TREE_CODE (arg) == SSA_NAME);
simduid_to_vf *p = NULL, data;
data.simduid = DECL_UID (SSA_NAME_VAR (arg));
if (*htab)
p = (*htab)->find (&data);
if (p)
vf = p->vf;
if (htab)
{
p = htab->find (&data);
if (p)
vf = p->vf;
}
switch (ifn)
{
case IFN_GOMP_SIMD_VF:
@ -306,6 +308,38 @@ note_simd_array_uses (hash_table<simd_array_to_simduid> **htab)
walk_gimple_op (use_stmt, note_simd_array_uses_cb, &wi);
}
}
/* Shrink arrays with "omp simd array" attribute to the corresponding
vectorization factor. */
static void
shrink_simd_arrays
(hash_table<simd_array_to_simduid> *simd_array_to_simduid_htab,
hash_table<simduid_to_vf> *simduid_to_vf_htab)
{
for (hash_table<simd_array_to_simduid>::iterator iter
= simd_array_to_simduid_htab->begin ();
iter != simd_array_to_simduid_htab->end (); ++iter)
if ((*iter)->simduid != -1U)
{
tree decl = (*iter)->decl;
int vf = 1;
if (simduid_to_vf_htab)
{
simduid_to_vf *p = NULL, data;
data.simduid = (*iter)->simduid;
p = simduid_to_vf_htab->find (&data);
if (p)
vf = p->vf;
}
tree atype
= build_array_type_nelts (TREE_TYPE (TREE_TYPE (decl)), vf);
TREE_TYPE (decl) = atype;
relayout_decl (decl);
}
delete simd_array_to_simduid_htab;
}
/* A helper function to free data refs. */
@ -442,11 +476,7 @@ vectorize_loops (void)
/* Bail out if there are no loops. */
if (vect_loops_num <= 1)
{
if (cfun->has_simduid_loops)
adjust_simduid_builtins (&simduid_to_vf_htab);
return 0;
}
return 0;
if (cfun->has_simduid_loops)
note_simd_array_uses (&simd_array_to_simduid_htab);
@ -555,37 +585,14 @@ vectorize_loops (void)
/* Fold IFN_GOMP_SIMD_{VF,LANE,LAST_LANE} builtins. */
if (cfun->has_simduid_loops)
adjust_simduid_builtins (&simduid_to_vf_htab);
adjust_simduid_builtins (simduid_to_vf_htab);
/* Shrink any "omp array simd" temporary arrays to the
actual vectorization factors. */
if (simd_array_to_simduid_htab)
{
for (hash_table<simd_array_to_simduid>::iterator iter
= simd_array_to_simduid_htab->begin ();
iter != simd_array_to_simduid_htab->end (); ++iter)
if ((*iter)->simduid != -1U)
{
tree decl = (*iter)->decl;
int vf = 1;
if (simduid_to_vf_htab)
{
simduid_to_vf *p = NULL, data;
data.simduid = (*iter)->simduid;
p = simduid_to_vf_htab->find (&data);
if (p)
vf = p->vf;
}
tree atype
= build_array_type_nelts (TREE_TYPE (TREE_TYPE (decl)), vf);
TREE_TYPE (decl) = atype;
relayout_decl (decl);
}
delete simd_array_to_simduid_htab;
}
delete simduid_to_vf_htab;
simduid_to_vf_htab = NULL;
shrink_simd_arrays (simd_array_to_simduid_htab, simduid_to_vf_htab);
delete simduid_to_vf_htab;
cfun->has_simduid_loops = false;
if (num_vectorized_loops > 0)
{
@ -600,6 +607,64 @@ vectorize_loops (void)
}
/* Entry point to the simduid cleanup pass. */
namespace {
const pass_data pass_data_simduid_cleanup =
{
GIMPLE_PASS, /* type */
"simduid", /* name */
OPTGROUP_NONE, /* optinfo_flags */
TV_NONE, /* tv_id */
( PROP_ssa | PROP_cfg ), /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
0, /* todo_flags_finish */
};
class pass_simduid_cleanup : public gimple_opt_pass
{
public:
pass_simduid_cleanup (gcc::context *ctxt)
: gimple_opt_pass (pass_data_simduid_cleanup, ctxt)
{}
/* opt_pass methods: */
opt_pass * clone () { return new pass_simduid_cleanup (m_ctxt); }
virtual bool gate (function *fun) { return fun->has_simduid_loops; }
virtual unsigned int execute (function *);
}; // class pass_simduid_cleanup
unsigned int
pass_simduid_cleanup::execute (function *fun)
{
hash_table<simd_array_to_simduid> *simd_array_to_simduid_htab = NULL;
note_simd_array_uses (&simd_array_to_simduid_htab);
/* Fold IFN_GOMP_SIMD_{VF,LANE,LAST_LANE} builtins. */
adjust_simduid_builtins (NULL);
/* Shrink any "omp array simd" temporary arrays to the
actual vectorization factors. */
if (simd_array_to_simduid_htab)
shrink_simd_arrays (simd_array_to_simduid_htab, NULL);
fun->has_simduid_loops = false;
return 0;
}
} // anon namespace
gimple_opt_pass *
make_pass_simduid_cleanup (gcc::context *ctxt)
{
return new pass_simduid_cleanup (ctxt);
}
/* Entry point to basic block SLP phase. */
namespace {