https://gcc.gnu.org/g:1990e6544b9f0db39c470b999c32d2ecdd419f46

commit r13-10355-g1990e6544b9f0db39c470b999c32d2ecdd419f46
Author: Richard Biener <[email protected]>
Date:   Wed Sep 13 11:04:31 2023 +0200

    tree-optimization/111387 - BB SLP and irreducible regions
    
    When we split an irreducible region for BB vectorization analysis
    the defensive handling of external backedge defs in
    vect_get_and_check_slp_defs doesn't work since that relies on
    dominance info to identify a backedge.  The testcase also shows
    we are iterating over the function in a sub-optimal way which is
    why we split the irreducible region in the first place.  The fix
    is to mark backedges and use EDGE_DFS_BACK to identify them.
    
            PR tree-optimization/111387
            * tree-vect-slp.cc (vect_get_and_check_slp_defs): Check
            EDGE_DFS_BACK when doing BB vectorization.
            (vect_slp_function): Mark backedges.
    
            * gcc.dg/torture/pr111387.c: New testcase.

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr111387.c | 34 +++++++++++++++++++++++++++++++++
 gcc/tree-vect-slp.cc                    | 11 ++++++++---
 2 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/torture/pr111387.c 
b/gcc/testsuite/gcc.dg/torture/pr111387.c
new file mode 100644
index 000000000000..e14eeef6e4ad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr111387.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-ftree-vectorize -fno-vect-cost-model" } */
+
+struct {
+  unsigned a;
+  unsigned b;
+} c;
+int d, e, f, g, h;
+int main()
+{
+  if (c.b && g && g > 7)
+    goto i;
+ j:
+  if (c.a) {
+    int k = 0;
+    unsigned l = c.b;
+    if (0) {
+    m:
+      k = l = c.b;
+    }
+    c.a = k;
+    c.b = l;
+  }
+  if (0) {
+  i:
+    goto m;
+  }
+  if (d)
+    goto j;
+  for (f = 5; f; f--)
+    if (h)
+      e = 0;
+  return 0;
+}
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index d5b114dbcc9c..19050c2c164a 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -594,9 +594,13 @@ vect_get_and_check_slp_defs (vec_info *vinfo, unsigned 
char swap,
        {
          oprnd = gimple_arg (stmt_info->stmt, opno);
          if (gphi *stmt = dyn_cast <gphi *> (stmt_info->stmt))
-           backedge = dominated_by_p (CDI_DOMINATORS,
-                                      gimple_phi_arg_edge (stmt, opno)->src,
-                                      gimple_bb (stmt_info->stmt));
+           {
+             edge e = gimple_phi_arg_edge (stmt, opno);
+             backedge = (is_a <bb_vec_info> (vinfo)
+                         ? e->flags & EDGE_DFS_BACK
+                         : dominated_by_p (CDI_DOMINATORS, e->src,
+                                           gimple_bb (stmt_info->stmt)));
+           }
        }
       if (TREE_CODE (oprnd) == VIEW_CONVERT_EXPR)
        oprnd = TREE_OPERAND (oprnd, 0);
@@ -7678,6 +7682,7 @@ vect_slp_function (function *fun)
   bool r = false;
   int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fun));
   unsigned n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, false);
+  mark_dfs_back_edges (fun);
 
   /* For the moment split the function into pieces to avoid making
      the iteration on the vector mode moot.  Split at points we know

Reply via email to