aboutsummaryrefslogtreecommitdiff
path: root/gcc/value-range.cc
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2022-09-22 18:20:39 +0200
committerAldy Hernandez <aldyh@redhat.com>2022-09-23 10:52:21 +0200
commitb7fd7fb5011106c062df9275ca8fddcbce4ebdeb (patch)
treea42c03a68d1a2a8f16bee2a2b6957ea6a1cf3586 /gcc/value-range.cc
parent76dbbfe62c0d7f4548cb12e757f67a1b1f84c3df (diff)
downloadgcc-b7fd7fb5011106c062df9275ca8fddcbce4ebdeb.zip
gcc-b7fd7fb5011106c062df9275ca8fddcbce4ebdeb.tar.gz
gcc-b7fd7fb5011106c062df9275ca8fddcbce4ebdeb.tar.bz2
frange: drop endpoints to min/max representable numbers for -ffinite-math-only.
Similarly to how we drop NANs to UNDEFINED when -ffinite-math-only, I think we can drop the numbers outside of the min/max representable numbers to the representable number. This means the endpoings to VR_VARYING for -ffinite-math-only can now be the min/max representable, instead of -INF and +INF. Saturating in the setter means that the upcoming implementation for binary operators no longer have to worry about doing the right thing for -ffinite-math-only. If the range goes outside the limits, it'll get chopped down. Tested on x86-64 Linux. gcc/ChangeLog: * range-op-float.cc (build_le): Use vrp_val_*. (build_lt): Same. (build_ge): Same. (build_gt): Same. * value-range.cc (frange::set): Chop ranges outside of the representable numbers for -ffinite-math-only. (frange::normalize_kind): Use vrp_val*. (frange::verify_range): Same. (frange::set_nonnegative): Same. (range_tests_floats): Remove tests that depend on -INF and +INF. * value-range.h (real_max_representable): Add prototype. (real_min_representable): Same. (vrp_val_max): Set max representable number for -ffinite-math-only. (vrp_val_min): Same but for min. (frange::set_varying): Use vrp_val*.
Diffstat (limited to 'gcc/value-range.cc')
-rw-r--r--gcc/value-range.cc46
1 files changed, 21 insertions, 25 deletions
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 7e8028e..43905ba 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -338,6 +338,18 @@ frange::set (tree min, tree max, value_range_kind kind)
m_neg_nan = false;
}
+ // For -ffinite-math-only we can drop ranges outside the
+ // representable numbers to min/max for the type.
+ if (flag_finite_math_only)
+ {
+ REAL_VALUE_TYPE min_repr = frange_val_min (m_type);
+ REAL_VALUE_TYPE max_repr = frange_val_max (m_type);
+ if (real_less (&m_min, &min_repr))
+ m_min = min_repr;
+ if (real_less (&max_repr, &m_max))
+ m_max = max_repr;
+ }
+
// Check for swapped ranges.
gcc_checking_assert (tree_compare (LE_EXPR, min, max));
@@ -371,8 +383,8 @@ bool
frange::normalize_kind ()
{
if (m_kind == VR_RANGE
- && real_isinf (&m_min, 1)
- && real_isinf (&m_max, 0))
+ && frange_val_is_min (m_min, m_type)
+ && frange_val_is_max (m_max, m_type))
{
if (m_pos_nan && m_neg_nan)
{
@@ -385,8 +397,8 @@ frange::normalize_kind ()
if (!m_pos_nan || !m_neg_nan)
{
m_kind = VR_RANGE;
- m_min = dconstninf;
- m_max = dconstinf;
+ m_min = frange_val_min (m_type);
+ m_max = frange_val_max (m_type);
return true;
}
}
@@ -706,8 +718,8 @@ frange::verify_range ()
case VR_VARYING:
gcc_checking_assert (m_type);
gcc_checking_assert (m_pos_nan && m_neg_nan);
- gcc_checking_assert (real_isinf (&m_min, 1));
- gcc_checking_assert (real_isinf (&m_max, 0));
+ gcc_checking_assert (frange_val_is_min (m_min, m_type));
+ gcc_checking_assert (frange_val_is_max (m_max, m_type));
return;
case VR_RANGE:
gcc_checking_assert (m_type);
@@ -732,7 +744,8 @@ frange::verify_range ()
// If all the properties are clear, we better not span the entire
// domain, because that would make us varying.
if (m_pos_nan && m_neg_nan)
- gcc_checking_assert (!real_isinf (&m_min, 1) || !real_isinf (&m_max, 0));
+ gcc_checking_assert (!frange_val_is_min (m_min, m_type)
+ || !frange_val_is_max (m_max, m_type));
}
// We can't do much with nonzeros yet.
@@ -779,7 +792,7 @@ frange::zero_p () const
void
frange::set_nonnegative (tree type)
{
- set (type, dconst0, dconstinf);
+ set (type, dconst0, frange_val_max (type));
// Set +NAN as the only possibility.
if (HONOR_NANS (type))
@@ -3886,23 +3899,6 @@ range_tests_floats ()
r0.clear_nan ();
ASSERT_FALSE (r0.varying_p ());
- // The endpoints of a VARYING are +-INF.
- r0.set_varying (float_type_node);
- ASSERT_TRUE (real_identical (&r0.lower_bound (), &dconstninf));
- ASSERT_TRUE (real_identical (&r0.upper_bound (), &dconstinf));
-
- // The maximum representable range for a type is still a subset of VARYING.
- REAL_VALUE_TYPE q, r;
- real_min_representable (&q, float_type_node);
- real_max_representable (&r, float_type_node);
- r0 = frange (float_type_node, q, r);
- // r0 is not a varying, because it does not include -INF/+INF.
- ASSERT_FALSE (r0.varying_p ());
- // The upper bound of r0 must be less than +INF.
- ASSERT_TRUE (real_less (&r0.upper_bound (), &dconstinf));
- // The lower bound of r0 must be greater than -INF.
- ASSERT_TRUE (real_less (&dconstninf, &r0.lower_bound ()));
-
// For most architectures, where float and double are different
// sizes, having the same endpoints does not necessarily mean the
// ranges are equal.