diff options
-rw-r--r-- | gcc/range-op-float.cc | 72 | ||||
-rw-r--r-- | gcc/range-op-mixed.h | 6 | ||||
-rw-r--r-- | gcc/range-op.h | 2 |
3 files changed, 14 insertions, 66 deletions
diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc index cb2c0a6..ffa3dec 100644 --- a/gcc/range-op-float.cc +++ b/gcc/range-op-float.cc @@ -63,41 +63,14 @@ range_operator::fold_range (frange &r, tree type, } 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. @@ -130,17 +103,11 @@ range_operator::fold_range (frange &r, tree type, // 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)); } @@ -2479,14 +2446,15 @@ operator_plus::op2_range (frange &r, tree type, 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); @@ -2496,8 +2464,6 @@ operator_plus::rv_fold (frange &r, tree type, // [+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. @@ -2543,14 +2509,15 @@ operator_minus::op2_range (frange &r, tree type, 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); @@ -2560,8 +2527,6 @@ operator_minus::rv_fold (frange &r, tree type, // [-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. @@ -2652,8 +2617,6 @@ operator_mult::op2_range (frange &r, tree type, 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, @@ -2666,8 +2629,8 @@ operator_mult::rv_fold (frange &r, tree type, && 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) @@ -2676,9 +2639,6 @@ operator_mult::rv_fold (frange &r, tree type, 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; } @@ -2841,7 +2801,6 @@ public: } 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, @@ -2852,13 +2811,12 @@ private: 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; @@ -2866,8 +2824,6 @@ private: 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); diff --git a/gcc/range-op-mixed.h b/gcc/range-op-mixed.h index ccaa2c2..45e11df 100644 --- a/gcc/range-op-mixed.h +++ b/gcc/range-op-mixed.h @@ -415,8 +415,6 @@ private: 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; @@ -485,8 +483,6 @@ private: 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; @@ -556,8 +552,6 @@ public: 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; diff --git a/gcc/range-op.h b/gcc/range-op.h index 3ec53a0..282ce38 100644 --- a/gcc/range-op.h +++ b/gcc/range-op.h @@ -186,8 +186,6 @@ protected: // Perform an float operation between 2 ranges and return it. virtual 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, |