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

commit r16-3542-gdf64893e7082d7fae5d6863fd02371b37c78557f
Author: Richard Biener <rguent...@suse.de>
Date:   Wed Sep 3 10:41:17 2025 +0200

    tree-optimization/121756 - handle irreducible regions when sinking
    
    The sinking code currently does not heuristically avoid placing
    code into an irreducible region in the same way it avoids placing
    into a deeper loop nest.  Critically for the PR we may not insert
    a VDEF into a irreducible region that does not contain a virtual
    definition.  The following adds the missing heuristic and also
    a stop-gap for the VDEF issue - since we cannot determine
    validity inside an irreducible region we have to reject any
    VDEF movement with destination inside such region, even when
    it originates there.  In particular irreducible sub-cycles are
    not tracked separately and can cause issues.
    
    I chose to not complicate the already partly incomplete assert
    but prune it down to essentials.
    
            PR tree-optimization/121756
            * tree-ssa-sink.cc (select_best_block): Avoid irreducible
            regions in otherwise same loop depth.
            (statement_sink_location): When sinking a VDEF, never place
            that into an irreducible region.
    
            * gcc.dg/torture/pr121756.c: New testcase.

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr121756.c | 30 ++++++++++++++++++++++++++++++
 gcc/tree-ssa-sink.cc                    | 17 +++++++++++------
 2 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/torture/pr121756.c 
b/gcc/testsuite/gcc.dg/torture/pr121756.c
new file mode 100644
index 000000000000..37c5c50e47ec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr121756.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+
+int a, b, *c = &b;
+static void g(int i) {
+  int d = 0, e, f[] = {a}, j = a;
+  e = b;
+  if (e - i)
+    return;
+  a = 0;
+h:
+  if (e) {
+    e = j;
+    if (f[3])
+      goto k;
+    goto h;
+  }
+  while (1) {    d = -1;
+    while (1) {
+      if (d - 1 - j < 0)
+        return;
+    k:
+      if (f[1])
+        break;
+    }
+  }
+}
+int main() {
+  g(1);
+  return 0;
+}
diff --git a/gcc/tree-ssa-sink.cc b/gcc/tree-ssa-sink.cc
index 2244e89fbb7f..60dfe5282a72 100644
--- a/gcc/tree-ssa-sink.cc
+++ b/gcc/tree-ssa-sink.cc
@@ -245,6 +245,12 @@ select_best_block (basic_block early_bb,
       else if (bb_loop_depth (temp_bb) > bb_loop_depth (best_bb))
        ;
 
+      /* Likewise an irreducible region inside an otherwise same loop
+        depth.  */
+      else if ((temp_bb->flags & BB_IRREDUCIBLE_LOOP)
+              && !(best_bb->flags & BB_IRREDUCIBLE_LOOP))
+       ;
+
       /* But sink the least distance, if the new candidate on the same
         loop depth is post-dominated by the current best block pick
         the new candidate.  */
@@ -265,11 +271,7 @@ select_best_block (basic_block early_bb,
     }
 
   gcc_checking_assert (best_bb == early_bb
-                      || (!do_not_sink (stmt, early_bb, best_bb)
-                          && ((bb_loop_depth (best_bb)
-                               < bb_loop_depth (early_bb))
-                              || !dominated_by_p (CDI_POST_DOMINATORS,
-                                                  early_bb, best_bb))));
+                      || !do_not_sink (stmt, early_bb, best_bb));
 
   return best_bb;
 }
@@ -500,7 +502,10 @@ statement_sink_location (gimple *stmt, basic_block frombb,
         operand update, requiring inserting of a PHI node.  */
       || (gimple_vdef (stmt)
          && bestbb != sinkbb
-         && !dominated_by_p (CDI_POST_DOMINATORS, bestbb, sinkbb)))
+         && !dominated_by_p (CDI_POST_DOMINATORS, bestbb, sinkbb))
+      /* Likewise avoid placing VDEFs into an irreducible region.  */
+      || (gimple_vdef (stmt)
+         && (bestbb->flags & BB_IRREDUCIBLE_LOOP)))
     return false;
 
   *togsi = gsi_after_labels (bestbb);

Reply via email to