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

commit r15-7283-gd1c7837d2d6e5a2997228681166ed8c814891881
Author: Richard Biener <rguent...@suse.de>
Date:   Wed Jan 29 13:25:14 2025 +0100

    tree-optimization/114052 - consider infinite sub-loops when lowering iter 
bound
    
    When we walk stmts to find always executed stmts with UB in the last
    iteration to be able to reduce the iteration count by one we fail
    to consider infinite subloops in the last iteration that would make
    such stmt not execute.  The following adds this.
    
            PR tree-optimization/114052
            * tree-ssa-loop-niter.cc (maybe_lower_iteration_bound): Check
            for infinite subloops we might not exit.
    
            * gcc.dg/pr114052-1.c: New testcase.

Diff:
---
 gcc/testsuite/gcc.dg/pr114052-1.c | 41 +++++++++++++++++++++++++++++++++++++++
 gcc/tree-ssa-loop-niter.cc        |  9 ++++++++-
 2 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/pr114052-1.c 
b/gcc/testsuite/gcc.dg/pr114052-1.c
new file mode 100644
index 000000000000..98e93bf670da
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr114052-1.c
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+/* { dg-require-effective-target signal } */
+/* { dg-require-effective-target alarm } */
+/* { dg-options "-O2" } */
+
+#include <stdint.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdlib.h>
+
+volatile int y;
+void __attribute__((noipa)) put(int x)
+{
+  if (y)
+    __builtin_printf ("%i\n", x);
+}
+
+void __attribute__((noipa)) f(void)
+{
+  int counter = 0;
+  while (1) {
+      if (counter >= 2) continue;
+      put (counter++);
+  }
+}
+
+void do_exit (int i)
+{
+  exit (0);
+}
+
+int main()
+{
+  struct sigaction s;
+  sigemptyset (&s.sa_mask);
+  s.sa_handler = do_exit;
+  s.sa_flags = 0;
+  sigaction (SIGALRM, &s, NULL);
+  alarm (1);
+  f();
+}
diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc
index de8d5ae62335..7743970bf3d5 100644
--- a/gcc/tree-ssa-loop-niter.cc
+++ b/gcc/tree-ssa-loop-niter.cc
@@ -4757,7 +4757,14 @@ maybe_lower_iteration_bound (class loop *loop)
           FOR_EACH_EDGE (e, ei, bb->succs)
            {
              if (loop_exit_edge_p (loop, e)
-                 || e == loop_latch_edge (loop))
+                 || e == loop_latch_edge (loop)
+                 /* When exiting an inner loop, verify it is finite.  */
+                 || (!flow_bb_inside_loop_p (bb->loop_father, e->dest)
+                     && !finite_loop_p (bb->loop_father))
+                 /* When we enter an irreducible region and the entry
+                    does not contain a bounding stmt assume it might be
+                    infinite.  */
+                 || (bb->flags & BB_IRREDUCIBLE_LOOP))
                {
                  found_exit = true;
                  break;

Reply via email to