tree-optimization/97558 - avoid SLP analyzing irrelevant stmts
authorRichard Biener <rguenther@suse.de>
Mon, 2 Nov 2020 08:38:09 +0000 (09:38 +0100)
committerRichard Biener <rguenther@suse.de>
Mon, 2 Nov 2020 10:03:30 +0000 (11:03 +0100)
This avoids analyzing reductions that are not relevant (thus dead)
which eventually will lead into crashes because the participating
stmts meta is not analyzed.  For this to work the patch also
properly removes reduction groups that are not uniformly recognized
as patterns.

2020-11-02  Richard Biener  <rguenther@suse.de>

PR tree-optimization/97558
* tree-vect-loop.c (vect_fixup_scalar_cycles_with_patterns):
Check for any mismatch in pattern vs. non-pattern and dissolve
the group if there is one.
* tree-vect-slp.c (vect_analyze_slp_instance): Avoid
analyzing not relevant reductions.
(vect_analyze_slp): Avoid analyzing not relevant reduction
groups.

* gcc.dg/vect/pr97558.c: New testcase.

gcc/testsuite/gcc.dg/vect/pr97558.c [new file with mode: 0644]
gcc/tree-vect-loop.c
gcc/tree-vect-slp.c

diff --git a/gcc/testsuite/gcc.dg/vect/pr97558.c b/gcc/testsuite/gcc.dg/vect/pr97558.c
new file mode 100644 (file)
index 0000000..fef9623
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fno-tree-dce -Ofast" } */
+
+long int x1;
+int fr;
+
+int
+us (int sk, int jx)
+{
+  while (sk < 1)
+    {
+      jx *= 2;
+      fr += x1 + 1;
+      ++sk;
+    }
+
+  return jx;
+}
index 5ab125d15c6db9b360833a79a51eca0e1c00195f..353703cccbfd828c805b438af658eab1ac14f8d4 100644 (file)
@@ -666,27 +666,50 @@ vect_fixup_scalar_cycles_with_patterns (loop_vec_info loop_vinfo)
   unsigned i;
 
   FOR_EACH_VEC_ELT (LOOP_VINFO_REDUCTION_CHAINS (loop_vinfo), i, first)
-    if (STMT_VINFO_IN_PATTERN_P (first))
-      {
-       stmt_vec_info next = REDUC_GROUP_NEXT_ELEMENT (first);
-       while (next)
-         {
-           if (! STMT_VINFO_IN_PATTERN_P (next)
-               || STMT_VINFO_REDUC_IDX (STMT_VINFO_RELATED_STMT (next)) == -1)
-             break;
-           next = REDUC_GROUP_NEXT_ELEMENT (next);
-         }
-       /* If not all stmt in the chain are patterns or if we failed
-          to update STMT_VINFO_REDUC_IDX try to handle the chain
-          without patterns.  */
-       if (! next
-           && STMT_VINFO_REDUC_IDX (STMT_VINFO_RELATED_STMT (first)) != -1)
-         {
-           vect_fixup_reduc_chain (first);
-           LOOP_VINFO_REDUCTION_CHAINS (loop_vinfo)[i]
-             = STMT_VINFO_RELATED_STMT (first);
-         }
-      }
+    {
+      stmt_vec_info next = REDUC_GROUP_NEXT_ELEMENT (first);
+      while (next)
+       {
+         if ((STMT_VINFO_IN_PATTERN_P (next)
+              != STMT_VINFO_IN_PATTERN_P (first))
+             || STMT_VINFO_REDUC_IDX (vect_stmt_to_vectorize (next)) == -1)
+           break;
+         next = REDUC_GROUP_NEXT_ELEMENT (next);
+       }
+      /* If all reduction chain members are well-formed patterns adjust
+        the group to group the pattern stmts instead.  */
+      if (! next
+         && STMT_VINFO_REDUC_IDX (vect_stmt_to_vectorize (first)) != -1)
+       {
+         if (STMT_VINFO_IN_PATTERN_P (first))
+           {
+             vect_fixup_reduc_chain (first);
+             LOOP_VINFO_REDUCTION_CHAINS (loop_vinfo)[i]
+               = STMT_VINFO_RELATED_STMT (first);
+           }
+       }
+      /* If not all stmt in the chain are patterns or if we failed
+        to update STMT_VINFO_REDUC_IDX dissolve the chain and handle
+        it as regular reduction instead.  */
+      else
+       {
+         stmt_vec_info vinfo = first;
+         stmt_vec_info last = NULL;
+         while (vinfo)
+           {
+             next = REDUC_GROUP_NEXT_ELEMENT (vinfo);
+             REDUC_GROUP_FIRST_ELEMENT (vinfo) = NULL;
+             REDUC_GROUP_NEXT_ELEMENT (vinfo) = NULL;
+             last = vinfo;
+             vinfo = next;
+           }
+         STMT_VINFO_DEF_TYPE (vect_stmt_to_vectorize (first))
+           = vect_internal_def;
+         loop_vinfo->reductions.safe_push (vect_stmt_to_vectorize (last));
+         LOOP_VINFO_REDUCTION_CHAINS (loop_vinfo).unordered_remove (i);
+         --i;
+       }
+    }
 }
 
 /* Function vect_get_loop_niters.
index d5249196d5eee44427ee3913d2e27137da504cbc..45e33c031d2882cfe23e42acd7fbcfb6d704b928 100644 (file)
@@ -2592,7 +2592,9 @@ vect_analyze_slp_instance (vec_info *vinfo,
       /* Collect reduction statements.  */
       vec<stmt_vec_info> reductions = as_a <loop_vec_info> (vinfo)->reductions;
       for (i = 0; reductions.iterate (i, &next_info); i++)
-       scalar_stmts.safe_push (next_info);
+       if (STMT_VINFO_RELEVANT_P (next_info)
+           || STMT_VINFO_LIVE_P (next_info))
+         scalar_stmts.quick_push (next_info);
     }
 
   /* Build the tree for the SLP instance.  */
@@ -2628,29 +2630,29 @@ vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size)
 
   if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
     {
-      if (loop_vinfo->reduction_chains.length () > 0)
-       {
-         /* Find SLP sequences starting from reduction chains.  */
-         FOR_EACH_VEC_ELT (loop_vinfo->reduction_chains, i, first_element)
-           if (! vect_analyze_slp_instance (vinfo, bst_map, first_element,
-                                            max_tree_size))
+      /* Find SLP sequences starting from reduction chains.  */
+      FOR_EACH_VEC_ELT (loop_vinfo->reduction_chains, i, first_element)
+       if (! STMT_VINFO_RELEVANT_P (first_element)
+           && ! STMT_VINFO_LIVE_P (first_element))
+         ;
+       else if (! vect_analyze_slp_instance (vinfo, bst_map, first_element,
+                                             max_tree_size))
+         {
+           /* Dissolve reduction chain group.  */
+           stmt_vec_info vinfo = first_element;
+           stmt_vec_info last = NULL;
+           while (vinfo)
              {
-               /* Dissolve reduction chain group.  */
-               stmt_vec_info vinfo = first_element;
-               stmt_vec_info last = NULL;
-               while (vinfo)
-                 {
-                   stmt_vec_info next = REDUC_GROUP_NEXT_ELEMENT (vinfo);
-                   REDUC_GROUP_FIRST_ELEMENT (vinfo) = NULL;
-                   REDUC_GROUP_NEXT_ELEMENT (vinfo) = NULL;
-                   last = vinfo;
-                   vinfo = next;
-                 }
-               STMT_VINFO_DEF_TYPE (first_element) = vect_internal_def;
-               /* It can be still vectorized as part of an SLP reduction.  */
-               loop_vinfo->reductions.safe_push (last);
+               stmt_vec_info next = REDUC_GROUP_NEXT_ELEMENT (vinfo);
+               REDUC_GROUP_FIRST_ELEMENT (vinfo) = NULL;
+               REDUC_GROUP_NEXT_ELEMENT (vinfo) = NULL;
+               last = vinfo;
+               vinfo = next;
              }
-       }
+           STMT_VINFO_DEF_TYPE (first_element) = vect_internal_def;
+           /* It can be still vectorized as part of an SLP reduction.  */
+           loop_vinfo->reductions.safe_push (last);
+         }
 
       /* Find SLP sequences starting from groups of reductions.  */
       if (loop_vinfo->reductions.length () > 1)