REAL_VALUE_TYPE lb = lhs.lower_bound ();
REAL_VALUE_TYPE ub = lhs.upper_bound ();
if (real_isfinite (&lb))
- frange_nextafter (TYPE_MODE (type), lb, dconstninf);
+ {
+ frange_nextafter (TYPE_MODE (type), lb, dconstninf);
+ if (real_isinf (&lb))
+ {
+ /* For -DBL_MAX, instead of -Inf use
+ nexttoward (-DBL_MAX, -LDBL_MAX) in a hypothetical
+ wider type with the same mantissa precision but larger
+ exponent range; it is outside of range of double values,
+ but makes it clear it is just one ulp larger rather than
+ infinite amount larger. */
+ lb = dconstm1;
+ SET_REAL_EXP (&lb, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1);
+ }
+ }
if (real_isfinite (&ub))
- frange_nextafter (TYPE_MODE (type), ub, dconstinf);
+ {
+ frange_nextafter (TYPE_MODE (type), ub, dconstinf);
+ if (real_isinf (&ub))
+ {
+ /* For DBL_MAX similarly. */
+ ub = dconst1;
+ SET_REAL_EXP (&ub, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1);
+ }
+ }
+ /* Temporarily disable -ffinite-math-only, so that frange::set doesn't
+ reduce the range back to real_min_representable (type) as lower bound
+ or real_max_representable (type) as upper bound. */
+ bool save_flag_finite_math_only = flag_finite_math_only;
+ flag_finite_math_only = false;
ret.set (type, lb, ub);
- ret.clear_nan ();
- ret.union_ (lhs);
+ if (lhs.kind () != VR_VARYING)
+ {
+ ret.clear_nan ();
+ ret.union_ (lhs);
+ }
+ flag_finite_math_only = save_flag_finite_math_only;
return ret;
}
--- /dev/null
+/* PR tree-optimization/109008 */
+/* { dg-do run } */
+/* { dg-options "-O2 -ffinite-math-only -fexcess-precision=standard" } */
+
+__attribute__((noipa)) double
+foo (double eps)
+{
+ double d = __DBL_MAX__ + eps;
+ if (d == __DBL_MAX__)
+ if (eps > 16.0)
+ return eps;
+ return 0.0;
+}
+
+int
+main ()
+{
+#if __DBL_MANT_DIG__ == 53 && __DBL_MAX_EXP__ == 1024 && __DBL_MIN_EXP__ == -1021 \
+ && __FLT_EVAL_METHOD__ == 0
+ if (foo (0x0.8p+970) == 0.0)
+ __builtin_abort ();
+ if (foo (32.0) == 0.0)
+ __builtin_abort ();
+#endif
+ return 0;
+}