[PATCH 3/4] Implement the exact nonzero-set test without nonzero_p.
Aldy Hernandez <[email protected]> Wed, 5 Aug 2026 16:17:24 +0200
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
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.
---
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 c1b9d8ec2f6..827a5260a19 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 f2dfda14831..d45c3649582 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;
--
2.47.3