https://gcc.gnu.org/g:728104624f30f8eb9f537a3f91b7bb35e4e3a98c
commit r17-4711-g728104624f30f8eb9f537a3f91b7bb35e4e3a98c Author: Andrew MacLeod <[email protected]> Date: Fri Sep 25 10:19:38 2026 -0400 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. Diff: --- 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 0535b1661d12..f0b20fae327b 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 4401dbf8fafe..19e2e2baf1c1 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));",
