https://gcc.gnu.org/g:679c67383f05caa624cb3f8c50fa9721624fa1b6
commit r17-3028-g679c67383f05caa624cb3f8c50fa9721624fa1b6 Author: Aldy Hernandez <[email protected]> Date: Wed Aug 5 09:00:50 2026 +0000 Implement the exact nonzero-set test without nonzero_p. The prange storage encoding and the get_legacy_range function use nonzero_p () for its exact meaning: is this range exactly ~[0,0]? Before removing nonzero_p (), test that directly instead of using nonzero_p. Tested on ppc64le Linux. gcc/ChangeLog: * value-range.cc (get_legacy_range): Compare against a set_nonzero prange instead of calling nonzero_p. * value-range-storage.cc (nonzero_range_p): New. (prange_storage::prange_format): Use it instead of nonzero_p. (prange_storage::equal_p): Likewise. Diff: --- gcc/value-range-storage.cc | 21 +++++++++++++++++++-- gcc/value-range.cc | 5 ++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/gcc/value-range-storage.cc b/gcc/value-range-storage.cc index c1b9d8ec2f67..827a5260a19a 100644 --- a/gcc/value-range-storage.cc +++ b/gcc/value-range-storage.cc @@ -646,6 +646,23 @@ prange_storage::prange_storage (const prange &r) : vrange_storage (VR_PRANGE) set_prange (r); } +// Return TRUE if R is exactly the nonzero set [1, MAX], which prange_storage +// encodes compactly as PR_NONZERO. +// +// Compare the bounds against a fresh set_nonzero () rather than using +// prange::operator==, because operator== also compares the bitmask and +// points-to info, which are stored separately here, so a non-null pointer that +// also carries e.g. an alignment bitmask still belongs in PR_NONZERO. + +static inline bool +nonzero_range_p (const prange &r) +{ + prange nonzero (r.type ()); + nonzero.set_nonzero (r.type ()); + return (r.lower_bound () == nonzero.lower_bound () + && r.upper_bound () == nonzero.upper_bound ()); +} + // Return the prange_kind for range R, and the number of words of storage // it requires in NUM_WORDS. @@ -664,7 +681,7 @@ prange_storage::prange_format (const prange &r, unsigned &num_words) enum prange_kind kind = PR_NONZERO; - if (!r.nonzero_p ()) + if (!nonzero_range_p (r)) { prange tmp (r.type ()); if (r.lower_bound () == tmp.lower_bound () @@ -803,7 +820,7 @@ prange_storage::equal_p (const prange &r) const return r.zero_p (); case PR_NONZERO: - if (!r.nonzero_p ()) + if (!nonzero_range_p (r)) return false; break; diff --git a/gcc/value-range.cc b/gcc/value-range.cc index f2dfda148319..d45c3649582b 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -1871,7 +1871,10 @@ get_legacy_range (const prange &r, tree &min, tree &max) min = max = r.lbound (); return VR_RANGE; } - if (r.nonzero_p ()) + prange nonzero (type); + nonzero.set_nonzero (type); + if (r.lower_bound () == nonzero.lower_bound () + && r.upper_bound () == nonzero.upper_bound ()) { min = max = build_zero_cst (type); return VR_ANTI_RANGE;
