mirror of
https://gcc.gnu.org/git/gcc.git
synced 2026-02-22 03:46:53 -05:00
Use range_compatible_p in check_operands_p.
Instead of directly checking type precision, check_operands_p should invoke range_compatible_p to keep the range checking centralized. * gimple-range-fold.h (range_compatible_p): Relocate. * value-range.h (range_compatible_p): Here. * range-op-mixed.h (operand_equal::operand_check_p): Call range_compatible_p rather than comparing precision. (operand_not_equal::operand_check_p): Ditto. (operand_not_lt::operand_check_p): Ditto. (operand_not_le::operand_check_p): Ditto. (operand_not_gt::operand_check_p): Ditto. (operand_not_ge::operand_check_p): Ditto. (operand_plus::operand_check_p): Ditto. (operand_abs::operand_check_p): Ditto. (operand_minus::operand_check_p): Ditto. (operand_negate::operand_check_p): Ditto. (operand_mult::operand_check_p): Ditto. (operand_bitwise_not::operand_check_p): Ditto. (operand_bitwise_xor::operand_check_p): Ditto. (operand_bitwise_and::operand_check_p): Ditto. (operand_bitwise_or::operand_check_p): Ditto. (operand_min::operand_check_p): Ditto. (operand_max::operand_check_p): Ditto. * range-op.cc (operand_lshift::operand_check_p): Ditto. (operand_rshift::operand_check_p): Ditto. (operand_logical_and::operand_check_p): Ditto. (operand_logical_or::operand_check_p): Ditto. (operand_logical_not::operand_check_p): Ditto.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -140,7 +140,7 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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,
|
||||
|
||||
@@ -2493,7 +2493,7 @@ public:
|
||||
{ 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 @@ public:
|
||||
{ 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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user