From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1011) id 80C9A385C6F1; Sat, 10 Jun 2023 00:34:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 80C9A385C6F1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1686357286; bh=fSinVF/z48wXn92luDflyiVJM2XqmAmNOfR4xvEft0A=; h=From:To:Subject:Date:From; b=etS8RGbjYN0KM3wU+tKB8ZbzAzGHjN+MmfdaxUVazlp3n4HdkKo6yE7FRudeDYrI5 TzgF4T/k5H/XH+7GJlnh94mDDZ3r7LND/bidYcAuYKYz/gOScqywQMRpc2YBI165yw WZf3NPWCIXB7drBA+NNZMI8i3e7J8A8XBd6x5RHQ= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Andrew Macleod To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-1681] Unify MULT_EXPR range operator X-Act-Checkin: gcc X-Git-Author: Andrew MacLeod X-Git-Refname: refs/heads/master X-Git-Oldrev: 56518befc2663ddc082e34dddd66b6334a3d4da5 X-Git-Newrev: a13c4440949f300eacb9918b554ead6a5760dc50 Message-Id: <20230610003446.80C9A385C6F1@sourceware.org> Date: Sat, 10 Jun 2023 00:34:46 +0000 (GMT) List-Id: https://gcc.gnu.org/g:a13c4440949f300eacb9918b554ead6a5760dc50 commit r14-1681-ga13c4440949f300eacb9918b554ead6a5760dc50 Author: Andrew MacLeod Date: Fri Jun 9 13:47:09 2023 -0400 Unify MULT_EXPR range operator Move the declaration of the class to the range-op-mixed header, add the floating point prototypes as well, and use it in the new unified table. * range-op-float.cc (foperator_mult_div_base): Delete. (foperator_mult_div_base::find_range): Make static local function. (foperator_mult): Remove. Move prototypes to range-op-mixed.h (operator_mult::op1_range): Rename from foperator_mult. (operator_mult::op2_range): Ditto. (operator_mult::rv_fold): Ditto. (float_table::float_table): Remove MULT_EXPR. (class foperator_div): Inherit from range_operator. (float_table::float_table): Delete. * range-op-mixed.h (class operator_mult): Combined from integer and float files. * range-op.cc (float_tree_table): Delete. (op_mult): New object. (unified_table::unified_table): Add MULT_EXPR. (get_op_handler): Do not check float table any longer. (class cross_product_operator): Move to range-op-mixed.h. (class operator_mult): Move to range-op-mixed.h. (integral_table::integral_table): Remove MULT_EXPR. (pointer_table::pointer_table): Remove MULT_EXPR. * range-op.h (float_table): Remove. Diff: --- gcc/range-op-float.cc | 349 ++++++++++++++++++++++++-------------------------- gcc/range-op-mixed.h | 51 ++++++++ gcc/range-op.cc | 53 +------- gcc/range-op.h | 10 -- 4 files changed, 227 insertions(+), 236 deletions(-) diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc index 20b4b9f0d61..757484a9de9 100644 --- a/gcc/range-op-float.cc +++ b/gcc/range-op-float.cc @@ -2331,188 +2331,182 @@ operator_minus::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, } -class foperator_mult_div_base : public range_operator -{ -protected: - // Given CP[0] to CP[3] floating point values rounded to -INF, - // set LB to the smallest of them (treating -0 as smaller to +0). - // Given CP[4] to CP[7] floating point values rounded to +INF, - // set UB to the largest of them (treating -0 as smaller to +0). - static void find_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, - const REAL_VALUE_TYPE (&cp)[8]) - { - lb = cp[0]; - ub = cp[4]; - for (int i = 1; i < 4; ++i) - { - if (real_less (&cp[i], &lb) - || (real_iszero (&lb) && real_isnegzero (&cp[i]))) - lb = cp[i]; - if (real_less (&ub, &cp[i + 4]) - || (real_isnegzero (&ub) && real_iszero (&cp[i + 4]))) - ub = cp[i + 4]; - } - } -}; +// Given CP[0] to CP[3] floating point values rounded to -INF, +// set LB to the smallest of them (treating -0 as smaller to +0). +// Given CP[4] to CP[7] floating point values rounded to +INF, +// set UB to the largest of them (treating -0 as smaller to +0). + +static void +find_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, + const REAL_VALUE_TYPE (&cp)[8]) +{ + lb = cp[0]; + ub = cp[4]; + for (int i = 1; i < 4; ++i) + { + if (real_less (&cp[i], &lb) + || (real_iszero (&lb) && real_isnegzero (&cp[i]))) + lb = cp[i]; + if (real_less (&ub, &cp[i + 4]) + || (real_isnegzero (&ub) && real_iszero (&cp[i + 4]))) + ub = cp[i + 4]; + } +} -class foperator_mult : public foperator_mult_div_base +bool +operator_mult::op1_range (frange &r, tree type, + const frange &lhs, const frange &op2, + relation_trio) const { - using range_operator::op1_range; - using range_operator::op2_range; -public: - virtual bool op1_range (frange &r, tree type, - const frange &lhs, - const frange &op2, - relation_trio = TRIO_VARYING) const final override - { - if (lhs.undefined_p ()) - return false; - range_op_handler rdiv (RDIV_EXPR, type); - if (!rdiv) - return false; - frange wlhs = float_widen_lhs_range (type, lhs); - bool ret = rdiv.fold_range (r, type, wlhs, op2); - if (ret == false) - return false; - if (wlhs.known_isnan () || op2.known_isnan () || op2.undefined_p ()) - return float_binary_op_range_finish (ret, r, type, wlhs); - const REAL_VALUE_TYPE &lhs_lb = wlhs.lower_bound (); - const REAL_VALUE_TYPE &lhs_ub = wlhs.upper_bound (); - const REAL_VALUE_TYPE &op2_lb = op2.lower_bound (); - const REAL_VALUE_TYPE &op2_ub = op2.upper_bound (); - if ((contains_zero_p (lhs_lb, lhs_ub) && contains_zero_p (op2_lb, op2_ub)) - || ((real_isinf (&lhs_lb) || real_isinf (&lhs_ub)) - && (real_isinf (&op2_lb) || real_isinf (&op2_ub)))) - { - // If both lhs and op2 could be zeros or both could be infinities, - // we don't know anything about op1 except maybe for the sign - // and perhaps if it can be NAN or not. - REAL_VALUE_TYPE lb, ub; - int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op2_lb, op2_ub); - zero_to_inf_range (lb, ub, signbit_known); - r.set (type, lb, ub); - } - // Otherwise, if op2 is a singleton INF and lhs doesn't include INF, - // or if lhs must be zero and op2 doesn't include zero, it would be - // UNDEFINED, while rdiv.fold_range computes a zero or singleton INF - // range. Those are supersets of UNDEFINED, so let's keep that way. + if (lhs.undefined_p ()) + return false; + range_op_handler rdiv (RDIV_EXPR, type); + if (!rdiv) + return false; + frange wlhs = float_widen_lhs_range (type, lhs); + bool ret = rdiv.fold_range (r, type, wlhs, op2); + if (ret == false) + return false; + if (wlhs.known_isnan () || op2.known_isnan () || op2.undefined_p ()) return float_binary_op_range_finish (ret, r, type, wlhs); - } - virtual bool op2_range (frange &r, tree type, - const frange &lhs, - const frange &op1, - relation_trio = TRIO_VARYING) const final override - { - return op1_range (r, type, lhs, op1); - } -private: - void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, bool &maybe_nan, - tree type, - 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 - { - bool is_square - = (kind == VREL_EQ - && real_equal (&lh_lb, &rh_lb) - && real_equal (&lh_ub, &rh_ub) - && real_isneg (&lh_lb) == real_isneg (&rh_lb) - && real_isneg (&lh_ub) == real_isneg (&rh_ub)); + const REAL_VALUE_TYPE &lhs_lb = wlhs.lower_bound (); + const REAL_VALUE_TYPE &lhs_ub = wlhs.upper_bound (); + const REAL_VALUE_TYPE &op2_lb = op2.lower_bound (); + const REAL_VALUE_TYPE &op2_ub = op2.upper_bound (); + if ((contains_zero_p (lhs_lb, lhs_ub) && contains_zero_p (op2_lb, op2_ub)) + || ((real_isinf (&lhs_lb) || real_isinf (&lhs_ub)) + && (real_isinf (&op2_lb) || real_isinf (&op2_ub)))) + { + // If both lhs and op2 could be zeros or both could be infinities, + // we don't know anything about op1 except maybe for the sign + // and perhaps if it can be NAN or not. + REAL_VALUE_TYPE lb, ub; + int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op2_lb, op2_ub); + zero_to_inf_range (lb, ub, signbit_known); + r.set (type, lb, ub); + } + // Otherwise, if op2 is a singleton INF and lhs doesn't include INF, + // or if lhs must be zero and op2 doesn't include zero, it would be + // UNDEFINED, while rdiv.fold_range computes a zero or singleton INF + // range. Those are supersets of UNDEFINED, so let's keep that way. + return float_binary_op_range_finish (ret, r, type, wlhs); +} - 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) - { - // [+-0, +-0] * [+INF,+INF] (or [-INF,-INF] or swapped is a known NAN. - 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; - return; - } - - // Otherwise, if one range includes zero and the other ends with +-INF, - // it is a maybe NAN. - if ((contains_zero_p (lh_lb, lh_ub) - && (real_isinf (&rh_lb) || real_isinf (&rh_ub))) - || (contains_zero_p (rh_lb, rh_ub) - && (real_isinf (&lh_lb) || real_isinf (&lh_ub)))) - { - maybe_nan = true; - - int signbit_known = signbit_known_p (lh_lb, lh_ub, rh_lb, rh_ub); - - // If one of the ranges that includes INF is singleton - // and the other range includes zero, the resulting - // range is INF and NAN, because the 0 * INF boundary - // case will be NAN, but already nextafter (0, 1) * INF - // is INF. - if (singleton_inf_p (lh_lb, lh_ub) - || singleton_inf_p (rh_lb, rh_ub)) - return inf_range (lb, ub, signbit_known); - - // If one of the multiplicands must be zero, the resulting - // range is +-0 and NAN. - if (zero_p (lh_lb, lh_ub) || zero_p (rh_lb, rh_ub)) - return zero_range (lb, ub, signbit_known); - - // Otherwise one of the multiplicands could be - // [0.0, nextafter (0.0, 1.0)] and the [DBL_MAX, INF] - // or similarly with different signs. 0.0 * DBL_MAX - // is still 0.0, nextafter (0.0, 1.0) * INF is still INF, - // so if the signs are always the same or always different, - // result is [+0.0, +INF] or [-INF, -0.0], otherwise VARYING. - return zero_to_inf_range (lb, ub, signbit_known); - } - } +bool +operator_mult::op2_range (frange &r, tree type, + const frange &lhs, const frange &op1, + relation_trio) const +{ + return op1_range (r, type, lhs, op1); +} - REAL_VALUE_TYPE cp[8]; - // Do a cross-product. At this point none of the multiplications - // should produce a NAN. - frange_arithmetic (MULT_EXPR, type, cp[0], lh_lb, rh_lb, dconstninf); - frange_arithmetic (MULT_EXPR, type, cp[4], lh_lb, rh_lb, dconstinf); - if (is_square) - { - // For x * x we can just do max (lh_lb * lh_lb, lh_ub * lh_ub) - // as maximum and -0.0 as minimum if 0.0 is in the range, - // otherwise min (lh_lb * lh_lb, lh_ub * lh_ub). - // -0.0 rather than 0.0 because VREL_EQ doesn't prove that - // x and y are bitwise equal, just that they compare equal. - if (contains_zero_p (lh_lb, lh_ub)) - { - if (real_isneg (&lh_lb) == real_isneg (&lh_ub)) - cp[1] = dconst0; - else - cp[1] = dconstm0; - } - else - cp[1] = cp[0]; - cp[2] = cp[0]; - cp[5] = cp[4]; - cp[6] = cp[4]; - } - else - { - frange_arithmetic (MULT_EXPR, type, cp[1], lh_lb, rh_ub, dconstninf); - frange_arithmetic (MULT_EXPR, type, cp[5], lh_lb, rh_ub, dconstinf); - frange_arithmetic (MULT_EXPR, type, cp[2], lh_ub, rh_lb, dconstninf); - frange_arithmetic (MULT_EXPR, type, cp[6], lh_ub, rh_lb, dconstinf); - } - frange_arithmetic (MULT_EXPR, type, cp[3], lh_ub, rh_ub, dconstninf); - frange_arithmetic (MULT_EXPR, type, cp[7], lh_ub, rh_ub, dconstinf); +void +operator_mult::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, + bool &maybe_nan, tree type, + 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 +{ + bool is_square + = (kind == VREL_EQ + && real_equal (&lh_lb, &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; + // 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) + { + // [+-0, +-0] * [+INF,+INF] (or [-INF,-INF] or swapped is a known NAN. + 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; + return; + } - find_range (lb, ub, cp); - } -} fop_mult; + // Otherwise, if one range includes zero and the other ends with +-INF, + // it is a maybe NAN. + if ((contains_zero_p (lh_lb, lh_ub) + && (real_isinf (&rh_lb) || real_isinf (&rh_ub))) + || (contains_zero_p (rh_lb, rh_ub) + && (real_isinf (&lh_lb) || real_isinf (&lh_ub)))) + { + maybe_nan = true; + + int signbit_known = signbit_known_p (lh_lb, lh_ub, rh_lb, rh_ub); + + // If one of the ranges that includes INF is singleton + // and the other range includes zero, the resulting + // range is INF and NAN, because the 0 * INF boundary + // case will be NAN, but already nextafter (0, 1) * INF + // is INF. + if (singleton_inf_p (lh_lb, lh_ub) + || singleton_inf_p (rh_lb, rh_ub)) + return inf_range (lb, ub, signbit_known); + + // If one of the multiplicands must be zero, the resulting + // range is +-0 and NAN. + if (zero_p (lh_lb, lh_ub) || zero_p (rh_lb, rh_ub)) + return zero_range (lb, ub, signbit_known); + + // Otherwise one of the multiplicands could be + // [0.0, nextafter (0.0, 1.0)] and the [DBL_MAX, INF] + // or similarly with different signs. 0.0 * DBL_MAX + // is still 0.0, nextafter (0.0, 1.0) * INF is still INF, + // so if the signs are always the same or always different, + // result is [+0.0, +INF] or [-INF, -0.0], otherwise VARYING. + return zero_to_inf_range (lb, ub, signbit_known); + } + } + REAL_VALUE_TYPE cp[8]; + // Do a cross-product. At this point none of the multiplications + // should produce a NAN. + frange_arithmetic (MULT_EXPR, type, cp[0], lh_lb, rh_lb, dconstninf); + frange_arithmetic (MULT_EXPR, type, cp[4], lh_lb, rh_lb, dconstinf); + if (is_square) + { + // For x * x we can just do max (lh_lb * lh_lb, lh_ub * lh_ub) + // as maximum and -0.0 as minimum if 0.0 is in the range, + // otherwise min (lh_lb * lh_lb, lh_ub * lh_ub). + // -0.0 rather than 0.0 because VREL_EQ doesn't prove that + // x and y are bitwise equal, just that they compare equal. + if (contains_zero_p (lh_lb, lh_ub)) + { + if (real_isneg (&lh_lb) == real_isneg (&lh_ub)) + cp[1] = dconst0; + else + cp[1] = dconstm0; + } + else + cp[1] = cp[0]; + cp[2] = cp[0]; + cp[5] = cp[4]; + cp[6] = cp[4]; + } + else + { + frange_arithmetic (MULT_EXPR, type, cp[1], lh_lb, rh_ub, dconstninf); + frange_arithmetic (MULT_EXPR, type, cp[5], lh_lb, rh_ub, dconstinf); + frange_arithmetic (MULT_EXPR, type, cp[2], lh_ub, rh_lb, dconstninf); + frange_arithmetic (MULT_EXPR, type, cp[6], lh_ub, rh_lb, dconstinf); + } + frange_arithmetic (MULT_EXPR, type, cp[3], lh_ub, rh_ub, dconstninf); + frange_arithmetic (MULT_EXPR, type, cp[7], lh_ub, rh_ub, dconstinf); -class foperator_div : public foperator_mult_div_base + find_range (lb, ub, cp); +} + + +class foperator_div : public range_operator { using range_operator::op1_range; using range_operator::op2_range; @@ -2525,7 +2519,7 @@ public: if (lhs.undefined_p ()) return false; frange wlhs = float_widen_lhs_range (type, lhs); - bool ret = fop_mult.fold_range (r, type, wlhs, op2); + bool ret = range_op_handler (MULT_EXPR).fold_range (r, type, wlhs, op2); if (!ret) return ret; if (wlhs.known_isnan () || op2.known_isnan () || op2.undefined_p ()) @@ -2669,12 +2663,7 @@ private: } fop_div; -float_table::float_table () -{ - set (MULT_EXPR, fop_mult); -} - -// Initialize any pointer operators to the primary table +// Initialize any float operators to the primary table void range_op_table::initialize_float_ops () diff --git a/gcc/range-op-mixed.h b/gcc/range-op-mixed.h index 598825af919..52b8570cb2a 100644 --- a/gcc/range-op-mixed.h +++ b/gcc/range-op-mixed.h @@ -450,4 +450,55 @@ class operator_negate : public range_operator const frange &lhs, const frange &op2, relation_trio rel = TRIO_VARYING) const final override; }; + + +class cross_product_operator : public range_operator +{ +public: + virtual bool wi_op_overflows (wide_int &r, + tree type, + const wide_int &, + const wide_int &) const = 0; + void wi_cross_product (irange &r, tree type, + const wide_int &lh_lb, + const wide_int &lh_ub, + const wide_int &rh_lb, + const wide_int &rh_ub) const; +}; + +class operator_mult : public cross_product_operator +{ +public: + using range_operator::op1_range; + using range_operator::op2_range; + bool op1_range (irange &r, tree type, + const irange &lhs, const irange &op2, + relation_trio) const final override; + bool op1_range (frange &r, tree type, + const frange &lhs, const frange &op2, + relation_trio = TRIO_VARYING) const final override; + + bool op2_range (irange &r, tree type, + const irange &lhs, const irange &op1, + relation_trio) const final override; + bool op2_range (frange &r, tree type, + const frange &lhs, const frange &op1, + relation_trio = TRIO_VARYING) const final override; + + void update_bitmask (irange &r, const irange &lh, + const irange &rh) const final override; + + void wi_fold (irange &r, tree type, const wide_int &lh_lb, + const wide_int &lh_ub, const wide_int &rh_lb, + const wide_int &rh_ub) const final override; + bool wi_op_overflows (wide_int &res, tree type, const wide_int &w0, + const wide_int &w1) const final override; + + void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, + bool &maybe_nan, tree type, + 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; +}; + #endif // GCC_RANGE_OP_MIXED_H diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 539036d4cfa..028631c6851 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -51,7 +51,6 @@ along with GCC; see the file COPYING3. If not see integral_table integral_tree_table; pointer_table pointer_tree_table; -float_table float_tree_table; // Instantiate a range_op_table for unified operations. class unified_table : public range_op_table @@ -75,6 +74,7 @@ operator_plus op_plus; operator_abs op_abs; operator_minus op_minus; operator_negate op_negate; +operator_mult op_mult; // Invoke the initialization routines for each class of range. @@ -101,6 +101,7 @@ unified_table::unified_table () set (ABS_EXPR, op_abs); set (MINUS_EXPR, op_minus); set (NEGATE_EXPR, op_negate); + set (MULT_EXPR, op_mult); } // The tables are hidden and accessed via a simple extern function. @@ -113,7 +114,6 @@ get_op_handler (enum tree_code code, tree type) // Should not be in any other table if it is in the unified table. gcc_checking_assert (!pointer_tree_table[code]); gcc_checking_assert (!integral_tree_table[code]); - gcc_checking_assert (!float_tree_table[code]); return unified_tree_table[code]; } @@ -121,8 +121,6 @@ get_op_handler (enum tree_code code, tree type) return pointer_tree_table[code]; if (INTEGRAL_TYPE_P (type)) return integral_tree_table[code]; - if (frange::supports_p (type)) - return float_tree_table[code]; return NULL; } @@ -2012,24 +2010,6 @@ operator_max::wi_fold (irange &r, tree type, } -class cross_product_operator : public range_operator -{ -public: - // Perform an operation between two wide-ints and place the result - // in R. Return true if the operation overflowed. - virtual bool wi_op_overflows (wide_int &r, - tree type, - const wide_int &, - const wide_int &) const = 0; - - // Calculate the cross product of two sets of sub-ranges and return it. - void wi_cross_product (irange &r, tree type, - const wide_int &lh_lb, - const wide_int &lh_ub, - const wide_int &rh_lb, - const wide_int &rh_ub) const; -}; - // Calculate the cross product of two sets of ranges and return it. // // Multiplications, divisions and shifts are a bit tricky to handle, @@ -2085,30 +2065,12 @@ cross_product_operator::wi_cross_product (irange &r, tree type, } -class operator_mult : public cross_product_operator +void +operator_mult::update_bitmask (irange &r, const irange &lh, + const irange &rh) const { - using range_operator::op1_range; - using range_operator::op2_range; -public: - virtual void wi_fold (irange &r, tree type, - const wide_int &lh_lb, - const wide_int &lh_ub, - const wide_int &rh_lb, - const wide_int &rh_ub) const final override; - virtual bool wi_op_overflows (wide_int &res, tree type, - const wide_int &w0, const wide_int &w1) - const final override; - virtual bool op1_range (irange &r, tree type, - const irange &lhs, - const irange &op2, - relation_trio) const final override; - virtual bool op2_range (irange &r, tree type, - const irange &lhs, - const irange &op1, - relation_trio) const final override; - void update_bitmask (irange &r, const irange &lh, const irange &rh) const - { update_known_bitmask (r, MULT_EXPR, lh, rh); } -} op_mult; + update_known_bitmask (r, MULT_EXPR, lh, rh); +} bool operator_mult::op1_range (irange &r, tree type, @@ -4647,7 +4609,6 @@ integral_table::integral_table () { set (MIN_EXPR, op_min); set (MAX_EXPR, op_max); - set (MULT_EXPR, op_mult); set (BIT_AND_EXPR, op_bitwise_and); set (BIT_IOR_EXPR, op_bitwise_or); set (BIT_XOR_EXPR, op_bitwise_xor); diff --git a/gcc/range-op.h b/gcc/range-op.h index 20a77e1165e..0f5ee41f96c 100644 --- a/gcc/range-op.h +++ b/gcc/range-op.h @@ -317,16 +317,6 @@ public: }; extern pointer_table pointer_tree_table; -// Instantiate a range_op_table for floating point operations. -class float_table : public range_op_table -{ - public: - float_table (); -}; -extern float_table float_tree_table; - - - extern range_operator *ptr_op_widen_mult_signed; extern range_operator *ptr_op_widen_mult_unsigned; extern range_operator *ptr_op_widen_plus_signed;