aboutsummaryrefslogtreecommitdiff
path: root/gcc/value-range.h
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2023-03-08 10:58:01 +0100
committerAldy Hernandez <aldyh@redhat.com>2023-03-22 10:07:13 +0100
commit81295d445ec569c6413fd6f7921e27420167f8fa (patch)
treef84f266d86af5f3873a0a64325d832750efcc75a /gcc/value-range.h
parent5e812e8c1e8d65aee05cc3fbbe5727d4e365df57 (diff)
downloadgcc-81295d445ec569c6413fd6f7921e27420167f8fa.zip
gcc-81295d445ec569c6413fd6f7921e27420167f8fa.tar.gz
gcc-81295d445ec569c6413fd6f7921e27420167f8fa.tar.bz2
frange: Implement nan_state class [PR109008]
This patch implements a nan_state class, that allows us to query or pass around the NANness of an frange. We can store +NAN, -NAN, +-NAN, or not-a-NAN with it. I tried to touch as little as possible, leaving other cleanups to the next release. For example, we should replace the m_*_nan fields in frange with nan_state, and provide relevant accessors to nan_state (isnan, etc). PR tree-optimization/109008 gcc/ChangeLog: * value-range.cc (frange::set): Add nan_state argument. * value-range.h (class nan_state): New. (frange::get_nan_state): New.
Diffstat (limited to 'gcc/value-range.h')
-rw-r--r--gcc/value-range.h62
1 files changed, 62 insertions, 0 deletions
diff --git a/gcc/value-range.h b/gcc/value-range.h
index f4ac73b..ec50346 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -268,6 +268,56 @@ public:
virtual void accept (const vrange_visitor &v) const override;
};
+// The NAN state as an opaque object. The default constructor is +-NAN.
+
+class nan_state
+{
+public:
+ nan_state ();
+ nan_state (bool pos_nan, bool neg_nan);
+ bool neg_p () const;
+ bool pos_p () const;
+private:
+ bool m_pos_nan;
+ bool m_neg_nan;
+};
+
+// Default constructor initializing the object to +-NAN.
+
+inline
+nan_state::nan_state ()
+{
+ m_pos_nan = true;
+ m_neg_nan = true;
+}
+
+// Constructor initializing the object to +NAN if POS_NAN is set, -NAN
+// if NEG_NAN is set, or +-NAN if both are set. Otherwise POS_NAN and
+// NEG_NAN are clear, and the object cannot be a NAN.
+
+inline
+nan_state::nan_state (bool pos_nan, bool neg_nan)
+{
+ m_pos_nan = pos_nan;
+ m_neg_nan = neg_nan;
+}
+
+// Return if +NAN is possible.
+
+inline bool
+nan_state::pos_p () const
+{
+ return m_pos_nan;
+}
+
+// Return if -NAN is possible.
+
+inline bool
+nan_state::neg_p () const
+{
+ return m_neg_nan;
+}
+
// A floating point range.
//
// The representation is a type with a couple of endpoints, unioned
@@ -295,6 +345,8 @@ public:
virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
value_range_kind = VR_RANGE);
+ void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
+ const nan_state &, value_range_kind = VR_RANGE);
void set_nan (tree type);
void set_nan (tree type, bool sign);
virtual void set_varying (tree type) override;
@@ -315,9 +367,11 @@ public:
bool operator!= (const frange &r) const { return !(*this == r); }
const REAL_VALUE_TYPE &lower_bound () const;
const REAL_VALUE_TYPE &upper_bound () const;
+ nan_state get_nan_state () const;
void update_nan ();
void update_nan (bool sign);
void update_nan (tree) = delete; // Disallow silent conversion to bool.
+ void update_nan (const nan_state &);
void clear_nan ();
// fpclassify like API
@@ -358,6 +412,14 @@ frange::upper_bound () const
return m_max;
}
+// Return the NAN state.
+
+inline nan_state
+frange::get_nan_state () const
+{
+ return nan_state (m_pos_nan, m_neg_nan);
+}
+
// is_a<> and as_a<> implementation for vrange.
// Anything we haven't specialized is a hard fail.