[PATCH 1/4] Add contains_zero_p to the vrange hierarchy.
Aldy Hernandez <[email protected]> Wed, 5 Aug 2026 16:17:21 +0200
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
Introduce a contains_zero_p() predicate on vrange and company,
returning whether the range contains zero. It is a clearer
replacement for nonzero_p(), which only holds for the exact ~[0,0]
range.
Tested on ppc64le Linux.
gcc/ChangeLog:
* value-range.h (vrange::contains_zero_p): New pure virtual.
(unsupported_range::contains_zero_p): Declare.
(irange::contains_zero_p): Declare and define.
(prange::contains_zero_p): Declare and define.
(frange::contains_zero_p): Declare.
(Value_Range::contains_zero_p): New.
* value-range.cc (unsupported_range::contains_zero_p): Define.
(frange::contains_zero_p): Define.
---
gcc/value-range.cc | 14 ++++++++++++++
gcc/value-range.h | 26 ++++++++++++++++++++++++++
2 files changed, 40 insertions(+)
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 69d89f34227..f2dfda14831 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -297,6 +297,12 @@ unsupported_range::nonzero_p () const
return false;
}
+bool
+unsupported_range::contains_zero_p () const
+{
+ return varying_p ();
+}
+
void
unsupported_range::set_nonzero (tree type)
{
@@ -1716,6 +1722,14 @@ frange::nonzero_p () const
return tmp == nz;
}
+// Return TRUE if the range contains zero (+0.0 or -0.0).
+
+bool
+frange::contains_zero_p () const
+{
+ return contains_p (dconst0) || contains_p (dconstm0);
+}
+
// Set range to [+0.0, +0.0] if honoring signed zeros, or [0.0, 0.0]
// otherwise.
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 585120dda44..260f822c8ea 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -103,6 +103,7 @@ public:
virtual bool contains_p (tree cst) const = 0;
virtual bool zero_p () const = 0;
virtual bool nonzero_p () const = 0;
+ virtual bool contains_zero_p () const = 0;
virtual void set_nonzero (tree type) = 0;
virtual void set_zero (tree type) = 0;
virtual void set_nonnegative (tree type) = 0;
@@ -315,6 +316,7 @@ public:
// Predicates.
virtual bool zero_p () const override;
virtual bool nonzero_p () const override;
+ virtual bool contains_zero_p () const override;
virtual bool singleton_p (tree *result = NULL) const override;
bool singleton_p (wide_int &) const;
bool contains_p (const wide_int &) const;
@@ -422,6 +424,7 @@ public:
virtual bool singleton_p (tree *result = NULL) const final override;
virtual bool zero_p () const final override;
virtual bool nonzero_p () const final override;
+ virtual bool contains_zero_p () const final override;
virtual void set (tree, tree, value_range_kind = VR_RANGE) final override;
virtual tree type () const final override;
virtual bool union_ (const vrange &v) final override;
@@ -522,6 +525,7 @@ public:
bool contains_p (tree) const final override;
bool zero_p () const final override;
bool nonzero_p () const final override;
+ bool contains_zero_p () const final override;
void set_nonzero (tree type) final override;
void set_zero (tree type) final override;
void set_nonnegative (tree type) final override;
@@ -634,6 +638,7 @@ public:
virtual void accept (const vrange_visitor &v) const override;
virtual bool zero_p () const override;
virtual bool nonzero_p () const override;
+ virtual bool contains_zero_p () const override;
virtual void set_nonzero (tree type) override;
virtual void set_zero (tree type) override;
virtual void set_nonnegative (tree type) override;
@@ -886,6 +891,7 @@ public:
void set_nonzero (tree type)
{ init (type); return m_vrange->set_nonzero (type); }
bool nonzero_p () const { return m_vrange->nonzero_p (); }
+ bool contains_zero_p () const { return m_vrange->contains_zero_p (); }
bool zero_p () const { return m_vrange->zero_p (); }
tree lbound () const { return m_vrange->lbound (); }
tree ubound () const { return m_vrange->ubound (); }
@@ -1137,6 +1143,16 @@ irange::nonzero_p () const
return *this == int_range<2> (type (), zero, zero, VR_ANTI_RANGE);
}
+inline bool
+irange::contains_zero_p () const
+{
+ if (undefined_p ())
+ return false;
+
+ wide_int zero = wi::zero (TYPE_PRECISION (type ()));
+ return contains_p (zero);
+}
+
inline bool
irange::supports_p (const_tree type)
{
@@ -1470,6 +1486,16 @@ prange::nonzero_p () const
return m_kind == VR_RANGE && m_min == 1 && m_max == -1;
}
+inline bool
+prange::contains_zero_p () const
+{
+ if (undefined_p ())
+ return false;
+
+ wide_int zero = wi::zero (TYPE_PRECISION (type ()));
+ return contains_p (zero);
+}
+
inline tree
prange::type () const
{
--
2.47.3