[gcc r14-7101] middle-end: Fix dominators updates when peeling with multiple exits [PR113144]

Tamar Christina tnfchris@gcc.gnu.org
Wed Jan 10 12:54:38 GMT 2024


https://gcc.gnu.org/g:9e7c77c7933b1bb0dd07214333e52a9a896fa349

commit r14-7101-g9e7c77c7933b1bb0dd07214333e52a9a896fa349
Author: Tamar Christina <tamar.christina@arm.com>
Date:   Wed Jan 10 12:51:54 2024 +0000

    middle-end: Fix dominators updates when peeling with multiple exits [PR113144]
    
    When we peel at_exit we are moving the new loop at the exit of the previous
    loop.  This means that the blocks outside the loop dat the previous loop used to
    dominate are no longer being dominated by it.
    
    The new dominators however are hard to predict since if the loop has multiple
    exits and all the exits are an "early" one then we always execute the scalar
    loop.  In this case the scalar loop can completely dominate the new loop.
    
    If we later have skip_vector then there's an additional skip edge added that
    might change the dominators.
    
    The previous patch would force an update of all blocks reachable from the new
    exits.  This one updates *only* blocks that we know the scalar exits dominated.
    
    For the examples this reduces the blocks to update from 18 to 3.
    
    gcc/ChangeLog:
    
            PR tree-optimization/113144
            PR tree-optimization/113145
            * tree-vect-loop-manip.cc (slpeel_tree_duplicate_loop_to_edge_cfg):
            Update all BB that the original exits dominated.
    
    gcc/testsuite/ChangeLog:
    
            PR tree-optimization/113144
            PR tree-optimization/113145
            * gcc.dg/vect/vect-early-break_94-pr113144.c: New test.

Diff:
---
 .../gcc.dg/vect/vect-early-break_94-pr113144.c     | 41 ++++++++++++++++++++++
 gcc/tree-vect-loop-manip.cc                        | 13 +++----
 2 files changed, 45 insertions(+), 9 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_94-pr113144.c b/gcc/testsuite/gcc.dg/vect/vect-early-break_94-pr113144.c
new file mode 100644
index 00000000000..903fe7be662
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_94-pr113144.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+
+long tar_atol256_max, tar_atol256_size, tar_atosl_min;
+char tar_atol256_s;
+void __errno_location();
+
+
+inline static long tar_atol256(long min) {
+  char c;
+  int sign;
+  c = tar_atol256_s;
+  sign = c;
+  while (tar_atol256_size) {
+    if (c != sign)
+      return sign ? min : tar_atol256_max;
+    c = tar_atol256_size--;
+  }
+  if ((c & 128) != (sign & 128))
+    return sign ? min : tar_atol256_max;
+  return 0;
+}
+
+inline static long tar_atol(long min) {
+  return tar_atol256(min);
+}
+
+long tar_atosl() {
+  long n = tar_atol(-1);
+  if (tar_atosl_min) {
+    __errno_location();
+    return 0;
+  }
+  if (n > 0)
+    return 0;
+  return n;
+}
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index f0ea7fc069b..8aa7575a0e3 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -1716,8 +1716,6 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit,
 	  /* Now link the alternative exits.  */
 	  if (multiple_exits_p)
 	    {
-	      set_immediate_dominator (CDI_DOMINATORS, new_preheader,
-				       main_loop_exit_block);
 	      for (auto gsi_from = gsi_start_phis (loop->header),
 		   gsi_to = gsi_start_phis (new_preheader);
 		   !gsi_end_p (gsi_from) && !gsi_end_p (gsi_to);
@@ -1755,13 +1753,10 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit,
       if (multiple_exits_p)
 	{
 	  update_loop = new_loop;
-	  for (edge e : get_loop_exit_edges (loop))
-	    doms.safe_push (e->dest);
-	  doms.safe_push (exit_dest);
-
-	  /* Likely a fall-through edge, so update if needed.  */
-	  if (single_succ_p (exit_dest))
-	    doms.safe_push (single_succ (exit_dest));
+	  doms = get_all_dominated_blocks (CDI_DOMINATORS, loop->header);
+	  for (unsigned i = 0; i < doms.length (); ++i)
+	    if (flow_bb_inside_loop_p (loop, doms[i]))
+	      doms.unordered_remove (i);
 	}
     }
   else /* Add the copy at entry.  */


More information about the Gcc-cvs mailing list