From f48e4da3259d52076f86aa081cece40dfda7b235 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 29 Aug 2019 08:07:35 +0000 Subject: [PATCH] re PR tree-optimization/91568 (internal compiler error: in vect_schedule_slp_instance, at tree-vect-slp.c:3922) 2019-08-29 Richard Biener PR tree-optimization/91568 * tree-vectorizer.h (_slp_tree::max_nunits): Add. (vect_update_max_nunits): Add overload for poly_uint64. * tree-vect-slp.c (vect_create_new_slp_node): Initialize it. (vect_build_slp_tree): Record max_nunits into the subtree and merge it upwards. (vect_print_slp_tree): Print max_nunits. * gfortran.dg/pr91568.f: New testcase. From-SVN: r275023 --- gcc/ChangeLog | 10 ++++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/pr91568.f | 11 +++++++++++ gcc/tree-vect-slp.c | 20 +++++++++++++++----- gcc/tree-vectorizer.h | 19 +++++++++++++++---- 5 files changed, 56 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr91568.f diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c4a7b30ead8..49ab435387b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2019-08-29 Richard Biener + + PR tree-optimization/91568 + * tree-vectorizer.h (_slp_tree::max_nunits): Add. + (vect_update_max_nunits): Add overload for poly_uint64. + * tree-vect-slp.c (vect_create_new_slp_node): Initialize it. + (vect_build_slp_tree): Record max_nunits into the subtree + and merge it upwards. + (vect_print_slp_tree): Print max_nunits. + 2019-08-28 Marek Polacek Implement P1152R4: Deprecating some uses of volatile. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3a503ac8b3d..3a4f36e167c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-29 Richard Biener + + PR tree-optimization/91568 + * gfortran.dg/pr91568.f: New testcase. + 2019-08-28 Marek Polacek Implement P1152R4: Deprecating some uses of volatile. diff --git a/gcc/testsuite/gfortran.dg/pr91568.f b/gcc/testsuite/gfortran.dg/pr91568.f new file mode 100644 index 00000000000..4ada559d692 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr91568.f @@ -0,0 +1,11 @@ +! { dg-do compile } +! { dg-options "-Ofast" } + subroutine h3dall(z,hvec,hder,nterms) + complex *16 hvec(0:1),hder(0:1) + complex *16 z,zinv,ztmp/1.0/ + zinv=1.0/z + do i=1,nterms + ztmp=zinv*i + hder(i)=hvec(i-1)-ztmp*hvec(i) + enddo + end diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 52f2a06e3b8..9b86b67734a 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -129,6 +129,7 @@ vect_create_new_slp_node (vec scalar_stmts) SLP_TREE_TWO_OPERATORS (node) = false; SLP_TREE_DEF_TYPE (node) = vect_internal_def; node->refcnt = 1; + node->max_nunits = 1; unsigned i; FOR_EACH_VEC_ELT (scalar_stmts, i, stmt_info) @@ -1067,14 +1068,22 @@ vect_build_slp_tree (vec_info *vinfo, dump_printf_loc (MSG_NOTE, vect_location, "re-using %sSLP tree %p\n", *leader ? "" : "failed ", *leader); if (*leader) - (*leader)->refcnt++; + { + (*leader)->refcnt++; + vect_update_max_nunits (max_nunits, (*leader)->max_nunits); + } return *leader; } + poly_uint64 this_max_nunits = 1; slp_tree res = vect_build_slp_tree_2 (vinfo, stmts, group_size, max_nunits, matches, npermutes, tree_size, bst_map); - /* Keep a reference for the bst_map use. */ if (res) - res->refcnt++; + { + res->max_nunits = this_max_nunits; + vect_update_max_nunits (max_nunits, this_max_nunits); + /* Keep a reference for the bst_map use. */ + res->refcnt++; + } bst_map->put (stmts.copy (), res); return res; } @@ -1473,9 +1482,10 @@ vect_print_slp_tree (dump_flags_t dump_kind, dump_location_t loc, dump_metadata_t metadata (dump_kind, loc.get_impl_location ()); dump_user_location_t user_loc = loc.get_user_location (); - dump_printf_loc (metadata, user_loc, "node%s %p\n", + dump_printf_loc (metadata, user_loc, "node%s %p (max_nunits=%u)\n", SLP_TREE_DEF_TYPE (node) != vect_internal_def - ? " (external)" : "", node); + ? " (external)" : "", node, + estimated_poly_value (node->max_nunits)); FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt_info) dump_printf_loc (metadata, user_loc, "\tstmt %d %G", i, stmt_info->stmt); if (SLP_TREE_CHILDREN (node).is_empty ()) diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 1456cde4c2c..05ad1c6862b 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -132,6 +132,9 @@ struct _slp_tree { unsigned int vec_stmts_size; /* Reference count in the SLP graph. */ unsigned int refcnt; + /* The maximum number of vector elements for the subtree rooted + at this node. */ + poly_uint64 max_nunits; /* Whether the scalar computations use two different operators. */ bool two_operators; /* The DEF type of this node. */ @@ -1375,19 +1378,27 @@ vect_get_num_copies (loop_vec_info loop_vinfo, tree vectype) } /* Update maximum unit count *MAX_NUNITS so that it accounts for - the number of units in vector type VECTYPE. *MAX_NUNITS can be 1 - if we haven't yet recorded any vector types. */ + NUNITS. *MAX_NUNITS can be 1 if we haven't yet recorded anything. */ static inline void -vect_update_max_nunits (poly_uint64 *max_nunits, tree vectype) +vect_update_max_nunits (poly_uint64 *max_nunits, poly_uint64 nunits) { /* All unit counts have the form current_vector_size * X for some rational X, so two unit sizes must have a common multiple. Everything is a multiple of the initial value of 1. */ - poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype); *max_nunits = force_common_multiple (*max_nunits, nunits); } +/* Update maximum unit count *MAX_NUNITS so that it accounts for + the number of units in vector type VECTYPE. *MAX_NUNITS can be 1 + if we haven't yet recorded any vector types. */ + +static inline void +vect_update_max_nunits (poly_uint64 *max_nunits, tree vectype) +{ + vect_update_max_nunits (max_nunits, TYPE_VECTOR_SUBPARTS (vectype)); +} + /* Return the vectorization factor that should be used for costing purposes while vectorizing the loop described by LOOP_VINFO. Pick a reasonable estimate if the vectorization factor isn't -- 2.30.2