[gcc r15-1583] tree-optimization/115602 - SLP CSE results in cycles

Richard Biener rguenth@gcc.gnu.org
Mon Jun 24 11:45:40 GMT 2024


https://gcc.gnu.org/g:c43c74f6ec795a586388de7abfdd20a0040f6f16

commit r15-1583-gc43c74f6ec795a586388de7abfdd20a0040f6f16
Author: Richard Biener <rguenther@suse.de>
Date:   Mon Jun 24 09:52:39 2024 +0200

    tree-optimization/115602 - SLP CSE results in cycles
    
    The following prevents SLP CSE to create new cycles which happened
    because of a 1:1 permute node being present where its child was then
    CSEd to the permute node.  Fixed by making a node only available to
    CSE to after recursing.
    
            PR tree-optimization/115602
            * tree-vect-slp.cc (vect_cse_slp_nodes): Delay populating the
            bst-map to avoid cycles.
    
            * gcc.dg/vect/pr115602.c: New testcase.

Diff:
---
 gcc/testsuite/gcc.dg/vect/pr115602.c | 27 +++++++++++++++++++++++++++
 gcc/tree-vect-slp.cc                 | 33 +++++++++++++++++++++------------
 2 files changed, 48 insertions(+), 12 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/vect/pr115602.c b/gcc/testsuite/gcc.dg/vect/pr115602.c
new file mode 100644
index 00000000000..9a208d1d950
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr115602.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+
+typedef struct {
+  double x, y;
+} pointf;
+struct {
+  pointf focus;
+  double zoom;
+  pointf devscale;
+  char button;
+  pointf oldpointer;
+} gvevent_motion_job;
+char gvevent_motion_job_4;
+double gvevent_motion_pointer_1, gvevent_motion_pointer_0;
+void gvevent_motion() {
+  double dx = (gvevent_motion_pointer_0 - gvevent_motion_job.oldpointer.x) /
+              gvevent_motion_job.devscale.x,
+         dy = (gvevent_motion_pointer_1 - gvevent_motion_job.oldpointer.y) /
+              gvevent_motion_job.devscale.y;
+  if (dx && dy < .0001)
+    return;
+  switch (gvevent_motion_job_4)
+  case 2: {
+    gvevent_motion_job.focus.x -= dy / gvevent_motion_job.zoom;
+    gvevent_motion_job.focus.y += dx / gvevent_motion_job.zoom;
+  }
+}
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index e84aeabef94..b47b7e8c979 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -6079,35 +6079,44 @@ vect_optimize_slp_pass::run ()
 static void
 vect_cse_slp_nodes (scalar_stmts_to_slp_tree_map_t *bst_map, slp_tree& node)
 {
+  bool put_p = false;
   if (SLP_TREE_DEF_TYPE (node) == vect_internal_def
       /* Besides some VEC_PERM_EXPR, two-operator nodes also
 	 lack scalar stmts and thus CSE doesn't work via bst_map.  Ideally
 	 we'd have sth that works for all internal and external nodes.  */
       && !SLP_TREE_SCALAR_STMTS (node).is_empty ())
     {
-      if (slp_tree *leader = bst_map->get (SLP_TREE_SCALAR_STMTS (node)))
+      slp_tree *leader = bst_map->get (SLP_TREE_SCALAR_STMTS (node));
+      if (leader)
 	{
-	  if (*leader != node)
-	    {
-	      if (dump_enabled_p ())
-		dump_printf_loc (MSG_NOTE, vect_location,
-				 "re-using SLP tree %p for %p\n",
-				 (void *)*leader, (void *)node);
-	      vect_free_slp_tree (node);
-	      (*leader)->refcnt += 1;
-	      node = *leader;
-	    }
+	  /* We've visited this node already.  */
+	  if (!*leader || *leader == node)
+	    return;
+
+	  if (dump_enabled_p ())
+	    dump_printf_loc (MSG_NOTE, vect_location,
+			     "re-using SLP tree %p for %p\n",
+			     (void *)*leader, (void *)node);
+	  vect_free_slp_tree (node);
+	  (*leader)->refcnt += 1;
+	  node = *leader;
 	  return;
 	}
 
-      bst_map->put (SLP_TREE_SCALAR_STMTS (node).copy (), node);
+      /* Avoid creating a cycle by populating the map only after recursion.  */
+      bst_map->put (SLP_TREE_SCALAR_STMTS (node).copy (), nullptr);
       node->refcnt += 1;
+      put_p = true;
       /* And recurse.  */
     }
 
   for (slp_tree &child : SLP_TREE_CHILDREN (node))
     if (child)
       vect_cse_slp_nodes (bst_map, child);
+
+  /* Now record the node for CSE in other siblings.  */
+  if (put_p)
+    bst_map->put (SLP_TREE_SCALAR_STMTS (node).copy (), node);
 }
 
 /* Optimize the SLP graph of VINFO.  */


More information about the Gcc-cvs mailing list