https://gcc.gnu.org/g:b632956cd4154b3102a36675e0ee7375c9d8bb81
commit r17-1710-gb632956cd4154b3102a36675e0ee7375c9d8bb81 Author: Andrew Pinski <[email protected]> Date: Thu Jun 18 14:16:04 2026 -0700 ipa: Don't record return value ranges for pranges with non ipa-invariant [PR125857] Now that pranges can have invariants in it, we need to make sure the return value range does not record non-ipa invariants; otherwise we might prop the address of a local variable from one function to another. Bootstrapped and tested on x86_64-linux-gnu. PR tree-optimization/125857 gcc/ChangeLog: * ipa-prop.cc (ipa_record_return_value_range_1): Don't record pranges which have non ipa-invariants in it. gcc/testsuite/ChangeLog: * gcc.dg/pr125857-1.c: New test. Signed-off-by: Andrew Pinski <[email protected]> Diff: --- gcc/ipa-prop.cc | 17 +++++++++++++++++ gcc/testsuite/gcc.dg/pr125857-1.c | 16 ++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc index 79b59a6a76f9..3e05f659f305 100644 --- a/gcc/ipa-prop.cc +++ b/gcc/ipa-prop.cc @@ -5986,6 +5986,23 @@ ipa_prop_write_jump_functions (void) static void ipa_record_return_value_range_1 (cgraph_node *n, value_range val) { + // Remove local invariant from return values. + if (is_a<prange> (val)) + { + const prange &pr = as_a <prange> (val); + tree t = pr.pt_invariant (); + if (t && !is_gimple_ip_invariant (t)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Could not record return range of %s:", n->dump_name ()); + val.dump (dump_file); + fprintf (dump_file, "\n"); + fprintf (dump_file, "Because uses non ipa invariant\n"); + } + return; + } + } if (!ipa_return_value_sum) { if (!ipa_vr_hash_table) diff --git a/gcc/testsuite/gcc.dg/pr125857-1.c b/gcc/testsuite/gcc.dg/pr125857-1.c new file mode 100644 index 000000000000..1904db7e3193 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr125857-1.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* PR tree-optimization/125857 */ + +/* Make sure we don't ICE when returning the address to a local variable + and using it in the other function. */ +int *a, **b = &a, c; +int *d() { + int e, *f = &e; + for (; c; c++) + __builtin_abort(); + if (!b) + __builtin_abort(); + return f; /* { dg-warning "function may return address of local variable" } */ +} +int main() { *b = d(); }
