https://gcc.gnu.org/g:33e4cfbd9495a23ffe4639c217442a5459b9e400
commit r17-1816-g33e4cfbd9495a23ffe4639c217442a5459b9e400 Author: Andrew MacLeod <[email protected]> Date: Tue Jun 23 16:11:16 2026 -0400 prange zero_p() should never have points to. Intersection sometimes produced a [0, 0] range with a points to field. PR tree-optimization/125910 gcc/ * value-range.cc (prange::set_pt): Do not set PT when zero. (prange::intersect): If the result is zero_p, clear PT. (prange::verify_range): Verify points-to range is valid. * value-range.h (zero_p): Do not assert, move to verify range. (prange::set_pt): Only set PT when the range valid. gcc/testsuite/ * gcc.dg/pr125910.c: New. Diff: --- gcc/testsuite/gcc.dg/pr125910.c | 15 +++++++++++++++ gcc/value-range.cc | 14 ++++++++++++++ gcc/value-range.h | 6 ++++-- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/gcc/testsuite/gcc.dg/pr125910.c b/gcc/testsuite/gcc.dg/pr125910.c new file mode 100644 index 000000000000..88ec139f9795 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr125910.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-delete-null-pointer-checks" } */ + +void a(); +extern int b; +int *c; +void d() { + int *e = c; + if (e) + a(); + if (e == &b) + a(); + if (e) + a(); +} diff --git a/gcc/value-range.cc b/gcc/value-range.cc index 86eb2f507fb7..722eca9abca7 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -539,6 +539,10 @@ prange::set_pt (tree expr, bool points_to_p) m_pt = NULL_TREE; m_points_to_p = false; + // A zero range means no points-to info. + if (zero_p ()) + return; + // No points to initially may make this VARYING. if (varying_compatible_p ()) set_varying (type ()); @@ -825,6 +829,10 @@ prange::intersect (const vrange &v) set_pt (r); } + // If this evolves to zero, clear all points-to info. + if (zero_p () && !pt_unknown_p ()) + set_pt_unknown (); + if (varying_compatible_p ()) { set_varying (type ()); @@ -931,6 +939,12 @@ prange::verify_range () const } gcc_checking_assert (!varying_compatible_p ()); gcc_checking_assert (m_kind == VR_RANGE); + if (!pt_unknown_p ()) + { + gcc_checking_assert (!varying_p ()); + gcc_checking_assert (!undefined_p ()); + gcc_checking_assert (!zero_p ()); + } } void diff --git a/gcc/value-range.h b/gcc/value-range.h index d5588faefb41..e6dc59eb7066 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -1429,8 +1429,6 @@ inline bool prange::zero_p () const { bool ret = m_kind == VR_RANGE && m_min == 0 && m_max == 0; - // if zero_p is true, there should be no points to info. - gcc_checking_assert (!ret || pt_unknown_p ()); return ret; } @@ -1486,6 +1484,10 @@ prange::fits_p (const vrange &) const inline void prange::set_pt (const prange &r) { + // Do not set points-to info if this is zero or undefined. + if (!r.pt_unknown_p () && (undefined_p () || zero_p())) + return; + m_pt = r.m_pt; m_points_to_p = r.m_points_to_p;
