From b052d6bbbeea2b04c8a4f765e89b0b3f19f81764 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 26 Jun 2026 16:28:52 +0200 Subject: [PATCH] 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. --- gcc/testsuite/gcc.dg/torture/pr125040.c | 14 +++++++++ gcc/tree-ssa-pre.cc | 38 ++++++++++++++++++------- 2 files changed, 41 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr125040.c diff --git a/gcc/testsuite/gcc.dg/torture/pr125040.c b/gcc/testsuite/gcc.dg/torture/pr125040.c new file mode 100644 index 00000000000..be732084cb0 --- /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 cc182f6fe36..79f1639e143 100644 --- a/gcc/tree-ssa-pre.cc +++ b/gcc/tree-ssa-pre.cc @@ -2171,22 +2171,38 @@ static void clean (bitmap_set_t set1, bitmap_set_t set2 = NULL) { vec 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) -- 2.47.3