public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-2668] Provide cleaner set_nan(), clear_nan(), and update_nan() methods.
@ 2022-09-14 15:07 Aldy Hernandez
0 siblings, 0 replies; only message in thread
From: Aldy Hernandez @ 2022-09-14 15:07 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:9c4c4186eb7ca0a62fc590edcbb3f8fc9a081e64
commit r13-2668-g9c4c4186eb7ca0a62fc590edcbb3f8fc9a081e64
Author: Aldy Hernandez <aldyh@redhat.com>
Date: Wed Sep 14 06:58:35 2022 +0200
Provide cleaner set_nan(), clear_nan(), and update_nan() methods.
set_* has a very specific meaning for irange's and friends. Methods
prefixed with set_* are setters clobbering the existing range. As
such, the current set_nan() method is confusing in that it's not
actually setting a range to a NAN, but twiddling the NAN flags for an
existing frange.
This patch replaces set_nan() with an update_nan() to set the flag,
and clear_nan() to clear it. This makes the code clearer, and though
the confusing tristate is still there, it will be removed in upcoming
patches.
Also, there is now an actual set_nan() method to set the range to a
NAN. This replaces two out of class functions doing the same thing.
In future patches I will also add the ability to create a NAN with a
specific sign, but doing so now would be confusing because we're not
tracking NAN signs.
We should also submit set_signbit to the same fate, but it's about to
get removed.
No functional changes.
Regstrapped on x86-64 Linux, plus I ran selftests for
-ffinite-math-only.
gcc/ChangeLog:
* range-op-float.cc (frange_set_nan): Remove.
(build_lt): Use set_nan, update_nan, clear_nan.
(build_gt): Same.
(foperator_equal::op1_range): Same.
(foperator_not_equal::op1_range): Same.
(foperator_lt::op1_range): Same.
(foperator_lt::op2_range): Same.
(foperator_le::op1_range): Same.
(foperator_le::op2_range): Same.
(foperator_gt::op1_range): Same.
(foperator_gt::op2_range): Same.
(foperator_ge::op1_range): Same.
(foperator_ge::op2_range): Same.
(foperator_unordered::op1_range): Same.
(foperator_ordered::op1_range): Same.
* value-query.cc (range_query::get_tree_range): Same.
* value-range.cc (frange::set_nan): Same.
(frange::update_nan): Same.
(frange::union_): Same.
(frange::intersect): Same.
(range_tests_nan): Same.
(range_tests_signed_zeros): Same.
(range_tests_signbit): Same.
(range_tests_floats): Same.
* value-range.h (class frange): Add update_nan and clear_nan.
(frange::set_nan): New.
Diff:
---
gcc/range-op-float.cc | 46 +++++++++++++++++----------------------------
gcc/value-query.cc | 4 ++--
gcc/value-range.cc | 52 +++++++++++++++++++++++++--------------------------
gcc/value-range.h | 11 ++++++-----
4 files changed, 51 insertions(+), 62 deletions(-)
diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index 0f928b6c098..f979ca597cb 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -150,18 +150,6 @@ range_operator_float::op1_op2_relation (const irange &lhs ATTRIBUTE_UNUSED) cons
return VREL_VARYING;
}
-// Set R to [NAN, NAN].
-
-static inline void
-frange_set_nan (frange &r, tree type)
-{
- REAL_VALUE_TYPE rv;
- bool res = real_nan (&rv, "", 1, TYPE_MODE (type));
- if (flag_checking)
- gcc_assert (res);
- r.set (type, rv, rv);
-}
-
// Return TRUE if OP1 is known to be free of NANs.
static inline bool
@@ -248,7 +236,7 @@ build_lt (frange &r, tree type, const REAL_VALUE_TYPE &val)
if (real_isinf (&val, 1))
{
if (HONOR_NANS (type))
- frange_set_nan (r, type);
+ r.set_nan (type);
else
r.set_undefined ();
return false;
@@ -286,7 +274,7 @@ build_gt (frange &r, tree type, const REAL_VALUE_TYPE &val)
if (real_isinf (&val, 0))
{
if (HONOR_NANS (type))
- frange_set_nan (r, type);
+ r.set_nan (type);
else
r.set_undefined ();
return false;
@@ -392,14 +380,14 @@ foperator_equal::op1_range (frange &r, tree type,
if (HONOR_SIGNED_ZEROS (type) && r.contains_p (build_zero_cst (type)))
r.set_signbit (fp_prop::VARYING);
// The TRUE side of op1 == op2 implies op1 is !NAN.
- r.set_nan (fp_prop::NO);
+ r.clear_nan ();
break;
case BRS_FALSE:
r.set_varying (type);
// The FALSE side of op1 == op1 implies op1 is a NAN.
if (rel == VREL_EQ)
- frange_set_nan (r, type);
+ r.set_nan (type);
// If the result is false, the only time we know anything is
// if OP2 is a constant.
else if (op2.singleton_p ()
@@ -496,7 +484,7 @@ foperator_not_equal::op1_range (frange &r, tree type,
if (HONOR_SIGNED_ZEROS (type) && r.contains_p (build_zero_cst (type)))
r.set_signbit (fp_prop::VARYING);
// The FALSE side of op1 != op2 implies op1 is !NAN.
- r.set_nan (fp_prop::NO);
+ r.clear_nan ();
break;
default:
@@ -563,7 +551,7 @@ foperator_lt::op1_range (frange &r,
case BRS_TRUE:
if (build_lt (r, type, op2.upper_bound ()))
{
- r.set_nan (fp_prop::NO);
+ r.clear_nan ();
// x < y implies x is not +INF.
frange_drop_inf (r, type);
}
@@ -591,7 +579,7 @@ foperator_lt::op2_range (frange &r,
case BRS_TRUE:
if (build_gt (r, type, op1.lower_bound ()))
{
- r.set_nan (fp_prop::NO);
+ r.clear_nan ();
// x < y implies y is not -INF.
frange_drop_ninf (r, type);
}
@@ -664,7 +652,7 @@ foperator_le::op1_range (frange &r,
{
case BRS_TRUE:
if (build_le (r, type, op2.upper_bound ()))
- r.set_nan (fp_prop::NO);
+ r.clear_nan ();
break;
case BRS_FALSE:
@@ -688,7 +676,7 @@ foperator_le::op2_range (frange &r,
{
case BRS_TRUE:
if (build_ge (r, type, op1.lower_bound ()))
- r.set_nan (fp_prop::NO);
+ r.clear_nan ();
break;
case BRS_FALSE:
@@ -759,7 +747,7 @@ foperator_gt::op1_range (frange &r,
case BRS_TRUE:
if (build_gt (r, type, op2.lower_bound ()))
{
- r.set_nan (fp_prop::NO);
+ r.clear_nan ();
// x > y implies x is not -INF.
frange_drop_ninf (r, type);
}
@@ -787,7 +775,7 @@ foperator_gt::op2_range (frange &r,
case BRS_TRUE:
if (build_lt (r, type, op1.upper_bound ()))
{
- r.set_nan (fp_prop::NO);
+ r.clear_nan ();
// x > y implies y is not +INF.
frange_drop_inf (r, type);
}
@@ -860,7 +848,7 @@ foperator_ge::op1_range (frange &r,
{
case BRS_TRUE:
build_ge (r, type, op2.lower_bound ());
- r.set_nan (fp_prop::NO);
+ r.clear_nan ();
break;
case BRS_FALSE:
@@ -887,7 +875,7 @@ foperator_ge::op2_range (frange &r, tree type,
case BRS_TRUE:
build_le (r, type, op1.upper_bound ());
- r.set_nan (fp_prop::NO);
+ r.clear_nan ();
break;
default:
@@ -948,13 +936,13 @@ foperator_unordered::op1_range (frange &r, tree type,
// Since at least one operand must be NAN, if one of them is
// not, the other must be.
if (!op2.maybe_nan ())
- frange_set_nan (r, type);
+ r.set_nan (type);
break;
case BRS_FALSE:
r.set_varying (type);
// A false UNORDERED means both operands are !NAN.
- r.set_nan (fp_prop::NO);
+ r.clear_nan ();
break;
default:
@@ -1011,14 +999,14 @@ foperator_ordered::op1_range (frange &r, tree type,
case BRS_TRUE:
r.set_varying (type);
// The TRUE side of op1 ORDERED op2 implies op1 is !NAN.
- r.set_nan (fp_prop::NO);
+ r.clear_nan ();
break;
case BRS_FALSE:
r.set_varying (type);
// The FALSE side of op1 ORDERED op1 implies op1 is !NAN.
if (rel == VREL_EQ)
- r.set_nan (fp_prop::NO);
+ r.clear_nan ();
break;
default:
diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index de83f469be4..ea6e4b979ad 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -223,9 +223,9 @@ range_query::get_tree_range (vrange &r, tree expr, gimple *stmt)
// Singletons from the tree world have known properties.
REAL_VALUE_TYPE *rv = TREE_REAL_CST_PTR (expr);
if (real_isnan (rv))
- f.set_nan (fp_prop::YES);
+ f.update_nan (fp_prop::YES);
else
- f.set_nan (fp_prop::NO);
+ f.clear_nan ();
if (real_isneg (rv))
f.set_signbit (fp_prop::YES);
else
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index d40a4ebf657..dd827421aca 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -270,7 +270,7 @@ tree_compare (tree_code code, tree op1, tree op2)
// Set the NAN property. Adjust the range if appopriate.
void
-frange::set_nan (fp_prop::kind k)
+frange::update_nan (fp_prop::kind k)
{
if (k == fp_prop::YES)
{
@@ -280,7 +280,7 @@ frange::set_nan (fp_prop::kind k)
return;
}
gcc_checking_assert (!undefined_p ());
- *this = frange_nan (m_type);
+ set_nan (m_type);
return;
}
@@ -474,7 +474,7 @@ frange::union_ (const vrange &v)
*this = r;
m_props = save;
m_props.union_ (r.m_props);
- set_nan (fp_prop::VARYING);
+ update_nan (fp_prop::VARYING);
if (flag_checking)
verify_range ();
return true;
@@ -482,7 +482,7 @@ frange::union_ (const vrange &v)
if (r.known_nan ())
{
m_props.union_ (r.m_props);
- set_nan (fp_prop::VARYING);
+ update_nan (fp_prop::VARYING);
if (flag_checking)
verify_range ();
return true;
@@ -531,7 +531,7 @@ frange::intersect (const vrange &v)
if (m_props == r.m_props)
return false;
- *this = frange_nan (m_type);
+ set_nan (m_type);
return true;
}
// ?? Perhaps the intersection of a NAN and anything is a NAN ??.
@@ -3634,14 +3634,14 @@ range_tests_nan ()
r1 = frange_float ("10", "12");
r0 = r1;
ASSERT_EQ (r0, r1);
- r0.set_nan (fp_prop::NO);
+ r0.clear_nan ();
ASSERT_NE (r0, r1);
- r0.set_nan (fp_prop::YES);
+ r0.clear_nan ();
ASSERT_NE (r0, r1);
}
// NAN ranges are not equal to each other.
- r0 = frange_nan (float_type_node);
+ r0.set_nan (float_type_node);
r1 = r0;
ASSERT_FALSE (r0 == r1);
ASSERT_FALSE (r0 == r0);
@@ -3649,8 +3649,8 @@ range_tests_nan ()
// [5,6] U NAN = [5,6] NAN.
r0 = frange_float ("5", "6");
- r0.set_nan (fp_prop::NO);
- r1 = frange_nan (float_type_node);
+ r0.clear_nan ();
+ r1.set_nan (float_type_node);
r0.union_ (r1);
real_from_string (&q, "5");
real_from_string (&r, "6");
@@ -3659,34 +3659,34 @@ range_tests_nan ()
ASSERT_TRUE (r0.maybe_nan ());
// NAN U NAN = NAN
- r0 = frange_nan (float_type_node);
- r1 = frange_nan (float_type_node);
+ r0.set_nan (float_type_node);
+ r1.set_nan (float_type_node);
r0.union_ (r1);
ASSERT_TRUE (real_isnan (&r0.lower_bound ()));
ASSERT_TRUE (real_isnan (&r1.upper_bound ()));
ASSERT_TRUE (r0.known_nan ());
// [INF, INF] ^ NAN = VARYING
- r0 = frange_nan (float_type_node);
+ r0.set_nan (float_type_node);
r1 = frange_float ("+Inf", "+Inf");
r0.intersect (r1);
ASSERT_TRUE (r0.varying_p ());
// NAN ^ NAN = NAN
- r0 = frange_nan (float_type_node);
- r1 = frange_nan (float_type_node);
+ r0.set_nan (float_type_node);
+ r1.set_nan (float_type_node);
r0.intersect (r1);
ASSERT_TRUE (r0.known_nan ());
// VARYING ^ NAN = NAN.
- r0 = frange_nan (float_type_node);
+ r0.set_nan (float_type_node);
r1.set_varying (float_type_node);
r0.intersect (r1);
ASSERT_TRUE (r0.known_nan ());
// Setting the NAN bit to yes, forces to range to [NAN, NAN].
r0.set_varying (float_type_node);
- r0.set_nan (fp_prop::YES);
+ r0.update_nan (fp_prop::YES);
ASSERT_TRUE (r0.known_nan ());
ASSERT_TRUE (real_isnan (&r0.lower_bound ()));
ASSERT_TRUE (real_isnan (&r0.upper_bound ()));
@@ -3736,7 +3736,7 @@ range_tests_signed_zeros ()
ASSERT_TRUE (r0.zero_p () && !r0.known_signbit (signbit));
// NAN U [5,6] should be [5,6] with no sign info.
- r0 = frange_nan (float_type_node);
+ r0.set_nan (float_type_node);
r1 = frange_float ("5", "6");
r0.union_ (r1);
real_from_string (&q, "5");
@@ -3762,7 +3762,7 @@ range_tests_signbit ()
// the signbit property set.
r0 = frange_float ("-5", "10");
r0.set_signbit (fp_prop::YES);
- r0.set_nan (fp_prop::NO);
+ r0.clear_nan ();
ASSERT_TRUE (r0.known_signbit (signbit) && signbit);
r1 = frange_float ("-5", "0");
ASSERT_TRUE (real_identical (&r0.lower_bound (), &r1.lower_bound ()));
@@ -3770,20 +3770,20 @@ range_tests_signbit ()
// Negative numbers should have the SIGNBIT set.
r0 = frange_float ("-5", "-1");
- r0.set_nan (fp_prop::NO);
+ r0.clear_nan ();
ASSERT_TRUE (r0.known_signbit (signbit) && signbit);
// Positive numbers should have the SIGNBIT clear.
r0 = frange_float ("1", "10");
- r0.set_nan (fp_prop::NO);
+ r0.clear_nan ();
ASSERT_TRUE (r0.known_signbit (signbit) && !signbit);
// Numbers containing zero should have an unknown SIGNBIT.
r0 = frange_float ("0", "10");
- r0.set_nan (fp_prop::NO);
+ r0.clear_nan ();
ASSERT_TRUE (!r0.known_signbit (signbit));
// Numbers spanning both positive and negative should have an
// unknown SIGNBIT.
r0 = frange_float ("-10", "10");
- r0.set_nan (fp_prop::NO);
+ r0.clear_nan ();
ASSERT_TRUE (!r0.known_signbit (signbit));
r0.set_varying (float_type_node);
ASSERT_TRUE (!r0.known_signbit (signbit));
@@ -3791,12 +3791,12 @@ range_tests_signbit ()
// Ignore signbit changes when the sign bit is obviously known from
// the range.
r0 = frange_float ("5", "10");
- r0.set_nan (fp_prop::NO);
+ r0.clear_nan ();
r0.set_signbit (fp_prop::VARYING);
ASSERT_TRUE (r0.known_signbit (signbit) && !signbit);
r0 = frange_float ("-5", "-1");
r0.set_signbit (fp_prop::NO);
- r0.set_nan (fp_prop::NO);
+ r0.clear_nan ();
ASSERT_TRUE (r0.undefined_p ());
}
@@ -3817,7 +3817,7 @@ range_tests_floats ()
if (r0.maybe_nan ())
ASSERT_TRUE (r0.varying_p ());
// ...unless it has some special property...
- r0.set_nan (fp_prop::NO);
+ r0.clear_nan ();
ASSERT_FALSE (r0.varying_p ());
// The endpoints of a VARYING are +-INF.
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 0ba0193bc1f..6e896eb9ab5 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -348,6 +348,7 @@ 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_nan (tree type);
virtual void set_varying (tree type) override;
virtual void set_undefined () override;
virtual bool union_ (const vrange &) override;
@@ -376,7 +377,8 @@ public:
bool known_signbit (bool &signbit) const;
// Accessors for FP properties.
- void set_nan (fp_prop::kind f);
+ void update_nan (fp_prop::kind f);
+ void clear_nan () { update_nan (fp_prop::NO); }
void set_signbit (fp_prop::kind);
private:
fp_prop get_nan () const { return m_props.get_nan (); }
@@ -1186,13 +1188,12 @@ real_min_representable (REAL_VALUE_TYPE *r, tree type)
// Build a NAN of type TYPE.
-inline frange
-frange_nan (tree type)
+inline void
+frange::set_nan (tree type)
{
REAL_VALUE_TYPE r;
-
gcc_assert (real_nan (&r, "", 1, TYPE_MODE (type)));
- return frange (type, r, r);
+ set (type, r, r);
}
// Return TRUE if range is known to be finite.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-09-14 15:07 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-14 15:07 [gcc r13-2668] Provide cleaner set_nan(), clear_nan(), and update_nan() methods Aldy Hernandez
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).