Change fold_range to return a boolean result.
2019-11-14 Andrew MacLeod <amacleod@redhat.com> * range-op.h (range_operator::fold_range): Return a bool. * range-op.cc (range_operator::wi_fold): Assert supported type. (range_operator::fold_range): Assert supported type and return true. (operator_equal::fold_range): Return true. (operator_not_equal::fold_range): Same. (operator_lt::fold_range): Same. (operator_le::fold_range): Same. (operator_gt::fold_range): Same. (operator_ge::fold_range): Same. (operator_plus::op1_range): Adjust call to fold_range. (operator_plus::op2_range): Same. (operator_minus::op1_range): Same. (operator_minus::op2_range): Same. (operator_exact_divide::op1_range): Same. (operator_lshift::fold_range): Return true and adjust fold_range call. (operator_rshift::fold_range): Same. (operator_cast::fold_range): Return true. (operator_logical_and::fold_range): Same. (operator_logical_or::fold_range): Same. (operator_logical_not::fold_range): Same. (operator_bitwise_not::fold_range): Adjust call to fold_range. (operator_bitwise_not::op1_range): Same. (operator_cst::fold_range): Return true. (operator_identity::fold_range): Return true. (operator_negate::fold_range): Return true and adjust fold_range call. (operator_addr_expr::fold_range): Return true. (operator_addr_expr::op1_range): Adjust call to fold_range. (range_cast): Same. * tree-vrp.c (range_fold_binary_symbolics_p): Adjust call to fold_range. (range_fold_unary_symbolics_p): Same. From-SVN: r278266
This commit is contained in:
parent
7c5890cc0a
commit
f674b4a72a
@ -1,3 +1,36 @@
|
||||
2019-11-14 Andrew MacLeod <amacleod@redhat.com>
|
||||
|
||||
* range-op.h (range_operator::fold_range): Return a bool.
|
||||
* range-op.cc (range_operator::wi_fold): Assert supported type.
|
||||
(range_operator::fold_range): Assert supported type and return true.
|
||||
(operator_equal::fold_range): Return true.
|
||||
(operator_not_equal::fold_range): Same.
|
||||
(operator_lt::fold_range): Same.
|
||||
(operator_le::fold_range): Same.
|
||||
(operator_gt::fold_range): Same.
|
||||
(operator_ge::fold_range): Same.
|
||||
(operator_plus::op1_range): Adjust call to fold_range.
|
||||
(operator_plus::op2_range): Same.
|
||||
(operator_minus::op1_range): Same.
|
||||
(operator_minus::op2_range): Same.
|
||||
(operator_exact_divide::op1_range): Same.
|
||||
(operator_lshift::fold_range): Return true and adjust fold_range call.
|
||||
(operator_rshift::fold_range): Same.
|
||||
(operator_cast::fold_range): Return true.
|
||||
(operator_logical_and::fold_range): Same.
|
||||
(operator_logical_or::fold_range): Same.
|
||||
(operator_logical_not::fold_range): Same.
|
||||
(operator_bitwise_not::fold_range): Adjust call to fold_range.
|
||||
(operator_bitwise_not::op1_range): Same.
|
||||
(operator_cst::fold_range): Return true.
|
||||
(operator_identity::fold_range): Return true.
|
||||
(operator_negate::fold_range): Return true and adjust fold_range call.
|
||||
(operator_addr_expr::fold_range): Return true.
|
||||
(operator_addr_expr::op1_range): Adjust call to fold_range.
|
||||
(range_cast): Same.
|
||||
* tree-vrp.c (range_fold_binary_symbolics_p): Adjust call to fold_range.
|
||||
(range_fold_unary_symbolics_p): Same.
|
||||
|
||||
2019-11-14 Andrew MacLeod <amacleod@redhat.com>
|
||||
|
||||
PR tree-optimization/92506
|
||||
|
177
gcc/range-op.cc
177
gcc/range-op.cc
@ -131,19 +131,21 @@ range_operator::wi_fold (value_range &r, tree type,
|
||||
const wide_int &rh_lb ATTRIBUTE_UNUSED,
|
||||
const wide_int &rh_ub ATTRIBUTE_UNUSED) const
|
||||
{
|
||||
gcc_checking_assert (value_range::supports_type_p (type));
|
||||
r = value_range (type);
|
||||
}
|
||||
|
||||
// The default for fold is to break all ranges into sub-ranges and
|
||||
// invoke the wi_fold method on each sub-range pair.
|
||||
|
||||
void
|
||||
bool
|
||||
range_operator::fold_range (value_range &r, tree type,
|
||||
const value_range &lh,
|
||||
const value_range &rh) const
|
||||
{
|
||||
gcc_checking_assert (value_range::supports_type_p (type));
|
||||
if (empty_range_check (r, lh, rh))
|
||||
return;
|
||||
return true;
|
||||
|
||||
value_range tmp;
|
||||
r.set_undefined ();
|
||||
@ -157,8 +159,9 @@ range_operator::fold_range (value_range &r, tree type,
|
||||
wi_fold (tmp, type, lh_lb, lh_ub, rh_lb, rh_ub);
|
||||
r.union_ (tmp);
|
||||
if (r.varying_p ())
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// The default for op1_range is to return false.
|
||||
@ -364,7 +367,7 @@ get_bool_state (value_range &r, const value_range &lhs, tree val_type)
|
||||
class operator_equal : public range_operator
|
||||
{
|
||||
public:
|
||||
virtual void fold_range (value_range &r, tree type,
|
||||
virtual bool fold_range (value_range &r, tree type,
|
||||
const value_range &op1,
|
||||
const value_range &op2) const;
|
||||
virtual bool op1_range (value_range &r, tree type,
|
||||
@ -375,13 +378,13 @@ public:
|
||||
const value_range &val) const;
|
||||
} op_equal;
|
||||
|
||||
void
|
||||
bool
|
||||
operator_equal::fold_range (value_range &r, tree type,
|
||||
const value_range &op1,
|
||||
const value_range &op2) const
|
||||
{
|
||||
if (empty_range_check (r, op1, op2))
|
||||
return;
|
||||
return true;
|
||||
|
||||
// We can be sure the values are always equal or not if both ranges
|
||||
// consist of a single value, and then compare them.
|
||||
@ -404,6 +407,7 @@ operator_equal::fold_range (value_range &r, tree type,
|
||||
else
|
||||
r = range_true_and_false (type);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -448,7 +452,7 @@ operator_equal::op2_range (value_range &r, tree type,
|
||||
class operator_not_equal : public range_operator
|
||||
{
|
||||
public:
|
||||
virtual void fold_range (value_range &r, tree type,
|
||||
virtual bool fold_range (value_range &r, tree type,
|
||||
const value_range &op1,
|
||||
const value_range &op2) const;
|
||||
virtual bool op1_range (value_range &r, tree type,
|
||||
@ -459,13 +463,13 @@ public:
|
||||
const value_range &op1) const;
|
||||
} op_not_equal;
|
||||
|
||||
void
|
||||
bool
|
||||
operator_not_equal::fold_range (value_range &r, tree type,
|
||||
const value_range &op1,
|
||||
const value_range &op2) const
|
||||
{
|
||||
if (empty_range_check (r, op1, op2))
|
||||
return;
|
||||
return true;
|
||||
|
||||
// We can be sure the values are always equal or not if both ranges
|
||||
// consist of a single value, and then compare them.
|
||||
@ -488,6 +492,7 @@ operator_not_equal::fold_range (value_range &r, tree type,
|
||||
else
|
||||
r = range_true_and_false (type);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -578,7 +583,7 @@ build_ge (value_range &r, tree type, const wide_int &val)
|
||||
class operator_lt : public range_operator
|
||||
{
|
||||
public:
|
||||
virtual void fold_range (value_range &r, tree type,
|
||||
virtual bool fold_range (value_range &r, tree type,
|
||||
const value_range &op1,
|
||||
const value_range &op2) const;
|
||||
virtual bool op1_range (value_range &r, tree type,
|
||||
@ -589,13 +594,13 @@ public:
|
||||
const value_range &op1) const;
|
||||
} op_lt;
|
||||
|
||||
void
|
||||
bool
|
||||
operator_lt::fold_range (value_range &r, tree type,
|
||||
const value_range &op1,
|
||||
const value_range &op2) const
|
||||
{
|
||||
if (empty_range_check (r, op1, op2))
|
||||
return;
|
||||
return true;
|
||||
|
||||
signop sign = TYPE_SIGN (op1.type ());
|
||||
gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
|
||||
@ -606,6 +611,7 @@ operator_lt::fold_range (value_range &r, tree type,
|
||||
r = range_false (type);
|
||||
else
|
||||
r = range_true_and_false (type);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -654,7 +660,7 @@ operator_lt::op2_range (value_range &r, tree type,
|
||||
class operator_le : public range_operator
|
||||
{
|
||||
public:
|
||||
virtual void fold_range (value_range &r, tree type,
|
||||
virtual bool fold_range (value_range &r, tree type,
|
||||
const value_range &op1,
|
||||
const value_range &op2) const;
|
||||
virtual bool op1_range (value_range &r, tree type,
|
||||
@ -665,13 +671,13 @@ public:
|
||||
const value_range &op1) const;
|
||||
} op_le;
|
||||
|
||||
void
|
||||
bool
|
||||
operator_le::fold_range (value_range &r, tree type,
|
||||
const value_range &op1,
|
||||
const value_range &op2) const
|
||||
{
|
||||
if (empty_range_check (r, op1, op2))
|
||||
return;
|
||||
return true;
|
||||
|
||||
signop sign = TYPE_SIGN (op1.type ());
|
||||
gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
|
||||
@ -682,6 +688,7 @@ operator_le::fold_range (value_range &r, tree type,
|
||||
r = range_false (type);
|
||||
else
|
||||
r = range_true_and_false (type);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -730,7 +737,7 @@ operator_le::op2_range (value_range &r, tree type,
|
||||
class operator_gt : public range_operator
|
||||
{
|
||||
public:
|
||||
virtual void fold_range (value_range &r, tree type,
|
||||
virtual bool fold_range (value_range &r, tree type,
|
||||
const value_range &op1,
|
||||
const value_range &op2) const;
|
||||
virtual bool op1_range (value_range &r, tree type,
|
||||
@ -741,12 +748,12 @@ public:
|
||||
const value_range &op1) const;
|
||||
} op_gt;
|
||||
|
||||
void
|
||||
bool
|
||||
operator_gt::fold_range (value_range &r, tree type,
|
||||
const value_range &op1, const value_range &op2) const
|
||||
{
|
||||
if (empty_range_check (r, op1, op2))
|
||||
return;
|
||||
return true;
|
||||
|
||||
signop sign = TYPE_SIGN (op1.type ());
|
||||
gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
|
||||
@ -757,6 +764,7 @@ operator_gt::fold_range (value_range &r, tree type,
|
||||
r = range_false (type);
|
||||
else
|
||||
r = range_true_and_false (type);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -804,7 +812,7 @@ operator_gt::op2_range (value_range &r, tree type,
|
||||
class operator_ge : public range_operator
|
||||
{
|
||||
public:
|
||||
virtual void fold_range (value_range &r, tree type,
|
||||
virtual bool fold_range (value_range &r, tree type,
|
||||
const value_range &op1,
|
||||
const value_range &op2) const;
|
||||
virtual bool op1_range (value_range &r, tree type,
|
||||
@ -815,13 +823,13 @@ public:
|
||||
const value_range &op1) const;
|
||||
} op_ge;
|
||||
|
||||
void
|
||||
bool
|
||||
operator_ge::fold_range (value_range &r, tree type,
|
||||
const value_range &op1,
|
||||
const value_range &op2) const
|
||||
{
|
||||
if (empty_range_check (r, op1, op2))
|
||||
return;
|
||||
return true;
|
||||
|
||||
signop sign = TYPE_SIGN (op1.type ());
|
||||
gcc_checking_assert (sign == TYPE_SIGN (op2.type ()));
|
||||
@ -832,6 +840,7 @@ operator_ge::fold_range (value_range &r, tree type,
|
||||
r = range_false (type);
|
||||
else
|
||||
r = range_true_and_false (type);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -910,8 +919,7 @@ operator_plus::op1_range (value_range &r, tree type,
|
||||
const value_range &lhs,
|
||||
const value_range &op2) const
|
||||
{
|
||||
range_op_handler (MINUS_EXPR, type)->fold_range (r, type, lhs, op2);
|
||||
return true;
|
||||
return range_op_handler (MINUS_EXPR, type)->fold_range (r, type, lhs, op2);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -919,8 +927,7 @@ operator_plus::op2_range (value_range &r, tree type,
|
||||
const value_range &lhs,
|
||||
const value_range &op1) const
|
||||
{
|
||||
range_op_handler (MINUS_EXPR, type)->fold_range (r, type, lhs, op1);
|
||||
return true;
|
||||
return range_op_handler (MINUS_EXPR, type)->fold_range (r, type, lhs, op1);
|
||||
}
|
||||
|
||||
|
||||
@ -957,8 +964,7 @@ operator_minus::op1_range (value_range &r, tree type,
|
||||
const value_range &lhs,
|
||||
const value_range &op2) const
|
||||
{
|
||||
range_op_handler (PLUS_EXPR, type)->fold_range (r, type, lhs, op2);
|
||||
return true;
|
||||
return range_op_handler (PLUS_EXPR, type)->fold_range (r, type, lhs, op2);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -966,8 +972,7 @@ operator_minus::op2_range (value_range &r, tree type,
|
||||
const value_range &lhs,
|
||||
const value_range &op1) const
|
||||
{
|
||||
fold_range (r, type, op1, lhs);
|
||||
return true;
|
||||
return fold_range (r, type, op1, lhs);
|
||||
}
|
||||
|
||||
|
||||
@ -1351,10 +1356,7 @@ operator_exact_divide::op1_range (value_range &r, tree type,
|
||||
// If op2 is a multiple of 2, we would be able to set some non-zero bits.
|
||||
if (op2.singleton_p (&offset)
|
||||
&& !integer_zerop (offset))
|
||||
{
|
||||
range_op_handler (MULT_EXPR, type)->fold_range (r, type, lhs, op2);
|
||||
return true;
|
||||
}
|
||||
return range_op_handler (MULT_EXPR, type)->fold_range (r, type, lhs, op2);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1362,7 +1364,7 @@ operator_exact_divide::op1_range (value_range &r, tree type,
|
||||
class operator_lshift : public cross_product_operator
|
||||
{
|
||||
public:
|
||||
virtual void fold_range (value_range &r, tree type,
|
||||
virtual bool fold_range (value_range &r, tree type,
|
||||
const value_range &op1,
|
||||
const value_range &op2) const;
|
||||
|
||||
@ -1375,13 +1377,13 @@ public:
|
||||
const wide_int &) const;
|
||||
} op_lshift;
|
||||
|
||||
void
|
||||
bool
|
||||
operator_lshift::fold_range (value_range &r, tree type,
|
||||
const value_range &op1,
|
||||
const value_range &op2) const
|
||||
{
|
||||
if (undefined_shift_range_check (r, type, op2))
|
||||
return;
|
||||
return true;
|
||||
|
||||
// Transform left shifts by constants into multiplies.
|
||||
if (op2.singleton_p ())
|
||||
@ -1395,14 +1397,15 @@ operator_lshift::fold_range (value_range &r, tree type,
|
||||
bool saved_flag_wrapv_pointer = flag_wrapv_pointer;
|
||||
flag_wrapv = 1;
|
||||
flag_wrapv_pointer = 1;
|
||||
range_op_handler (MULT_EXPR, type)->fold_range (r, type, op1, mult);
|
||||
bool b = range_op_handler (MULT_EXPR, type)->fold_range (r, type, op1,
|
||||
mult);
|
||||
flag_wrapv = saved_flag_wrapv;
|
||||
flag_wrapv_pointer = saved_flag_wrapv_pointer;
|
||||
return;
|
||||
return b;
|
||||
}
|
||||
|
||||
// Otherwise, invoke the generic fold routine.
|
||||
range_operator::fold_range (r, type, op1, op2);
|
||||
else
|
||||
// Otherwise, invoke the generic fold routine.
|
||||
return range_operator::fold_range (r, type, op1, op2);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1486,7 +1489,7 @@ operator_lshift::wi_op_overflows (wide_int &res, tree type,
|
||||
class operator_rshift : public cross_product_operator
|
||||
{
|
||||
public:
|
||||
virtual void fold_range (value_range &r, tree type,
|
||||
virtual bool fold_range (value_range &r, tree type,
|
||||
const value_range &op1,
|
||||
const value_range &op2) const;
|
||||
virtual void wi_fold (value_range &r, tree type,
|
||||
@ -1519,16 +1522,16 @@ operator_rshift::wi_op_overflows (wide_int &res,
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
operator_rshift::fold_range (value_range &r, tree type,
|
||||
const value_range &op1,
|
||||
const value_range &op2) const
|
||||
{
|
||||
// Invoke the generic fold routine if not undefined..
|
||||
if (undefined_shift_range_check (r, type, op2))
|
||||
return;
|
||||
return true;
|
||||
|
||||
// Otherwise, invoke the generic fold routine.
|
||||
range_operator::fold_range (r, type, op1, op2);
|
||||
return range_operator::fold_range (r, type, op1, op2);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1543,7 +1546,7 @@ operator_rshift::wi_fold (value_range &r, tree type,
|
||||
class operator_cast: public range_operator
|
||||
{
|
||||
public:
|
||||
virtual void fold_range (value_range &r, tree type,
|
||||
virtual bool fold_range (value_range &r, tree type,
|
||||
const value_range &op1,
|
||||
const value_range &op2) const;
|
||||
virtual bool op1_range (value_range &r, tree type,
|
||||
@ -1552,13 +1555,13 @@ public:
|
||||
|
||||
} op_convert;
|
||||
|
||||
void
|
||||
bool
|
||||
operator_cast::fold_range (value_range &r, tree type ATTRIBUTE_UNUSED,
|
||||
const value_range &lh,
|
||||
const value_range &rh) const
|
||||
{
|
||||
if (empty_range_check (r, lh, rh))
|
||||
return;
|
||||
return true;
|
||||
|
||||
tree inner = lh.type ();
|
||||
tree outer = rh.type ();
|
||||
@ -1598,8 +1601,9 @@ operator_cast::fold_range (value_range &r, tree type ATTRIBUTE_UNUSED,
|
||||
}
|
||||
}
|
||||
r = value_range (type);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1682,7 +1686,7 @@ operator_cast::op1_range (value_range &r, tree type,
|
||||
class operator_logical_and : public range_operator
|
||||
{
|
||||
public:
|
||||
virtual void fold_range (value_range &r, tree type,
|
||||
virtual bool fold_range (value_range &r, tree type,
|
||||
const value_range &lh,
|
||||
const value_range &rh) const;
|
||||
virtual bool op1_range (value_range &r, tree type,
|
||||
@ -1694,13 +1698,13 @@ public:
|
||||
} op_logical_and;
|
||||
|
||||
|
||||
void
|
||||
bool
|
||||
operator_logical_and::fold_range (value_range &r, tree type,
|
||||
const value_range &lh,
|
||||
const value_range &rh) const
|
||||
{
|
||||
if (empty_range_check (r, lh, rh))
|
||||
return;
|
||||
return true;
|
||||
|
||||
// 0 && anything is 0.
|
||||
if ((wi::eq_p (lh.lower_bound (), 0) && wi::eq_p (lh.upper_bound (), 0))
|
||||
@ -1713,6 +1717,7 @@ operator_logical_and::fold_range (value_range &r, tree type,
|
||||
r = range_true_and_false (type);
|
||||
else
|
||||
r = range_true (type);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1964,7 +1969,7 @@ operator_bitwise_and::op2_range (value_range &r, tree type,
|
||||
class operator_logical_or : public range_operator
|
||||
{
|
||||
public:
|
||||
virtual void fold_range (value_range &r, tree type,
|
||||
virtual bool fold_range (value_range &r, tree type,
|
||||
const value_range &lh,
|
||||
const value_range &rh) const;
|
||||
virtual bool op1_range (value_range &r, tree type,
|
||||
@ -1975,16 +1980,17 @@ public:
|
||||
const value_range &op1) const;
|
||||
} op_logical_or;
|
||||
|
||||
void
|
||||
bool
|
||||
operator_logical_or::fold_range (value_range &r, tree type ATTRIBUTE_UNUSED,
|
||||
const value_range &lh,
|
||||
const value_range &rh) const
|
||||
{
|
||||
if (empty_range_check (r, lh, rh))
|
||||
return;
|
||||
return true;
|
||||
|
||||
r = lh;
|
||||
r.union_ (rh);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2198,7 +2204,7 @@ operator_trunc_mod::wi_fold (value_range &r, tree type,
|
||||
class operator_logical_not : public range_operator
|
||||
{
|
||||
public:
|
||||
virtual void fold_range (value_range &r, tree type,
|
||||
virtual bool fold_range (value_range &r, tree type,
|
||||
const value_range &lh,
|
||||
const value_range &rh) const;
|
||||
virtual bool op1_range (value_range &r, tree type,
|
||||
@ -2220,13 +2226,13 @@ public:
|
||||
// b_2 = x_1 < 20 [0,0] = x_1 < 20, false, so x_1 == [20, 255]
|
||||
// which is the result we are looking for.. so.. pass it through.
|
||||
|
||||
void
|
||||
bool
|
||||
operator_logical_not::fold_range (value_range &r, tree type,
|
||||
const value_range &lh,
|
||||
const value_range &rh ATTRIBUTE_UNUSED) const
|
||||
{
|
||||
if (empty_range_check (r, lh, rh))
|
||||
return;
|
||||
return true;
|
||||
|
||||
if (lh.varying_p () || lh.undefined_p ())
|
||||
r = lh;
|
||||
@ -2236,7 +2242,7 @@ operator_logical_not::fold_range (value_range &r, tree type,
|
||||
r.invert ();
|
||||
}
|
||||
gcc_checking_assert (lh.type() == type);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2255,7 +2261,7 @@ operator_logical_not::op1_range (value_range &r,
|
||||
class operator_bitwise_not : public range_operator
|
||||
{
|
||||
public:
|
||||
virtual void fold_range (value_range &r, tree type,
|
||||
virtual bool fold_range (value_range &r, tree type,
|
||||
const value_range &lh,
|
||||
const value_range &rh) const;
|
||||
virtual bool op1_range (value_range &r, tree type,
|
||||
@ -2263,19 +2269,19 @@ public:
|
||||
const value_range &op2) const;
|
||||
} op_bitwise_not;
|
||||
|
||||
void
|
||||
bool
|
||||
operator_bitwise_not::fold_range (value_range &r, tree type,
|
||||
const value_range &lh,
|
||||
const value_range &rh) const
|
||||
{
|
||||
if (empty_range_check (r, lh, rh))
|
||||
return;
|
||||
return true;
|
||||
|
||||
// ~X is simply -1 - X.
|
||||
value_range minusone (type, wi::minus_one (TYPE_PRECISION (type)),
|
||||
wi::minus_one (TYPE_PRECISION (type)));
|
||||
range_op_handler (MINUS_EXPR, type)->fold_range (r, type, minusone, lh);
|
||||
return;
|
||||
return range_op_handler (MINUS_EXPR, type)->fold_range (r, type, minusone,
|
||||
lh);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2284,32 +2290,32 @@ operator_bitwise_not::op1_range (value_range &r, tree type,
|
||||
const value_range &op2) const
|
||||
{
|
||||
// ~X is -1 - X and since bitwise NOT is involutary...do it again.
|
||||
fold_range (r, type, lhs, op2);
|
||||
return true;
|
||||
return fold_range (r, type, lhs, op2);
|
||||
}
|
||||
|
||||
|
||||
class operator_cst : public range_operator
|
||||
{
|
||||
public:
|
||||
virtual void fold_range (value_range &r, tree type,
|
||||
virtual bool fold_range (value_range &r, tree type,
|
||||
const value_range &op1,
|
||||
const value_range &op2) const;
|
||||
} op_integer_cst;
|
||||
|
||||
void
|
||||
bool
|
||||
operator_cst::fold_range (value_range &r, tree type ATTRIBUTE_UNUSED,
|
||||
const value_range &lh,
|
||||
const value_range &rh ATTRIBUTE_UNUSED) const
|
||||
{
|
||||
r = lh;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
class operator_identity : public range_operator
|
||||
{
|
||||
public:
|
||||
virtual void fold_range (value_range &r, tree type,
|
||||
virtual bool fold_range (value_range &r, tree type,
|
||||
const value_range &op1,
|
||||
const value_range &op2) const;
|
||||
virtual bool op1_range (value_range &r, tree type,
|
||||
@ -2317,12 +2323,13 @@ public:
|
||||
const value_range &op2) const;
|
||||
} op_identity;
|
||||
|
||||
void
|
||||
bool
|
||||
operator_identity::fold_range (value_range &r, tree type ATTRIBUTE_UNUSED,
|
||||
const value_range &lh,
|
||||
const value_range &rh ATTRIBUTE_UNUSED) const
|
||||
{
|
||||
r = lh;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2485,7 +2492,7 @@ operator_absu::wi_fold (value_range &r, tree type,
|
||||
class operator_negate : public range_operator
|
||||
{
|
||||
public:
|
||||
virtual void fold_range (value_range &r, tree type,
|
||||
virtual bool fold_range (value_range &r, tree type,
|
||||
const value_range &op1,
|
||||
const value_range &op2) const;
|
||||
virtual bool op1_range (value_range &r, tree type,
|
||||
@ -2493,16 +2500,17 @@ class operator_negate : public range_operator
|
||||
const value_range &op2) const;
|
||||
} op_negate;
|
||||
|
||||
void
|
||||
bool
|
||||
operator_negate::fold_range (value_range &r, tree type,
|
||||
const value_range &lh,
|
||||
const value_range &rh) const
|
||||
{
|
||||
if (empty_range_check (r, lh, rh))
|
||||
return;
|
||||
return true;
|
||||
// -X is simply 0 - X.
|
||||
range_op_handler (MINUS_EXPR, type)->fold_range (r, type,
|
||||
range_zero (type), lh);
|
||||
return range_op_handler (MINUS_EXPR, type)->fold_range (r, type,
|
||||
range_zero (type),
|
||||
lh);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2511,15 +2519,14 @@ operator_negate::op1_range (value_range &r, tree type,
|
||||
const value_range &op2) const
|
||||
{
|
||||
// NEGATE is involutory.
|
||||
fold_range (r, type, lhs, op2);
|
||||
return true;
|
||||
return fold_range (r, type, lhs, op2);
|
||||
}
|
||||
|
||||
|
||||
class operator_addr_expr : public range_operator
|
||||
{
|
||||
public:
|
||||
virtual void fold_range (value_range &r, tree type,
|
||||
virtual bool fold_range (value_range &r, tree type,
|
||||
const value_range &op1,
|
||||
const value_range &op2) const;
|
||||
virtual bool op1_range (value_range &r, tree type,
|
||||
@ -2527,13 +2534,13 @@ public:
|
||||
const value_range &op2) const;
|
||||
} op_addr;
|
||||
|
||||
void
|
||||
bool
|
||||
operator_addr_expr::fold_range (value_range &r, tree type,
|
||||
const value_range &lh,
|
||||
const value_range &rh) const
|
||||
{
|
||||
if (empty_range_check (r, lh, rh))
|
||||
return;
|
||||
return true;
|
||||
|
||||
// Return a non-null pointer of the LHS type (passed in op2).
|
||||
if (lh.zero_p ())
|
||||
@ -2542,6 +2549,7 @@ operator_addr_expr::fold_range (value_range &r, tree type,
|
||||
r = range_nonzero (type);
|
||||
else
|
||||
r = value_range (type);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2549,8 +2557,7 @@ operator_addr_expr::op1_range (value_range &r, tree type,
|
||||
const value_range &lhs,
|
||||
const value_range &op2) const
|
||||
{
|
||||
operator_addr_expr::fold_range (r, type, lhs, op2);
|
||||
return true;
|
||||
return operator_addr_expr::fold_range (r, type, lhs, op2);
|
||||
}
|
||||
|
||||
|
||||
@ -2808,7 +2815,9 @@ range_cast (value_range &r, tree type)
|
||||
{
|
||||
value_range tmp = r;
|
||||
range_operator *op = range_op_handler (CONVERT_EXPR, type);
|
||||
op->fold_range (r, type, tmp, value_range (type));
|
||||
// Call op_convert, if it fails, the result is varying.
|
||||
if (!op->fold_range (r, type, tmp, value_range (type)))
|
||||
r = value_range (type);
|
||||
}
|
||||
|
||||
#if CHECKING_P
|
||||
|
@ -50,7 +50,7 @@ class range_operator
|
||||
{
|
||||
public:
|
||||
// Perform an operation between 2 ranges and return it.
|
||||
virtual void fold_range (value_range &r, tree type,
|
||||
virtual bool fold_range (value_range &r, tree type,
|
||||
const value_range &lh,
|
||||
const value_range &rh) const;
|
||||
|
||||
@ -73,7 +73,7 @@ public:
|
||||
const value_range &op1) const;
|
||||
|
||||
protected:
|
||||
// Perform an operation between 2 sub-ranges and return it.
|
||||
// Perform an integral operation between 2 sub-ranges and return it.
|
||||
virtual void wi_fold (value_range &r, tree type,
|
||||
const wide_int &lh_lb,
|
||||
const wide_int &lh_ub,
|
||||
|
@ -1185,8 +1185,7 @@ range_fold_binary_symbolics_p (value_range *vr,
|
||||
value_range vr0_cst (*vr0), vr1_cst (*vr1);
|
||||
vr0_cst.normalize_symbolics ();
|
||||
vr1_cst.normalize_symbolics ();
|
||||
op->fold_range (*vr, expr_type, vr0_cst, vr1_cst);
|
||||
return true;
|
||||
return op->fold_range (*vr, expr_type, vr0_cst, vr1_cst);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -1221,8 +1220,7 @@ range_fold_unary_symbolics_p (value_range *vr,
|
||||
const range_operator *op = get_range_op_handler (vr, code, expr_type);
|
||||
value_range vr0_cst (*vr0);
|
||||
vr0_cst.normalize_symbolics ();
|
||||
op->fold_range (*vr, expr_type, vr0_cst, value_range (expr_type));
|
||||
return true;
|
||||
return op->fold_range (*vr, expr_type, vr0_cst, value_range (expr_type));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user