[gcc r17-3026] Add contains_zero_p to the vrange hierarchy.
Aldy Hernandez via Gcc-cvs <[email protected]> Thu, 6 Aug 2026 10:56:32 +0000 (GMT)
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:9231e36eeff6ec576e99f4c7c4b30e9fced44cd1 commit r17-3026-g9231e36eeff6ec576e99f4c7c4b30e9fced44cd1 Author: Aldy Hernandez <[email protected]> Date: Wed Aug 5 08:39:43 2026 +0000 Add contains_zero_p to the vrange hierarchy. 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. Diff: --- gcc/value-range.cc | 14 ++++++++++++++ gcc/value-range.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/gcc/value-range.cc b/gcc/value-range.cc index 69d89f342272..f2dfda148319 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 585120dda44c..1d138ab1828c 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -103,6 +103,9 @@ public: virtual bool contains_p (tree cst) const = 0; virtual bool zero_p () const = 0; virtual bool nonzero_p () const = 0; + // True if val == 0 may hold for some value in the range; for a float + // range that means +0.0 or -0.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 +318,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 +426,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 +527,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 +640,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 +893,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 +1145,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 +1488,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 {