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;

Reply via email to