tree-optimization/125040 - iterate PRE clean The testcase has a cycle in the value graph of ANTIC_IN, this means we have to iterate to correctly prune all invalid expressions. PR tree-optimization/125040 * tree-ssa-pre.cc (clean): Iterate processing. * gcc.dg/torture/pr125040.c: New testcase.
diff --git a/gcc/testsuite/gcc.dg/torture/pr125040.c b/gcc/testsuite/gcc.dg/torture/pr125040.c new file mode 100644 index 0000000..be73208 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr125040.c
@@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +int a() { + int b; + int *c = __builtin_calloc(sizeof(int), b); + int count; + for (int d; d;) + for (int e;; b++) { + c[e] = c[b - count - 1]; + c[b - count - 1] = count; + count = count + 1; + } + __builtin_printf("", c); +}
diff --git a/gcc/tree-ssa-pre.cc b/gcc/tree-ssa-pre.cc index cc182f6..79f1639 100644 --- a/gcc/tree-ssa-pre.cc +++ b/gcc/tree-ssa-pre.cc
@@ -2171,22 +2171,38 @@ clean (bitmap_set_t set1, bitmap_set_t set2 = NULL) { vec<pre_expr> exprs = sorted_array_from_bitmap_set (set1, false); - pre_expr expr; - int i; + bool changed; - FOR_EACH_VEC_ELT (exprs, i, expr) + do { - if (!valid_in_sets (set1, set2, expr)) + unsigned j = 0; + changed = false; + for (unsigned i = 0; i < exprs.length (); ++i) { - unsigned int val = get_expr_value_id (expr); - bitmap_clear_bit (&set1->expressions, get_expression_id (expr)); - /* We are entered with possibly multiple expressions for a value - so before removing a value from the set see if there's an - expression for it left. */ - if (! bitmap_find_leader (set1, val)) - bitmap_clear_bit (&set1->values, val); + pre_expr expr = exprs[i]; + if (!valid_in_sets (set1, set2, expr)) + { + unsigned int val = get_expr_value_id (expr); + bitmap_clear_bit (&set1->expressions, get_expression_id (expr)); + /* We are entered with possibly multiple expressions for a value + so before removing a value from the set see if there's an + expression for it left. */ + if (! bitmap_find_leader (set1, val)) + { + bitmap_clear_bit (&set1->values, val); + changed = true; + } + } + else + { + exprs[j] = expr; + ++j; + } } + exprs.truncate (j); } + /* As the value graph can have cycles we have to iterate here. */ + while (changed); exprs.release (); if (flag_checking)