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:
Andrew MacLeod
2023-12-01 11:15:33 -05:00
parent b8edb812ff
commit c6bb413eeb
4 changed files with 33 additions and 45 deletions

View File

@@ -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.

View File

@@ -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,

View File

@@ -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

View File

@@ -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