diff --git a/gcc/gimple-range-fold.h b/gcc/gimple-range-fold.h index fcbe1626790..0094b4e3f35 100644 --- a/gcc/gimple-range-fold.h +++ b/gcc/gimple-range-fold.h @@ -89,18 +89,6 @@ gimple_range_ssa_p (tree exp) return NULL_TREE; } -// Return true if TYPE1 and TYPE2 are compatible range types. - -inline bool -range_compatible_p (tree type1, tree type2) -{ - // types_compatible_p requires conversion in both directions to be useless. - // GIMPLE only requires a cast one way in order to be compatible. - // Ranges really only need the sign and precision to be the same. - return (TYPE_PRECISION (type1) == TYPE_PRECISION (type2) - && TYPE_SIGN (type1) == TYPE_SIGN (type2)); -} - // Source of all operands for fold_using_range and gori_compute. // It abstracts out the source of an operand so it can come from a stmt or // and edge or anywhere a derived class of fur_source wants. diff --git a/gcc/range-op-mixed.h b/gcc/range-op-mixed.h index 4386a68e946..7e3ee17ccbd 100644 --- a/gcc/range-op-mixed.h +++ b/gcc/range-op-mixed.h @@ -140,7 +140,7 @@ class operator_equal : public range_operator const irange &rh) const final override; // Check op1 and op2 for compatibility. bool operand_check_p (tree, tree t1, tree t2) const final override - { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } + { return range_compatible_p (t1, t2); } }; class operator_not_equal : public range_operator @@ -179,7 +179,7 @@ class operator_not_equal : public range_operator const irange &rh) const final override; // Check op1 and op2 for compatibility. bool operand_check_p (tree, tree t1, tree t2) const final override - { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } + { return range_compatible_p (t1, t2); } }; class operator_lt : public range_operator @@ -215,7 +215,7 @@ class operator_lt : public range_operator const irange &rh) const final override; // Check op1 and op2 for compatibility. bool operand_check_p (tree, tree t1, tree t2) const final override - { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } + { return range_compatible_p (t1, t2); } }; class operator_le : public range_operator @@ -254,7 +254,7 @@ class operator_le : public range_operator const irange &rh) const final override; // Check op1 and op2 for compatibility. bool operand_check_p (tree, tree t1, tree t2) const final override - { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } + { return range_compatible_p (t1, t2); } }; class operator_gt : public range_operator @@ -292,7 +292,7 @@ class operator_gt : public range_operator const irange &rh) const final override; // Check op1 and op2 for compatibility. bool operand_check_p (tree, tree t1, tree t2) const final override - { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } + { return range_compatible_p (t1, t2); } }; class operator_ge : public range_operator @@ -331,7 +331,7 @@ class operator_ge : public range_operator const irange &rh) const final override; // Check op1 and op2 for compatibility. bool operand_check_p (tree, tree t1, tree t2) const final override - { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } + { return range_compatible_p (t1, t2); } }; class operator_identity : public range_operator @@ -429,8 +429,7 @@ class operator_plus : public range_operator relation_trio = TRIO_VARYING) const; // Check compatibility of all operands. bool operand_check_p (tree t1, tree t2, tree t3) const final override - { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) - && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } + { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); } private: void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, const wide_int &rh_lb, @@ -459,7 +458,7 @@ class operator_abs : public range_operator const irange &rh) const final override; // Check compatibility of LHS and op1. bool operand_check_p (tree t1, tree t2, tree) const final override - { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } + { return range_compatible_p (t1, t2); } private: void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, const wide_int &rh_lb, @@ -503,8 +502,7 @@ class operator_minus : public range_operator relation_trio = TRIO_VARYING) const; // Check compatibility of all operands. bool operand_check_p (tree t1, tree t2, tree t3) const final override - { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) - && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } + { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); } private: void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, const wide_int &rh_lb, @@ -535,7 +533,7 @@ class operator_negate : public range_operator relation_trio rel = TRIO_VARYING) const final override; // Check compatibility of LHS and op1. bool operand_check_p (tree t1, tree t2, tree) const final override - { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } + { return range_compatible_p (t1, t2); } }; @@ -589,8 +587,7 @@ class operator_mult : public cross_product_operator relation_trio = TRIO_VARYING) const; // Check compatibility of all operands. bool operand_check_p (tree t1, tree t2, tree t3) const final override - { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) - && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } + { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); } }; class operator_addr_expr : public range_operator @@ -621,8 +618,7 @@ class operator_bitwise_not : public range_operator const irange &rh) const final override; // Check compatibility of all operands. bool operand_check_p (tree t1, tree t2, tree t3) const final override - { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) - && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } + { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); } }; class operator_bitwise_xor : public range_operator @@ -645,8 +641,7 @@ class operator_bitwise_xor : public range_operator const irange &rh) const final override; // Check compatibility of all operands. bool operand_check_p (tree t1, tree t2, tree t3) const final override - { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) - && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } + { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); } private: void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, const wide_int &rh_lb, @@ -672,8 +667,7 @@ class operator_bitwise_and : public range_operator const irange &rh) const override; // Check compatibility of all operands. bool operand_check_p (tree t1, tree t2, tree t3) const final override - { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) - && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } + { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); } protected: void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, const wide_int &rh_lb, @@ -698,8 +692,7 @@ class operator_bitwise_or : public range_operator const irange &rh) const override; // Check compatibility of all operands. bool operand_check_p (tree t1, tree t2, tree t3) const final override - { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) - && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } + { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); } protected: void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, const wide_int &rh_lb, @@ -713,8 +706,7 @@ class operator_min : public range_operator const irange &rh) const override; // Check compatibility of all operands. bool operand_check_p (tree t1, tree t2, tree t3) const final override - { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) - && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } + { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); } protected: void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, const wide_int &rh_lb, @@ -728,8 +720,7 @@ class operator_max : public range_operator const irange &rh) const override; // Check compatibility of all operands. bool operand_check_p (tree t1, tree t2, tree t3) const final override - { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) - && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } + { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); } protected: void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, const wide_int &rh_lb, diff --git a/gcc/range-op.cc b/gcc/range-op.cc index a091815997d..5dbc4bbb42e 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -2493,7 +2493,7 @@ class operator_lshift : public cross_product_operator { update_known_bitmask (r, LSHIFT_EXPR, lh, rh); } // Check compatibility of LHS and op1. bool operand_check_p (tree t1, tree t2, tree) const final override - { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } + { return range_compatible_p (t1, t2); } } op_lshift; class operator_rshift : public cross_product_operator @@ -2525,7 +2525,7 @@ class operator_rshift : public cross_product_operator { update_known_bitmask (r, RSHIFT_EXPR, lh, rh); } // Check compatibility of LHS and op1. bool operand_check_p (tree t1, tree t2, tree) const final override - { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } + { return range_compatible_p (t1, t2); } } op_rshift; @@ -3103,8 +3103,7 @@ class operator_logical_and : public range_operator relation_trio rel = TRIO_VARYING) const; // Check compatibility of all operands. bool operand_check_p (tree t1, tree t2, tree t3) const final override - { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) - && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } + { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); } } op_logical_and; bool @@ -3608,8 +3607,7 @@ class operator_logical_or : public range_operator relation_trio rel = TRIO_VARYING) const; // Check compatibility of all operands. bool operand_check_p (tree t1, tree t2, tree t3) const final override - { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) - && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } + { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); } } op_logical_or; bool @@ -4038,7 +4036,7 @@ class operator_logical_not : public range_operator relation_trio rel = TRIO_VARYING) const; // Check compatibility of LHS and op1. bool operand_check_p (tree t1, tree t2, tree) const final override - { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } + { return range_compatible_p (t1, t2); } } op_logical_not; // Folding a logical NOT, oddly enough, involves doing nothing on the diff --git a/gcc/value-range.h b/gcc/value-range.h index 330e6f70c6b..33f204a7171 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -1550,4 +1550,15 @@ void frange_arithmetic (enum tree_code, tree, REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &); +// Return true if TYPE1 and TYPE2 are compatible range types. + +inline bool +range_compatible_p (tree type1, tree type2) +{ + // types_compatible_p requires conversion in both directions to be useless. + // GIMPLE only requires a cast one way in order to be compatible. + // Ranges really only need the sign and precision to be the same. + return (TYPE_PRECISION (type1) == TYPE_PRECISION (type2) + && TYPE_SIGN (type1) == TYPE_SIGN (type2)); +} #endif // GCC_VALUE_RANGE_H