From: Jakub Jelinek Date: Wed, 17 Jun 2015 17:59:25 +0000 (+0200) Subject: re PR middle-end/66429 (ICE in expand_GOMP_SIMD_LAST_LANE) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8c8b9f3265820507a1a9472fee7384b265692380;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 868a70808a4..8f92fecf5af 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2015-06-17 Jakub Jelinek + + 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 * tree-core.h (tree_target_option): Make opts field a pointer to a diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 64b5c66e933..6325b826010 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -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; } diff --git a/gcc/passes.def b/gcc/passes.def index 4690e23afb2..9ced6558000 100644 --- a/gcc/passes.def +++ b/gcc/passes.def @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bc86c88e1e0..10c61ef2cf6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-06-17 Jakub Jelinek + + PR middle-end/66429 + * c-c++-common/gomp/pr66429.c: New test. + 2015-06-17 David Malcolm * jit.dg/test-error-accessing-field-in-other-struct.c: Rename to... diff --git a/gcc/testsuite/c-c++-common/gomp/pr66429.c b/gcc/testsuite/c-c++-common/gomp/pr66429.c new file mode 100644 index 00000000000..01c795fef40 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr66429.c @@ -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; + } +} diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 172bd821902..454555653db 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -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); diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c index ff46a52fc82..9d178026a2f 100644 --- a/gcc/tree-vectorizer.c +++ b/gcc/tree-vectorizer.c @@ -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 **htab) +adjust_simduid_builtins (hash_table *htab) { basic_block bb; @@ -200,10 +200,12 @@ adjust_simduid_builtins (hash_table **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 **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_htab, + hash_table *simduid_to_vf_htab) +{ + for (hash_table::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::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_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 {