Skip to content

Commit

Permalink
Use range_compatible_p in check_operands_p.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
andrewwmacleod authored and Liaoshihua committed Mar 19, 2024
1 parent 4c1c14d commit e6e7b39
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 45 deletions.
12 changes: 0 additions & 12 deletions gcc/gimple-range-fold.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
43 changes: 17 additions & 26 deletions gcc/range-op-mixed.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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); }
};


Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down
12 changes: 5 additions & 7 deletions gcc/range-op.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;


Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
11 changes: 11 additions & 0 deletions gcc/value-range.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit e6e7b39

Please sign in to comment.