aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/range-op-float.cc20
1 files changed, 18 insertions, 2 deletions
diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index 58606aa..204b391 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -2205,8 +2205,8 @@ zero_to_inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
[1., 1.] = op1 + [1., 1.]. op1's range is not [0., 0.], but
[-0x1.0p-54, 0x1.0p-53] (when not -frounding-math), any value for
which adding 1. to it results in 1. after rounding to nearest.
- So, for op1_range/op2_range extend the lhs range by 1ulp in each
- direction. See PR109008 for more details. */
+ So, for op1_range/op2_range extend the lhs range by 1ulp (or 0.5ulp)
+ in each direction. See PR109008 for more details. */
static frange
float_widen_lhs_range (tree type, const frange &lhs)
@@ -2230,6 +2230,14 @@ float_widen_lhs_range (tree type, const frange &lhs)
lb = dconstm1;
SET_REAL_EXP (&lb, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1);
}
+ if (!flag_rounding_math && !MODE_COMPOSITE_P (TYPE_MODE (type)))
+ {
+ /* If not -frounding-math nor IBM double double, actually widen
+ just by 0.5ulp rather than 1ulp. */
+ REAL_VALUE_TYPE tem;
+ real_arithmetic (&tem, PLUS_EXPR, &lhs.lower_bound (), &lb);
+ real_arithmetic (&lb, RDIV_EXPR, &tem, &dconst2);
+ }
}
if (real_isfinite (&ub))
{
@@ -2240,6 +2248,14 @@ float_widen_lhs_range (tree type, const frange &lhs)
ub = dconst1;
SET_REAL_EXP (&ub, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1);
}
+ if (!flag_rounding_math && !MODE_COMPOSITE_P (TYPE_MODE (type)))
+ {
+ /* If not -frounding-math nor IBM double double, actually widen
+ just by 0.5ulp rather than 1ulp. */
+ REAL_VALUE_TYPE tem;
+ real_arithmetic (&tem, PLUS_EXPR, &lhs.upper_bound (), &ub);
+ real_arithmetic (&ub, RDIV_EXPR, &tem, &dconst2);
+ }
}
/* Temporarily disable -ffinite-math-only, so that frange::set doesn't
reduce the range back to real_min_representable (type) as lower bound