re PR tree-optimization/91568 (internal compiler error: in vect_schedule_slp_instance...
authorRichard Biener <rguenther@suse.de>
Thu, 29 Aug 2019 08:07:35 +0000 (08:07 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 29 Aug 2019 08:07:35 +0000 (08:07 +0000)
2019-08-29  Richard Biener  <rguenther@suse.de>

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
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/pr91568.f [new file with mode: 0644]
gcc/tree-vect-slp.c
gcc/tree-vectorizer.h

index c4a7b30..49ab435 100644 (file)
@@ -1,3 +1,13 @@
+2019-08-29  Richard Biener  <rguenther@suse.de>
+
+       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  <polacek@redhat.com>
 
        Implement P1152R4: Deprecating some uses of volatile.
index 3a503ac..3a4f36e 100644 (file)
@@ -1,3 +1,8 @@
+2019-08-29  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/91568
+       * gfortran.dg/pr91568.f: New testcase.
+
 2019-08-28  Marek Polacek  <polacek@redhat.com>
 
        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 (file)
index 0000000..4ada559
--- /dev/null
@@ -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
index 52f2a06..9b86b67 100644 (file)
@@ -129,6 +129,7 @@ vect_create_new_slp_node (vec<stmt_vec_info> 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 ())
index 1456cde..05ad1c6 100644 (file)
@@ -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