diff options
author | Richard Biener <rguenther@suse.de> | 2025-10-01 14:16:50 +0200 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2025-10-02 09:12:10 +0200 |
commit | 0e91910c0708a60b3ac521a4ea74e44301109f4a (patch) | |
tree | 497a050ea8cf64c529ba645f3a911a2cb6b82d2e | |
parent | 6051a849aa1e8ed444ee71161d90fd800469121d (diff) | |
download | gcc-0e91910c0708a60b3ac521a4ea74e44301109f4a.zip gcc-0e91910c0708a60b3ac521a4ea74e44301109f4a.tar.gz gcc-0e91910c0708a60b3ac521a4ea74e44301109f4a.tar.bz2 |
tree-optimization/122079 - PRE antic_compute doesn't converge
The following fixes another case of us pruning from the value set
based on the expression set after expression removal when the
maximum expression set is involved.
PR tree-optimization/122079
* tree-ssa-pre.cc (prune_clobbered_mems): Do not prune
values when the maximum expression set is involved.
* gcc.dg/torture/pr122079-1.c: New testcase.
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr122079-1.c | 27 | ||||
-rw-r--r-- | gcc/tree-ssa-pre.cc | 8 |
2 files changed, 33 insertions, 2 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr122079-1.c b/gcc/testsuite/gcc.dg/torture/pr122079-1.c new file mode 100644 index 0000000..0af01a5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr122079-1.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-fcode-hoisting" } */ + +int a, b, c; +void e(int *f) { + int d = 0; + if (f) + goto g; + goto h; +i: + d = 1 + f[0]; +j: + if (c) + goto h; +k: + if (b) + goto i; + if (a) + goto j; +g: + if (d + f[0]) + goto k; +h: + int l[] = {f[0]}; + if (a) + e(l); +} diff --git a/gcc/tree-ssa-pre.cc b/gcc/tree-ssa-pre.cc index 64ffaca..d08caab 100644 --- a/gcc/tree-ssa-pre.cc +++ b/gcc/tree-ssa-pre.cc @@ -2049,8 +2049,12 @@ prune_clobbered_mems (bitmap_set_t set, basic_block block, bool clean_traps) the bitmap_find_leader way to see if there's still an expression for it. For some ratio of to be removed values and number of values/expressions in the set this might be faster than rebuilding - the value-set. */ - if (any_removed) + the value-set. + Note when there's a MAX solution on one edge (clean_traps) do not + prune values as we need to consider the resulting expression set MAX + as well. This avoids a later growing ANTIC_IN value-set during + iteration, when the explicitly represented expression set grows. */ + if (any_removed && !clean_traps) { bitmap_clear (&set->values); FOR_EACH_EXPR_ID_IN_SET (set, i, bi) |