diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc index 58606aa46112f83dd9d7aa41a9d4728219d4871a..204b3911cc48fbee0742214eaa227eabffbb53ba 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