From c6bb413eeb9d13412e8101e3029099d7fd746708 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacleod@redhat.com>
Date: Fri, 1 Dec 2023 11:15:33 -0500
Subject: [PATCH] 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.
---
gcc/gimple-range-fold.h | 12 ------------
gcc/range-op-mixed.h | 43 ++++++++++++++++-------------------------
gcc/range-op.cc | 12 +++++-------
gcc/value-range.h | 11 +++++++++++
4 files changed, 33 insertions(+), 45 deletions(-)
@@ -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
--
2.41.0