}
frange res;
- REAL_VALUE_TYPE lb, ub;
- bool maybe_nan;
- rv_fold (res, type,
- lb, ub, maybe_nan,
+ rv_fold (r, type,
op1.lower_bound (), op1.upper_bound (),
op2.lower_bound (), op2.upper_bound (), trio.op1_op2 ());
- // Handle possible NANs by saturating to the appropriate INF if only
- // one end is a NAN. If both ends are a NAN, just return a NAN.
- bool lb_nan = real_isnan (&lb);
- bool ub_nan = real_isnan (&ub);
- if (lb_nan && ub_nan)
- {
- r.set_nan (type);
- gcc_checking_assert (r == res);
- return true;
- }
- if (lb_nan)
- lb = dconstninf;
- else if (ub_nan)
- ub = dconstinf;
-
- r.set (type, lb, ub);
-
- if (lb_nan || ub_nan || maybe_nan
- || op1.maybe_isnan ()
- || op2.maybe_isnan ())
- // Keep the default NAN (with a varying sign) set by the setter.
- ;
- else
- r.clear_nan ();
-
+ if (r.known_isnan ())
+ return true;
if (op1.maybe_isnan () || op2.maybe_isnan ())
- res.update_nan ();
- gcc_checking_assert (r == res);
+ r.update_nan ();
// If the result has overflowed and flag_trapping_math, folding this
// operation could elide an overflow or division by zero exception.
// UB, the final range has the possibility of a NAN.
void
range_operator::rv_fold (frange &r, tree type,
- REAL_VALUE_TYPE &lb,
- REAL_VALUE_TYPE &ub,
- bool &maybe_nan,
const REAL_VALUE_TYPE &,
const REAL_VALUE_TYPE &,
const REAL_VALUE_TYPE &,
const REAL_VALUE_TYPE &, relation_kind) const
{
- lb = dconstninf;
- ub = dconstinf;
- maybe_nan = true;
r.set (type, dconstninf, dconstinf, nan_state (true));
}
void
operator_plus::rv_fold (frange &r, tree type,
- REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
- bool &maybe_nan,
const REAL_VALUE_TYPE &lh_lb,
const REAL_VALUE_TYPE &lh_ub,
const REAL_VALUE_TYPE &rh_lb,
const REAL_VALUE_TYPE &rh_ub,
relation_kind) const
{
+ REAL_VALUE_TYPE lb, ub;
+ bool maybe_nan = false;
+
frange_arithmetic (PLUS_EXPR, type, lb, lh_lb, rh_lb, dconstninf);
frange_arithmetic (PLUS_EXPR, type, ub, lh_ub, rh_ub, dconstinf);
// [+INF] + [-INF] = NAN
else if (real_isinf (&lh_ub, false) && real_isinf (&rh_lb, true))
maybe_nan = true;
- else
- maybe_nan = false;
// Handle possible NANs by saturating to the appropriate INF if only
// one end is a NAN. If both ends are a NAN, just return a NAN.
void
operator_minus::rv_fold (frange &r, tree type,
- REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
- bool &maybe_nan,
const REAL_VALUE_TYPE &lh_lb,
const REAL_VALUE_TYPE &lh_ub,
const REAL_VALUE_TYPE &rh_lb,
const REAL_VALUE_TYPE &rh_ub,
relation_kind) const
{
+ REAL_VALUE_TYPE lb, ub;
+ bool maybe_nan = false;
+
frange_arithmetic (MINUS_EXPR, type, lb, lh_lb, rh_ub, dconstninf);
frange_arithmetic (MINUS_EXPR, type, ub, lh_ub, rh_lb, dconstinf);
// [-INF] - [-INF] = NAN
else if (real_isinf (&lh_lb, true) && real_isinf (&rh_lb, true))
maybe_nan = true;
- else
- maybe_nan = false;
// Handle possible NANs by saturating to the appropriate INF if only
// one end is a NAN. If both ends are a NAN, just return a NAN.
void
operator_mult::rv_fold (frange &r, tree type,
- REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
- bool &maybe_nan,
const REAL_VALUE_TYPE &lh_lb,
const REAL_VALUE_TYPE &lh_ub,
const REAL_VALUE_TYPE &rh_lb,
&& real_equal (&lh_ub, &rh_ub)
&& real_isneg (&lh_lb) == real_isneg (&rh_lb)
&& real_isneg (&lh_ub) == real_isneg (&rh_ub));
-
- maybe_nan = false;
+ REAL_VALUE_TYPE lb, ub;
+ bool maybe_nan = false;
// x * x never produces a new NAN and we only multiply the same
// values, so the 0 * INF problematic cases never appear there.
if (!is_square)
if ((zero_p (lh_lb, lh_ub) && singleton_inf_p (rh_lb, rh_ub))
|| (zero_p (rh_lb, rh_ub) && singleton_inf_p (lh_lb, lh_ub)))
{
- real_nan (&lb, "", 0, TYPE_MODE (type));
- ub = lb;
- maybe_nan = true;
r.set_nan (type);
return;
}
}
private:
void rv_fold (frange &r, tree type,
- REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, bool &maybe_nan,
const REAL_VALUE_TYPE &lh_lb,
const REAL_VALUE_TYPE &lh_ub,
const REAL_VALUE_TYPE &rh_lb,
if ((zero_p (lh_lb, lh_ub) && zero_p (rh_lb, rh_ub))
|| (singleton_inf_p (lh_lb, lh_ub) && singleton_inf_p (rh_lb, rh_ub)))
{
- real_nan (&lb, "", 0, TYPE_MODE (type));
- ub = lb;
- maybe_nan = true;
r.set_nan (type);
return;
}
+ REAL_VALUE_TYPE lb, ub;
+ bool maybe_nan = false;
// If +-0.0 is in both ranges, it is a maybe NAN.
if (contains_zero_p (lh_lb, lh_ub) && contains_zero_p (rh_lb, rh_ub))
maybe_nan = true;
else if ((real_isinf (&lh_lb) || real_isinf (&lh_ub))
&& (real_isinf (&rh_lb) || real_isinf (&rh_ub)))
maybe_nan = true;
- else
- maybe_nan = false;
int signbit_known = signbit_known_p (lh_lb, lh_ub, rh_lb, rh_ub);
const wide_int &lh_ub, const wide_int &rh_lb,
const wide_int &rh_ub) const final override;
void rv_fold (frange &r, tree type,
- REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
- bool &maybe_nan,
const REAL_VALUE_TYPE &lh_lb, const REAL_VALUE_TYPE &lh_ub,
const REAL_VALUE_TYPE &rh_lb, const REAL_VALUE_TYPE &rh_ub,
relation_kind) const final override;
const wide_int &lh_ub, const wide_int &rh_lb,
const wide_int &rh_ub) const final override;
void rv_fold (frange &r, tree type,
- REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
- bool &maybe_nan,
const REAL_VALUE_TYPE &lh_lb, const REAL_VALUE_TYPE &lh_ub,
const REAL_VALUE_TYPE &rh_lb, const REAL_VALUE_TYPE &rh_ub,
relation_kind) const final override;
const wide_int &w1) const final override;
void rv_fold (frange &r, tree type,
- REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
- bool &maybe_nan,
const REAL_VALUE_TYPE &lh_lb, const REAL_VALUE_TYPE &lh_ub,
const REAL_VALUE_TYPE &rh_lb, const REAL_VALUE_TYPE &rh_ub,
relation_kind kind) const final override;