aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2025-01-29 13:25:14 +0100
committerRichard Biener <rguenth@gcc.gnu.org>2025-01-30 10:00:14 +0100
commitd1c7837d2d6e5a2997228681166ed8c814891881 (patch)
tree01a0132bf2d71966400486ea5a10af051dd0e447 /gcc
parentf559ac896942ffe0e2315d0a4d8b8b517a16d607 (diff)
downloadgcc-d1c7837d2d6e5a2997228681166ed8c814891881.zip
gcc-d1c7837d2d6e5a2997228681166ed8c814891881.tar.gz
gcc-d1c7837d2d6e5a2997228681166ed8c814891881.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/pr114052-1.c41
-rw-r--r--gcc/tree-ssa-loop-niter.cc9
2 files changed, 49 insertions, 1 deletions
diff --git a/gcc/testsuite/gcc.dg/pr114052-1.c b/gcc/testsuite/gcc.dg/pr114052-1.c
new file mode 100644
index 0000000..98e93bf
--- /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 de8d5ae..7743970 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;