aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2021-08-27 09:47:49 +0200
committerRichard Biener <rguenther@suse.de>2021-08-27 09:51:26 +0200
commit41439e1f6d2da1e86538c726f0603cffd5dd098e (patch)
tree65fca8bcd2717417c16756e02f9a2270e859da91
parent44a545a6abdd330083c1d12ad70092defbba702a (diff)
downloadgcc-41439e1f6d2da1e86538c726f0603cffd5dd098e.zip
gcc-41439e1f6d2da1e86538c726f0603cffd5dd098e.tar.gz
gcc-41439e1f6d2da1e86538c726f0603cffd5dd098e.tar.bz2
tree-optimization/45178 - DCE of dead control flow in infinite loop
This fixes DCE to be able to elide dead control flow in an infinite loop without an exit edge. This special situation is handled well by the code finding an edge to preserve since there's no chance it will find the exit edge and make the loop finite. 2021-08-27 Richard Biener <rguenther@suse.de> PR tree-optimization/45178 * tree-ssa-dce.c (find_obviously_necessary_stmts): For infinite loops without exit do not mark control dependent edges of the latch necessary. * gcc.dg/tree-ssa/ssa-dce-3.c: Adjust testcase.
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c9
-rw-r--r--gcc/tree-ssa-dce.c14
2 files changed, 14 insertions, 9 deletions
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c
index 863aa79..fdfe37e 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c
@@ -21,11 +21,12 @@ int main(void)
return 0;
}
-/* We now can prove the infiniteness of the loop during CCP and fail
- to eliminate the code inside the infinite loop because we start
- by marking the j % 7 condition as useful. See PR45178. */
+/* We now can prove the infiniteness of the loop during CCP but we
+ still want to eliminate the code inside the infinite loop. See PR45178. */
/* We should eliminate the inner condition, but the loop must be preserved
- as it is infinite. Therefore there should be just one goto and no PHI. */
+ as it is infinite. Therefore there should be just one goto and no PHI
+ and no if. */
/* { dg-final { scan-tree-dump-times "PHI " 0 "cddce1" } } */
+/* { dg-final { scan-tree-dump-times "if " 0 "cddce1" } } */
/* { dg-final { scan-tree-dump-times "goto" 1 "cddce1" } } */
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index 0778eb9..c4907af 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -414,7 +414,9 @@ find_obviously_necessary_stmts (bool aggressive)
if ((flags & (ECF_CONST|ECF_PURE)) && !(flags & ECF_LOOPING_CONST_OR_PURE))
return;
- /* Prevent the empty possibly infinite loops from being removed. */
+ /* Prevent the empty possibly infinite loops from being removed. This is
+ needed to make the logic in remove_dead_stmt work to identify the
+ correct edge to keep when removing a controlling condition. */
if (aggressive)
{
if (mark_irreducible_loops ())
@@ -426,17 +428,19 @@ find_obviously_necessary_stmts (bool aggressive)
&& (e->flags & EDGE_IRREDUCIBLE_LOOP))
{
if (dump_file)
- fprintf (dump_file, "Marking back edge of irreducible loop %i->%i\n",
- e->src->index, e->dest->index);
+ fprintf (dump_file, "Marking back edge of irreducible "
+ "loop %i->%i\n", e->src->index, e->dest->index);
mark_control_dependent_edges_necessary (e->dest, false);
}
}
for (auto loop : loops_list (cfun, 0))
- if (!finite_loop_p (loop))
+ /* For loops without an exit do not mark any condition. */
+ if (loop->exits->next && !finite_loop_p (loop))
{
if (dump_file)
- fprintf (dump_file, "cannot prove finiteness of loop %i\n", loop->num);
+ fprintf (dump_file, "cannot prove finiteness of loop %i\n",
+ loop->num);
mark_control_dependent_edges_necessary (loop->latch, false);
}
}