Skip to content

Commit 715a1df

Browse files
committed
tree-optimization/114787 - more careful loop update with CFG cleanup
When CFG cleanup removes a backedge we have to be more careful with loop update. In particular we need to clear niter info and estimates and if we remove the last backedge of a loop we have to also mark it for removal to prevent a following basic block merging to associate loop info with an unrelated header. PR tree-optimization/114787 * tree-cfg.cc (remove_edge_and_dominated_blocks): When removing a loop backedge clear niter info and when removing the last backedge of a loop mark that loop for removal. * gcc.dg/torture/pr114787.c: New testcase. (cherry picked from commit cc48418)
1 parent 4c3011e commit 715a1df

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/* { dg-do run } */
2+
3+
int a, b, c, d, e = -1, f, g, h, j, k, n, o, p;
4+
int main() {
5+
int i, l = 2, m;
6+
for (b = 0; b < 1; b++)
7+
l = 0;
8+
for (; a >= 0; a--)
9+
for (m = 3; m; m--) {
10+
k = g;
11+
i = 0;
12+
for (; i < 1; i++)
13+
for (; f < 1; f++)
14+
h = g;
15+
n = 2 & ((e ^ d) | 1) * j;
16+
o = ~(e & n);
17+
q:
18+
if (c <= e)
19+
return 0;
20+
e = o;
21+
}
22+
p = l;
23+
l = 0;
24+
if (p)
25+
goto q;
26+
return 0;
27+
}

gcc/tree-cfg.cc

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8872,10 +8872,30 @@ remove_edge_and_dominated_blocks (edge e)
88728872

88738873
/* If we are removing a path inside a non-root loop that may change
88748874
loop ownership of blocks or remove loops. Mark loops for fixup. */
8875+
class loop *src_loop = e->src->loop_father;
88758876
if (current_loops
8876-
&& loop_outer (e->src->loop_father) != NULL
8877-
&& e->src->loop_father == e->dest->loop_father)
8878-
loops_state_set (LOOPS_NEED_FIXUP);
8877+
&& loop_outer (src_loop) != NULL
8878+
&& src_loop == e->dest->loop_father)
8879+
{
8880+
loops_state_set (LOOPS_NEED_FIXUP);
8881+
/* If we are removing a backedge clear the number of iterations
8882+
and estimates. */
8883+
class loop *dest_loop = e->dest->loop_father;
8884+
if (e->dest == src_loop->header
8885+
|| (e->dest == dest_loop->header
8886+
&& flow_loop_nested_p (dest_loop, src_loop)))
8887+
{
8888+
free_numbers_of_iterations_estimates (dest_loop);
8889+
/* If we removed the last backedge mark the loop for removal. */
8890+
FOR_EACH_EDGE (f, ei, dest_loop->header->preds)
8891+
if (f != e
8892+
&& (f->src->loop_father == dest_loop
8893+
|| flow_loop_nested_p (dest_loop, f->src->loop_father)))
8894+
break;
8895+
if (!f)
8896+
mark_loop_for_removal (dest_loop);
8897+
}
8898+
}
88798899

88808900
if (!dom_info_available_p (CDI_DOMINATORS))
88818901
{

0 commit comments

Comments
 (0)