Whej working on 127203, i discovered the fix for 126531 that was checked
in not only was causing this slowdown, but it also wasn't actually
fixing the problem! doh!
THe testcase was not being run with optimization, and when it was.. it
failed.
So, after the new fix for 127203 is committed, the new fix for this PR
is much simpler.
If there is an abnormal outgoing edge in a block, we are not supposed to
apply any inferred ranges from the final statement as being exported
from the block. The existing code had the logic incorrect. It was
adding ranges if there was at least 1 normal edge rather than not adding
them if there was at least one abnormal edge.
Bootstrapped on x86_64-pc-linux-gnu with no regressions. Pushed.
Andrew
From fc0e4b83377acc8ddda2075bf3f0aa050f22323d Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <[email protected]>
Date: Fri, 25 Sep 2026 10:19:38 -0400
Subject: [PATCH 2/2] Correct inferred range application.
If there is an abnormal outgoing edge in a block, we are not supposed to apply
any inferred ranges from the final statement as being exported from the block.
The existing code had the logic incorrect. It was adding ranges if there was
at least 1 normal edge rather than not adding them if there was at least
one abnormal edge.
The existing testcase was also flawed in that it was missing the flag to
test with optimization, which caused it to pass when it should not have.
Assisted-by: Claude Opus 5
PR tree-optimization/126531
gcc/
* gimple-range-cache.cc (ranger_cache::apply_inferred_ranges): Do not
update if there are abnormal edges.
gcc/testsuite/
* g++.dg/pr126531.C: Add optimization flag.
---
gcc/gimple-range-cache.cc | 13 ++++++++-----
gcc/testsuite/g++.dg/pr126531.C | 1 +
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc
index 0535b1661d1..f0b20fae327 100644
--- a/gcc/gimple-range-cache.cc
+++ b/gcc/gimple-range-cache.cc
@@ -1947,16 +1947,19 @@ ranger_cache::apply_inferred_ranges (gimple *s)
if (infer.num () == 0)
return;
- // Do not update the on-entry cache for block ending stmts.
+ // Do not update the on-entry cache for block ending stmts if there is
+ // an outgoing abnormal edge. Any outgoing abnormal edge makes the
+ // value unsafe to use.
if (stmt_ends_bb_p (s))
{
edge_iterator ei;
edge e;
FOR_EACH_EDGE (e, ei, gimple_bb (s)->succs)
- if (!(e->flags & (EDGE_ABNORMAL|EDGE_EH)))
- break;
- if (e == NULL)
- update = false;
+ if (e->flags & (EDGE_ABNORMAL|EDGE_EH))
+ {
+ update = false;
+ break;
+ }
}
infer_oracle ().add_ranges (s, infer);
diff --git a/gcc/testsuite/g++.dg/pr126531.C b/gcc/testsuite/g++.dg/pr126531.C
index 4401dbf8faf..19e2e2baf1c 100644
--- a/gcc/testsuite/g++.dg/pr126531.C
+++ b/gcc/testsuite/g++.dg/pr126531.C
@@ -1,4 +1,5 @@
// { dg-do run }
+// { dg-options "-O2" }
//
/* More than 16 bytes, so S is returned in memory. *p becomes the return slot
of the call and GIMPLE keeps a single statement "*p_7(D) = h (k_8(D));",
--
2.55.0