aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2025-10-01 14:16:50 +0200
committerRichard Biener <rguenth@gcc.gnu.org>2025-10-02 09:12:10 +0200
commit0e91910c0708a60b3ac521a4ea74e44301109f4a (patch)
tree497a050ea8cf64c529ba645f3a911a2cb6b82d2e
parent6051a849aa1e8ed444ee71161d90fd800469121d (diff)
downloadgcc-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.c27
-rw-r--r--gcc/tree-ssa-pre.cc8
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)