@@ -10882,8 +10882,7 @@ expr_not_equal_to (tree t, const wide_int &w)
else
get_global_range_query ()->range_of_expr (vr, t);
- if (!vr.undefined_p ()
- && !vr.contains_p (wide_int_to_tree (TREE_TYPE (t), w)))
+ if (!vr.undefined_p () && !vr.contains_p (w))
return true;
/* If T has some known zero bits and W has any of those bits set,
then T is known not to be equal to W. */
@@ -873,8 +873,8 @@ size_must_be_zero_p (tree size)
/* Compute the value of SSIZE_MAX, the largest positive value that
can be stored in ssize_t, the signed counterpart of size_t. */
wide_int ssize_max = wi::lshift (wi::one (prec), prec - 1) - 1;
- value_range valid_range (build_int_cst (type, 0),
- wide_int_to_tree (type, ssize_max));
+ wide_int zero = wi::zero (TYPE_PRECISION (type));
+ value_range valid_range (type, zero, ssize_max);
value_range vr;
if (cfun)
get_range_query (cfun)->range_of_expr (vr, size);
@@ -1476,7 +1476,7 @@ loop_versioning::prune_loop_conditions (class loop *loop)
gimple *stmt = first_stmt (loop->header);
if (get_range_query (cfun)->range_of_expr (r, name, stmt)
- && !r.contains_p (build_one_cst (TREE_TYPE (name))))
+ && !r.contains_p (wi::one (TYPE_PRECISION (TREE_TYPE (name)))))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, find_loop_location (loop),
@@ -59,9 +59,9 @@ gcond_edge_range (irange &r, edge e)
{
gcc_checking_assert (e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE));
if (e->flags & EDGE_TRUE_VALUE)
- r = int_range<2> (boolean_true_node, boolean_true_node);
+ r = range_true ();
else
- r = int_range<2> (boolean_false_node, boolean_false_node);
+ r = range_false ();
}
@@ -136,19 +136,22 @@ gimple_outgoing_range::calc_switch_ranges (gswitch *sw)
if (e == default_edge)
continue;
- tree low = CASE_LOW (gimple_switch_label (sw, x));
- tree high = CASE_HIGH (gimple_switch_label (sw, x));
- if (!high)
+ wide_int low = wi::to_wide (CASE_LOW (gimple_switch_label (sw, x)));
+ wide_int high;
+ tree tree_high = CASE_HIGH (gimple_switch_label (sw, x));
+ if (tree_high)
+ high = wi::to_wide (tree_high);
+ else
high = low;
// Remove the case range from the default case.
- int_range_max def_range (low, high);
+ int_range_max def_range (type, low, high);
range_cast (def_range, type);
def_range.invert ();
default_range.intersect (def_range);
// Create/union this case with anything on else on the edge.
- int_range_max case_range (low, high);
+ int_range_max case_range (type, low, high);
range_cast (case_range, type);
vrange_storage *&slot = m_edge_table->get_or_insert (e, &existed);
if (existed)
@@ -404,7 +404,8 @@ adjust_imagpart_expr (vrange &res, const gimple *stmt)
tree cst = gimple_assign_rhs1 (def_stmt);
if (TREE_CODE (cst) == COMPLEX_CST)
{
- int_range<2> imag (TREE_IMAGPART (cst), TREE_IMAGPART (cst));
+ wide_int w = wi::to_wide (TREE_IMAGPART (cst));
+ int_range<1> imag (TREE_TYPE (TREE_IMAGPART (cst)), w, w);
res.intersect (imag);
}
}
@@ -430,8 +431,8 @@ adjust_realpart_expr (vrange &res, const gimple *stmt)
tree cst = gimple_assign_rhs1 (def_stmt);
if (TREE_CODE (cst) == COMPLEX_CST)
{
- tree imag = TREE_REALPART (cst);
- int_range<2> tmp (imag, imag);
+ wide_int imag = wi::to_wide (TREE_REALPART (cst));
+ int_range<2> tmp (TREE_TYPE (TREE_REALPART (cst)), imag, imag);
res.intersect (tmp);
}
}
@@ -689,7 +690,8 @@ fold_using_range::range_of_address (irange &r, gimple *stmt, fur_source &src)
{
/* For -fdelete-null-pointer-checks -fno-wrapv-pointer we don't
allow going from non-NULL pointer to NULL. */
- if (r.undefined_p () || !r.contains_p (build_zero_cst (r.type ())))
+ if (r.undefined_p ()
+ || !r.contains_p (wi::zero (TYPE_PRECISION (TREE_TYPE (expr)))))
{
/* We could here instead adjust r by off >> LOG2_BITS_PER_UNIT
using POINTER_PLUS_EXPR if off_cst and just fall back to
@@ -1069,7 +1071,7 @@ fold_using_range::relation_fold_and_or (irange& lhs_range, gimple *s,
else if (ssa1_dep1 != ssa2_dep2 || ssa1_dep2 != ssa2_dep1)
return;
- int_range<2> bool_one (boolean_true_node, boolean_true_node);
+ int_range<2> bool_one = range_true ();
relation_kind relation1 = handler1.op1_op2_relation (bool_one);
relation_kind relation2 = handler2.op1_op2_relation (bool_one);
@@ -1081,7 +1083,7 @@ fold_using_range::relation_fold_and_or (irange& lhs_range, gimple *s,
// x && y is false if the relation intersection of the true cases is NULL.
if (is_and && relation_intersect (relation1, relation2) == VREL_UNDEFINED)
- lhs_range = int_range<2> (boolean_false_node, boolean_false_node);
+ lhs_range = range_false (boolean_type_node);
// x || y is true if the union of the true cases is NO-RELATION..
// ie, one or the other being true covers the full range of possibilities.
else if (!is_and && relation_union (relation1, relation2) == VREL_VARYING)
@@ -562,8 +562,8 @@ gori_compute::gori_compute (int not_executable_flag)
{
m_not_executable_flag = not_executable_flag;
// Create a boolean_type true and false range.
- m_bool_zero = int_range<2> (boolean_false_node, boolean_false_node);
- m_bool_one = int_range<2> (boolean_true_node, boolean_true_node);
+ m_bool_zero = range_false ();
+ m_bool_one = range_true ();
if (dump_file && (param_ranger_debug & RANGER_DEBUG_GORI))
tracer.enable_trace ();
}
@@ -731,7 +731,8 @@ range_is_either_true_or_false (const irange &r)
// so true can be ~[0, 0] (i.e. [1,MAX]).
tree type = r.type ();
gcc_checking_assert (range_compatible_p (type, boolean_type_node));
- return (r.singleton_p () || !r.contains_p (build_zero_cst (type)));
+ return (r.singleton_p ()
+ || !r.contains_p (wi::zero (TYPE_PRECISION (type))));
}
// Evaluate a binary logical expression by combining the true and
@@ -276,7 +276,8 @@ public:
{
if (lh.singleton_p ())
{
- r.set (build_one_cst (type), build_one_cst (type));
+ wide_int one = wi::one (TYPE_PRECISION (type));
+ r.set (type, one, one);
return true;
}
if (cfun->after_inlining)
@@ -298,7 +299,8 @@ public:
{
if (lh.singleton_p ())
{
- r.set (build_one_cst (type), build_one_cst (type));
+ wide_int one = wi::one (TYPE_PRECISION (type));
+ r.set (type, one, one);
return true;
}
if (cfun->after_inlining)
@@ -359,7 +361,7 @@ public:
r.update_nan (false);
return true;
}
- if (!lhs.contains_p (build_zero_cst (lhs.type ())))
+ if (!lhs.contains_p (wi::zero (TYPE_PRECISION (lhs.type ()))))
{
r.set (type, frange_val_min (type), dconstm0);
r.update_nan (true);
@@ -589,8 +591,12 @@ cfn_toupper_tolower::get_letter_range (tree type, irange &lowers,
if ((z - a == 25) && (Z - A == 25))
{
- lowers = int_range<2> (build_int_cst (type, a), build_int_cst (type, z));
- uppers = int_range<2> (build_int_cst (type, A), build_int_cst (type, Z));
+ lowers = int_range<2> (type,
+ wi::shwi (a, TYPE_PRECISION (type)),
+ wi::shwi (z, TYPE_PRECISION (type)));
+ uppers = int_range<2> (type,
+ wi::shwi (A, TYPE_PRECISION (type)),
+ wi::shwi (Z, TYPE_PRECISION (type)));
return true;
}
// Unknown character set.
@@ -648,7 +654,7 @@ public:
range_cast (tmp, unsigned_type_for (tmp.type ()));
wide_int max = tmp.upper_bound ();
maxi = wi::floor_log2 (max) + 1;
- r.set (build_int_cst (type, mini), build_int_cst (type, maxi));
+ r.set (type, wi::shwi (mini, prec), wi::shwi (maxi, prec));
return true;
}
} op_cfn_ffs;
@@ -753,7 +759,9 @@ cfn_clz::fold_range (irange &r, tree type, const irange &lh,
if (mini == -2)
return false;
- r.set (build_int_cst (type, mini), build_int_cst (type, maxi));
+ r.set (type,
+ wi::shwi (mini, TYPE_PRECISION (type)),
+ wi::shwi (maxi, TYPE_PRECISION (type)));
return true;
}
@@ -823,7 +831,9 @@ cfn_ctz::fold_range (irange &r, tree type, const irange &lh,
if (mini == -2)
return false;
- r.set (build_int_cst (type, mini), build_int_cst (type, maxi));
+ r.set (type,
+ wi::shwi (mini, TYPE_PRECISION (type)),
+ wi::shwi (maxi, TYPE_PRECISION (type)));
return true;
}
@@ -839,7 +849,9 @@ public:
if (lh.undefined_p ())
return false;
int prec = TYPE_PRECISION (lh.type ());
- r.set (build_int_cst (type, 0), build_int_cst (type, prec - 1));
+ r.set (type,
+ wi::zero (TYPE_PRECISION (type)),
+ wi::shwi (prec - 1, TYPE_PRECISION (type)));
return true;
}
} op_cfn_clrsb;
@@ -891,14 +903,12 @@ public:
tree max = vrp_val_max (ptrdiff_type_node);
wide_int wmax
= wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max)));
- tree range_min = build_zero_cst (type);
// To account for the terminating NULL, the maximum length
// is one less than the maximum array size, which in turn
// is one less than PTRDIFF_MAX (or SIZE_MAX where it's
// smaller than the former type).
// FIXME: Use max_object_size() - 1 here.
- tree range_max = wide_int_to_tree (type, wmax - 2);
- r.set (range_min, range_max);
+ r.set (type, wi::zero (TYPE_PRECISION (type)), wmax - 2);
return true;
}
} op_cfn_strlen;
@@ -922,9 +932,11 @@ public:
// If it's dynamic, the backend might know a hardware limitation.
size = targetm.goacc.dim_limit (axis);
- r.set (build_int_cst (type, m_is_pos ? 0 : 1),
+ r.set (type,
+ wi::shwi (m_is_pos ? 0 : 1, TYPE_PRECISION (type)),
size
- ? build_int_cst (type, size - m_is_pos) : vrp_val_max (type));
+ ? wi::shwi (size - m_is_pos, TYPE_PRECISION (type))
+ : wi::to_wide (vrp_val_max (type)));
return true;
}
private:
@@ -940,7 +952,7 @@ public:
virtual bool fold_range (irange &r, tree type, const irange &,
const irange &, relation_trio) const
{
- r.set (build_zero_cst (type), build_one_cst (type));
+ r = range_true_and_false (type);
return true;
}
} op_cfn_parity;
@@ -35,7 +35,9 @@ public:
// [5,10] + [15,20] => [20, 30]
tree expr = fold_build2 (PLUS_EXPR, type, op0, op1);
- int_range<2> expect (build_int_cst (type, 20), build_int_cst (type, 30));
+ int_range<1> expect (type,
+ wi::shwi (20, TYPE_PRECISION (type)),
+ wi::shwi (30, TYPE_PRECISION (type)));
int_range_max r;
ASSERT_TRUE (range_of_expr (r, expr));
@@ -45,14 +47,15 @@ public:
virtual bool range_of_expr (vrange &v, tree expr, gimple * = NULL) override
{
irange &r = as_a <irange> (v);
+ unsigned prec = TYPE_PRECISION (type);
if (expr == op0)
{
- r.set (build_int_cst (type, 5), build_int_cst (type, 10));
+ r.set (type, wi::shwi (5, prec), wi::shwi (10, prec));
return true;
}
if (expr == op1)
{
- r.set (build_int_cst (type, 15), build_int_cst (type, 20));
+ r.set (type, wi::shwi (15, prec), wi::shwi (20, prec));
return true;
}
return gimple_ranger::range_of_expr (r, expr);
@@ -222,8 +222,9 @@ alloca_call_type (gimple *stmt, bool is_vla)
&& !r.varying_p ())
{
// The invalid bits are anything outside of [0, MAX_SIZE].
- int_range<2> invalid_range (build_int_cst (size_type_node, 0),
- build_int_cst (size_type_node, max_size),
+ int_range<1> invalid_range (size_type_node,
+ wi::shwi (0, TYPE_PRECISION (size_type_node)),
+ wi::shwi (max_size, TYPE_PRECISION (size_type_node)),
VR_ANTI_RANGE);
r.intersect (invalid_range);
@@ -1943,8 +1943,9 @@ ipa_value_range_from_jfunc (ipa_node_params *info, cgraph_edge *cs,
if (!(*sum->m_vr)[idx].known)
return vr;
tree vr_type = ipa_get_type (info, idx);
- value_range srcvr (wide_int_to_tree (vr_type, (*sum->m_vr)[idx].min),
- wide_int_to_tree (vr_type, (*sum->m_vr)[idx].max),
+ value_range srcvr (vr_type,
+ (*sum->m_vr)[idx].min,
+ (*sum->m_vr)[idx].max,
(*sum->m_vr)[idx].type);
enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
@@ -2799,7 +2800,8 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
if (TREE_OVERFLOW_P (val))
val = drop_tree_overflow (val);
- value_range tmpvr (val, val);
+ value_range tmpvr (TREE_TYPE (val),
+ wi::to_wide (val), wi::to_wide (val));
return dest_lat->meet_with (&tmpvr);
}
}
@@ -6204,7 +6206,7 @@ decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset,
necessary. */
static inline bool
-ipa_range_contains_p (const irange &r, tree val)
+ipa_range_contains_p (const vrange &r, tree val)
{
if (r.undefined_p ())
return false;
@@ -2220,7 +2220,8 @@ ipa_get_value_range (value_range *tmp)
static value_range *
ipa_get_value_range (enum value_range_kind kind, tree min, tree max)
{
- value_range tmp (min, max, kind);
+ value_range tmp (TREE_TYPE (min),
+ wi::to_wide (min), wi::to_wide (max), kind);
return ipa_get_value_range (&tmp);
}
@@ -1208,7 +1208,10 @@ inline void
ipa_range_set_and_normalize (irange &r, tree val)
{
if (TREE_CODE (val) == INTEGER_CST)
- r.set (val, val);
+ {
+ wide_int w = wi::to_wide (val);
+ r.set (TREE_TYPE (val), w, w);
+ }
else if (TREE_CODE (val) == ADDR_EXPR)
r.set_nonzero (TREE_TYPE (val));
else
@@ -119,8 +119,9 @@ get_shift_range (irange &r, tree type, const irange &op)
return false;
// Build valid range and intersect it with the shift range.
- r = value_range (build_int_cst_type (op.type (), 0),
- build_int_cst_type (op.type (), TYPE_PRECISION (type) - 1));
+ r = value_range (op.type (),
+ wi::shwi (0, TYPE_PRECISION (op.type ())),
+ wi::shwi (TYPE_PRECISION (type) - 1, TYPE_PRECISION (op.type ())));
r.intersect (op);
// If there are no valid ranges in the shift range, returned false.
@@ -414,11 +415,7 @@ value_range_from_overflowed_bounds (irange &r, tree type,
if (covers || wi::cmp (tmin, tmax, sgn) > 0)
r.set_varying (type);
else
- {
- tree tree_min = wide_int_to_tree (type, tmin);
- tree tree_max = wide_int_to_tree (type, tmax);
- r.set (tree_min, tree_max, VR_ANTI_RANGE);
- }
+ r.set (type, tmin, tmax, VR_ANTI_RANGE);
}
// Create and return a range from a pair of wide-ints. MIN_OVF and
@@ -458,8 +455,7 @@ value_range_with_overflow (irange &r, tree type,
else
// No overflow or both overflow or underflow. The range
// kind stays normal.
- r.set (wide_int_to_tree (type, tmin),
- wide_int_to_tree (type, tmax));
+ r.set (type, tmin, tmax);
return;
}
@@ -497,8 +493,7 @@ value_range_with_overflow (irange &r, tree type,
else
new_ub = wmax;
- r.set (wide_int_to_tree (type, new_lb),
- wide_int_to_tree (type, new_ub));
+ r.set (type, new_lb, new_ub);
}
}
@@ -516,7 +511,7 @@ create_possibly_reversed_range (irange &r, tree type,
value_range_from_overflowed_bounds (r, type, new_lb, new_ub);
else
// Otherwise it's just a normal range.
- r.set (wide_int_to_tree (type, new_lb), wide_int_to_tree (type, new_ub));
+ r.set (type, new_lb, new_ub);
}
// Return the summary information about boolean range LHS. If EMPTY/FULL,
@@ -581,7 +576,7 @@ equal_op1_op2_relation (const irange &lhs)
return VREL_NE;
// TRUE = op1 == op2 indicates EQ_EXPR.
- if (!lhs.contains_p (build_zero_cst (lhs.type ())))
+ if (lhs.undefined_p () || !contains_zero_p (lhs))
return VREL_EQ;
return VREL_VARYING;
}
@@ -701,7 +696,7 @@ not_equal_op1_op2_relation (const irange &lhs)
return VREL_EQ;
// TRUE = op1 != op2 indicates NE_EXPR.
- if (!lhs.contains_p (build_zero_cst (lhs.type ())))
+ if (lhs.undefined_p () || !contains_zero_p (lhs))
return VREL_NE;
return VREL_VARYING;
}
@@ -881,7 +876,7 @@ lt_op1_op2_relation (const irange &lhs)
return VREL_GE;
// TRUE = op1 < op2 indicates LT_EXPR.
- if (!lhs.contains_p (build_zero_cst (lhs.type ())))
+ if (lhs.undefined_p () || !contains_zero_p (lhs))
return VREL_LT;
return VREL_VARYING;
}
@@ -1001,7 +996,7 @@ le_op1_op2_relation (const irange &lhs)
return VREL_GT;
// TRUE = op1 <= op2 indicates LE_EXPR.
- if (!lhs.contains_p (build_zero_cst (lhs.type ())))
+ if (lhs.undefined_p () || !contains_zero_p (lhs))
return VREL_LE;
return VREL_VARYING;
}
@@ -1118,7 +1113,7 @@ gt_op1_op2_relation (const irange &lhs)
return VREL_LE;
// TRUE = op1 > op2 indicates GT_EXPR.
- if (!lhs.contains_p (build_zero_cst (lhs.type ())))
+ if (!contains_zero_p (lhs))
return VREL_GT;
return VREL_VARYING;
}
@@ -1234,7 +1229,7 @@ ge_op1_op2_relation (const irange &lhs)
return VREL_LT;
// TRUE = op1 >= op2 indicates GE_EXPR.
- if (!lhs.contains_p (build_zero_cst (lhs.type ())))
+ if (!contains_zero_p (lhs))
return VREL_GE;
return VREL_VARYING;
}
@@ -1963,7 +1958,6 @@ operator_mult::op1_range (irange &r, tree type,
const irange &lhs, const irange &op2,
relation_trio) const
{
- tree offset;
if (lhs.undefined_p ())
return false;
@@ -1973,7 +1967,8 @@ operator_mult::op1_range (irange &r, tree type,
if (TYPE_OVERFLOW_WRAPS (type))
return false;
- if (op2.singleton_p (&offset) && !integer_zerop (offset))
+ wide_int offset;
+ if (op2.singleton_p (offset) && offset != 0)
return range_op_handler (TRUNC_DIV_EXPR, type).fold_range (r, type,
lhs, op2);
return false;
@@ -2284,15 +2279,14 @@ operator_exact_divide::op1_range (irange &r, tree type,
{
if (lhs.undefined_p ())
return false;
- tree offset;
+ wide_int offset;
// [2, 4] = op1 / [3,3] since its exact divide, no need to worry about
// remainders in the endpoints, so op1 = [2,4] * [3,3] = [6,12].
// We wont bother trying to enumerate all the in between stuff :-P
// TRUE accuracy is [6,6][9,9][12,12]. This is unlikely to matter most of
// the time however.
// 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))
+ if (op2.singleton_p (offset) && offset != 0)
return range_op_handler (MULT_EXPR, type).fold_range (r, type, lhs, op2);
return false;
}
@@ -2495,16 +2489,15 @@ operator_lshift::op1_range (irange &r,
{
if (lhs.undefined_p ())
return false;
- tree shift_amount;
- if (!lhs.contains_p (build_zero_cst (type)))
+ if (!contains_zero_p (lhs))
r.set_nonzero (type);
else
r.set_varying (type);
- if (op2.singleton_p (&shift_amount))
+ wide_int shift;
+ if (op2.singleton_p (shift))
{
- wide_int shift = wi::to_wide (shift_amount);
if (wi::lt_p (shift, 0, SIGNED))
return false;
if (wi::ge_p (shift, wi::uhwi (TYPE_PRECISION (type),
@@ -2541,8 +2534,7 @@ operator_lshift::op1_range (irange &r,
// This would be [0x42, 0xFC] aka [01000010, 11111100].
// Ideally we do this for each subrange, but just lump them all for now.
- unsigned low_bits = TYPE_PRECISION (utype)
- - TREE_INT_CST_LOW (shift_amount);
+ unsigned low_bits = TYPE_PRECISION (utype) - shift.to_uhwi ();
wide_int up_mask = wi::mask (low_bits, true, TYPE_PRECISION (utype));
wide_int new_ub = wi::bit_or (up_mask, tmp_range.upper_bound ());
wide_int new_lb = wi::set_bit (tmp_range.lower_bound (), low_bits);
@@ -2566,18 +2558,18 @@ operator_rshift::op1_range (irange &r,
const irange &op2,
relation_trio) const
{
- tree shift;
if (lhs.undefined_p ())
return false;
- if (op2.singleton_p (&shift))
+ wide_int shift;
+ if (op2.singleton_p (shift))
{
// Ignore nonsensical shifts.
unsigned prec = TYPE_PRECISION (type);
- if (wi::ge_p (wi::to_wide (shift),
- wi::uhwi (prec, TYPE_PRECISION (TREE_TYPE (shift))),
+ if (wi::ge_p (shift,
+ wi::uhwi (prec, TYPE_PRECISION (op2.type ())),
UNSIGNED))
return false;
- if (wi::to_wide (shift) == 0)
+ if (shift == 0)
{
r = lhs;
return true;
@@ -2593,7 +2585,7 @@ operator_rshift::op1_range (irange &r,
r.set_undefined ();
return true;
}
- int_range_max shift_range (shift, shift);
+ int_range_max shift_range (op2.type (), shift, shift);
int_range_max lb, ub;
op_lshift.fold_range (lb, type, lhs_refined, shift_range);
// LHS
@@ -2605,12 +2597,14 @@ operator_rshift::op1_range (irange &r,
tree mask = fold_build1 (BIT_NOT_EXPR, type,
fold_build2 (LSHIFT_EXPR, type,
build_minus_one_cst (type),
- shift));
- int_range_max mask_range (build_zero_cst (type), mask);
+ wide_int_to_tree (op2.type (), shift)));
+ int_range_max mask_range (type,
+ wi::zero (TYPE_PRECISION (type)),
+ wi::to_wide (mask));
op_plus.fold_range (ub, type, lb, mask_range);
r = lb;
r.union_ (ub);
- if (!lhs_refined.contains_p (build_zero_cst (type)))
+ if (!contains_zero_p (lhs_refined))
{
mask_range.invert ();
r.intersect (mask_range);
@@ -2853,7 +2847,7 @@ operator_cast::op1_range (irange &r, tree type,
{
// If the LHS is not a pointer nor a singleton, then it is
// either VARYING or non-zero.
- if (!lhs.contains_p (build_zero_cst (lhs.type ())))
+ if (!contains_zero_p (lhs))
r.set_nonzero (type);
else
r.set_varying (type);
@@ -2971,8 +2965,7 @@ operator_logical_and::fold_range (irange &r, tree type,
if ((wi::eq_p (lh.lower_bound (), 0) && wi::eq_p (lh.upper_bound (), 0))
|| (wi::eq_p (lh.lower_bound (), 0) && wi::eq_p (rh.upper_bound (), 0)))
r = range_false (type);
- else if (lh.contains_p (build_zero_cst (lh.type ()))
- || rh.contains_p (build_zero_cst (rh.type ())))
+ else if (contains_zero_p (lh) || contains_zero_p (rh))
// To reach this point, there must be a logical 1 on each side, and
// the only remaining question is whether there is a zero or not.
r = range_true_and_false (type);
@@ -3288,7 +3281,7 @@ operator_bitwise_and::wi_fold (irange &r, tree type,
static void
set_nonzero_range_from_mask (irange &r, tree type, const irange &lhs)
{
- if (!lhs.contains_p (build_zero_cst (type)))
+ if (!contains_zero_p (lhs))
r = range_nonzero (type);
else
r.set_varying (type);
@@ -3605,8 +3598,7 @@ operator_bitwise_or::op1_range (irange &r, tree type,
if (lhs.zero_p ())
{
- tree zero = build_zero_cst (type);
- r = int_range<1> (zero, zero);
+ r.set_zero (type);
return true;
}
r.set_varying (type);
@@ -3743,7 +3735,7 @@ operator_bitwise_xor::op1_range (irange &r, tree type,
else if (op2.zero_p ())
r = range_true (type);
// See get_bool_state for the rationale
- else if (op2.contains_p (build_zero_cst (op2.type ())))
+ else if (contains_zero_p (op2))
r = range_true_and_false (type);
else
r = range_false (type);
@@ -4346,7 +4338,7 @@ operator_addr_expr::fold_range (irange &r, tree type,
// Return a non-null pointer of the LHS type (passed in op2).
if (lh.zero_p ())
r = range_zero (type);
- else if (!lh.contains_p (build_zero_cst (lh.type ())))
+ else if (!contains_zero_p (lh))
r = range_nonzero (type);
else
r.set_varying (type);
@@ -4387,8 +4379,7 @@ pointer_plus_operator::wi_fold (irange &r, tree type,
// Check for [0,0] + const, and simply return the const.
if (lh_lb == 0 && lh_ub == 0 && rh_lb == rh_ub)
{
- tree val = wide_int_to_tree (type, rh_lb);
- r.set (val, val);
+ r.set (type, rh_lb, rh_lb);
return;
}
@@ -4522,8 +4513,7 @@ pointer_or_operator::op1_range (irange &r, tree type,
return false;
if (lhs.zero_p ())
{
- tree zero = build_zero_cst (type);
- r = int_range<1> (zero, zero);
+ r.set_zero (type);
return true;
}
r.set_varying (type);
@@ -4880,112 +4870,120 @@ range_cast (vrange &r, tree type)
namespace selftest
{
-#define INT(N) build_int_cst (integer_type_node, (N))
-#define UINT(N) build_int_cstu (unsigned_type_node, (N))
-#define INT16(N) build_int_cst (short_integer_type_node, (N))
-#define UINT16(N) build_int_cstu (short_unsigned_type_node, (N))
-#define SCHAR(N) build_int_cst (signed_char_type_node, (N))
-#define UCHAR(N) build_int_cstu (unsigned_char_type_node, (N))
+#define INT(x) wi::shwi ((x), TYPE_PRECISION (integer_type_node))
+#define UINT(x) wi::uhwi ((x), TYPE_PRECISION (unsigned_type_node))
+#define INT16(x) wi::shwi ((x), TYPE_PRECISION (short_integer_type_node))
+#define UINT16(x) wi::uhwi ((x), TYPE_PRECISION (short_unsigned_type_node))
+#define SCHAR(x) wi::shwi ((x), TYPE_PRECISION (signed_char_type_node))
+#define UCHAR(x) wi::uhwi ((x), TYPE_PRECISION (unsigned_char_type_node))
static void
range_op_cast_tests ()
{
int_range<2> r0, r1, r2, rold;
r0.set_varying (integer_type_node);
- tree maxint = wide_int_to_tree (integer_type_node, r0.upper_bound ());
+ wide_int maxint = r0.upper_bound ();
// If a range is in any way outside of the range for the converted
// to range, default to the range for the new type.
r0.set_varying (short_integer_type_node);
- tree minshort = wide_int_to_tree (short_integer_type_node, r0.lower_bound ());
- tree maxshort = wide_int_to_tree (short_integer_type_node, r0.upper_bound ());
- if (TYPE_PRECISION (TREE_TYPE (maxint))
+ wide_int minshort = r0.lower_bound ();
+ wide_int maxshort = r0.upper_bound ();
+ if (TYPE_PRECISION (integer_type_node)
> TYPE_PRECISION (short_integer_type_node))
{
- r1 = int_range<1> (integer_zero_node, maxint);
+ r1 = int_range<1> (integer_type_node,
+ wi::zero (TYPE_PRECISION (integer_type_node)),
+ maxint);
range_cast (r1, short_integer_type_node);
- ASSERT_TRUE (r1.lower_bound () == wi::to_wide (minshort)
- && r1.upper_bound() == wi::to_wide (maxshort));
+ ASSERT_TRUE (r1.lower_bound () == minshort
+ && r1.upper_bound() == maxshort);
}
// (unsigned char)[-5,-1] => [251,255].
- r0 = rold = int_range<1> (SCHAR (-5), SCHAR (-1));
+ r0 = rold = int_range<1> (signed_char_type_node, SCHAR (-5), SCHAR (-1));
range_cast (r0, unsigned_char_type_node);
- ASSERT_TRUE (r0 == int_range<1> (UCHAR (251), UCHAR (255)));
+ ASSERT_TRUE (r0 == int_range<1> (unsigned_char_type_node,
+ UCHAR (251), UCHAR (255)));
range_cast (r0, signed_char_type_node);
ASSERT_TRUE (r0 == rold);
// (signed char)[15, 150] => [-128,-106][15,127].
- r0 = rold = int_range<1> (UCHAR (15), UCHAR (150));
+ r0 = rold = int_range<1> (unsigned_char_type_node, UCHAR (15), UCHAR (150));
range_cast (r0, signed_char_type_node);
- r1 = int_range<1> (SCHAR (15), SCHAR (127));
- r2 = int_range<1> (SCHAR (-128), SCHAR (-106));
+ r1 = int_range<1> (signed_char_type_node, SCHAR (15), SCHAR (127));
+ r2 = int_range<1> (signed_char_type_node, SCHAR (-128), SCHAR (-106));
r1.union_ (r2);
ASSERT_TRUE (r1 == r0);
range_cast (r0, unsigned_char_type_node);
ASSERT_TRUE (r0 == rold);
// (unsigned char)[-5, 5] => [0,5][251,255].
- r0 = rold = int_range<1> (SCHAR (-5), SCHAR (5));
+ r0 = rold = int_range<1> (signed_char_type_node, SCHAR (-5), SCHAR (5));
range_cast (r0, unsigned_char_type_node);
- r1 = int_range<1> (UCHAR (251), UCHAR (255));
- r2 = int_range<1> (UCHAR (0), UCHAR (5));
+ r1 = int_range<1> (unsigned_char_type_node, UCHAR (251), UCHAR (255));
+ r2 = int_range<1> (unsigned_char_type_node, UCHAR (0), UCHAR (5));
r1.union_ (r2);
ASSERT_TRUE (r0 == r1);
range_cast (r0, signed_char_type_node);
ASSERT_TRUE (r0 == rold);
// (unsigned char)[-5,5] => [0,5][251,255].
- r0 = int_range<1> (INT (-5), INT (5));
+ r0 = int_range<1> (integer_type_node, INT (-5), INT (5));
range_cast (r0, unsigned_char_type_node);
- r1 = int_range<1> (UCHAR (0), UCHAR (5));
- r1.union_ (int_range<1> (UCHAR (251), UCHAR (255)));
+ r1 = int_range<1> (unsigned_char_type_node, UCHAR (0), UCHAR (5));
+ r1.union_ (int_range<1> (unsigned_char_type_node, UCHAR (251), UCHAR (255)));
ASSERT_TRUE (r0 == r1);
// (unsigned char)[5U,1974U] => [0,255].
- r0 = int_range<1> (UINT (5), UINT (1974));
+ r0 = int_range<1> (unsigned_type_node, UINT (5), UINT (1974));
range_cast (r0, unsigned_char_type_node);
- ASSERT_TRUE (r0 == int_range<1> (UCHAR (0), UCHAR (255)));
+ ASSERT_TRUE (r0 == int_range<1> (unsigned_char_type_node, UCHAR (0), UCHAR (255)));
range_cast (r0, integer_type_node);
// Going to a wider range should not sign extend.
- ASSERT_TRUE (r0 == int_range<1> (INT (0), INT (255)));
+ ASSERT_TRUE (r0 == int_range<1> (integer_type_node, INT (0), INT (255)));
// (unsigned char)[-350,15] => [0,255].
- r0 = int_range<1> (INT (-350), INT (15));
+ r0 = int_range<1> (integer_type_node, INT (-350), INT (15));
range_cast (r0, unsigned_char_type_node);
ASSERT_TRUE (r0 == (int_range<1>
- (TYPE_MIN_VALUE (unsigned_char_type_node),
- TYPE_MAX_VALUE (unsigned_char_type_node))));
+ (unsigned_char_type_node,
+ min_limit (unsigned_char_type_node),
+ max_limit (unsigned_char_type_node))));
// Casting [-120,20] from signed char to unsigned short.
// => [0, 20][0xff88, 0xffff].
- r0 = int_range<1> (SCHAR (-120), SCHAR (20));
+ r0 = int_range<1> (signed_char_type_node, SCHAR (-120), SCHAR (20));
range_cast (r0, short_unsigned_type_node);
- r1 = int_range<1> (UINT16 (0), UINT16 (20));
- r2 = int_range<1> (UINT16 (0xff88), UINT16 (0xffff));
+ r1 = int_range<1> (short_unsigned_type_node, UINT16 (0), UINT16 (20));
+ r2 = int_range<1> (short_unsigned_type_node,
+ UINT16 (0xff88), UINT16 (0xffff));
r1.union_ (r2);
ASSERT_TRUE (r0 == r1);
// A truncating cast back to signed char will work because [-120, 20]
// is representable in signed char.
range_cast (r0, signed_char_type_node);
- ASSERT_TRUE (r0 == int_range<1> (SCHAR (-120), SCHAR (20)));
+ ASSERT_TRUE (r0 == int_range<1> (signed_char_type_node,
+ SCHAR (-120), SCHAR (20)));
// unsigned char -> signed short
// (signed short)[(unsigned char)25, (unsigned char)250]
// => [(signed short)25, (signed short)250]
- r0 = rold = int_range<1> (UCHAR (25), UCHAR (250));
+ r0 = rold = int_range<1> (unsigned_char_type_node, UCHAR (25), UCHAR (250));
range_cast (r0, short_integer_type_node);
- r1 = int_range<1> (INT16 (25), INT16 (250));
+ r1 = int_range<1> (short_integer_type_node, INT16 (25), INT16 (250));
ASSERT_TRUE (r0 == r1);
range_cast (r0, unsigned_char_type_node);
ASSERT_TRUE (r0 == rold);
// Test casting a wider signed [-MIN,MAX] to a narrower unsigned.
- r0 = int_range<1> (TYPE_MIN_VALUE (long_long_integer_type_node),
- TYPE_MAX_VALUE (long_long_integer_type_node));
+ r0 = int_range<1> (long_long_integer_type_node,
+ min_limit (long_long_integer_type_node),
+ max_limit (long_long_integer_type_node));
range_cast (r0, short_unsigned_type_node);
- r1 = int_range<1> (TYPE_MIN_VALUE (short_unsigned_type_node),
- TYPE_MAX_VALUE (short_unsigned_type_node));
+ r1 = int_range<1> (short_unsigned_type_node,
+ min_limit (short_unsigned_type_node),
+ max_limit (short_unsigned_type_node));
ASSERT_TRUE (r0 == r1);
// Casting NONZERO to a narrower type will wrap/overflow so
@@ -4999,8 +4997,9 @@ range_op_cast_tests ()
{
r0 = range_nonzero (integer_type_node);
range_cast (r0, short_integer_type_node);
- r1 = int_range<1> (TYPE_MIN_VALUE (short_integer_type_node),
- TYPE_MAX_VALUE (short_integer_type_node));
+ r1 = int_range<1> (short_integer_type_node,
+ min_limit (short_integer_type_node),
+ max_limit (short_integer_type_node));
ASSERT_TRUE (r0 == r1);
}
@@ -5010,8 +5009,8 @@ range_op_cast_tests ()
// Converting this to 32-bits signed is [-MIN_16,-1][1, +MAX_16].
r0 = range_nonzero (short_integer_type_node);
range_cast (r0, integer_type_node);
- r1 = int_range<1> (INT (-32768), INT (-1));
- r2 = int_range<1> (INT (1), INT (32767));
+ r1 = int_range<1> (integer_type_node, INT (-32768), INT (-1));
+ r2 = int_range<1> (integer_type_node, INT (1), INT (32767));
r1.union_ (r2);
ASSERT_TRUE (r0 == r1);
}
@@ -5024,17 +5023,16 @@ range_op_lshift_tests ()
{
int_range_max res;
tree big_type = long_long_unsigned_type_node;
+ unsigned big_prec = TYPE_PRECISION (big_type);
// big_num = 0x808,0000,0000,0000
- tree big_num = fold_build2 (LSHIFT_EXPR, big_type,
- build_int_cst (big_type, 0x808),
- build_int_cst (big_type, 48));
+ wide_int big_num = wi::lshift (wi::uhwi (0x808, big_prec),
+ wi::uhwi (48, big_prec));
op_bitwise_and.fold_range (res, big_type,
int_range <1> (big_type),
- int_range <1> (big_num, big_num));
+ int_range <1> (big_type, big_num, big_num));
// val = 0x8,0000,0000,0000
- tree val = fold_build2 (LSHIFT_EXPR, big_type,
- build_int_cst (big_type, 0x8),
- build_int_cst (big_type, 48));
+ wide_int val = wi::lshift (wi::uhwi (8, big_prec),
+ wi::uhwi (48, big_prec));
ASSERT_TRUE (res.contains_p (val));
}
@@ -5042,13 +5040,13 @@ range_op_lshift_tests ()
{
// unsigned VARYING = op1 << 1 should be VARYING.
int_range<2> lhs (unsigned_type_node);
- int_range<2> shift (INT (1), INT (1));
+ int_range<2> shift (unsigned_type_node, INT (1), INT (1));
int_range_max op1;
op_lshift.op1_range (op1, unsigned_type_node, lhs, shift);
ASSERT_TRUE (op1.varying_p ());
// 0 = op1 << 1 should be [0,0], [0x8000000, 0x8000000].
- int_range<2> zero (UINT (0), UINT (0));
+ int_range<2> zero (unsigned_type_node, UINT (0), UINT (0));
op_lshift.op1_range (op1, unsigned_type_node, zero, shift);
ASSERT_TRUE (op1.num_pairs () == 2);
// Remove the [0,0] range.
@@ -5065,13 +5063,13 @@ range_op_lshift_tests ()
{
// unsigned VARYING = op1 << 1 should be VARYING.
int_range<2> lhs (integer_type_node);
- int_range<2> shift (INT (1), INT (1));
+ int_range<2> shift (integer_type_node, INT (1), INT (1));
int_range_max op1;
op_lshift.op1_range (op1, integer_type_node, lhs, shift);
ASSERT_TRUE (op1.varying_p ());
// 0 = op1 << 1 should be [0,0], [0x8000000, 0x8000000].
- int_range<2> zero (INT (0), INT (0));
+ int_range<2> zero (integer_type_node, INT (0), INT (0));
op_lshift.op1_range (op1, integer_type_node, zero, shift);
ASSERT_TRUE (op1.num_pairs () == 2);
// Remove the [0,0] range.
@@ -5090,10 +5088,11 @@ range_op_rshift_tests ()
{
// unsigned: [3, MAX] = OP1 >> 1
{
- int_range_max lhs (build_int_cst (unsigned_type_node, 3),
- TYPE_MAX_VALUE (unsigned_type_node));
- int_range_max one (build_one_cst (unsigned_type_node),
- build_one_cst (unsigned_type_node));
+ int_range_max lhs (unsigned_type_node,
+ UINT (3), max_limit (unsigned_type_node));
+ int_range_max one (unsigned_type_node,
+ wi::one (TYPE_PRECISION (unsigned_type_node)),
+ wi::one (TYPE_PRECISION (unsigned_type_node)));
int_range_max op1;
op_rshift.op1_range (op1, unsigned_type_node, lhs, one);
ASSERT_FALSE (op1.contains_p (UINT (3)));
@@ -5101,8 +5100,9 @@ range_op_rshift_tests ()
// signed: [3, MAX] = OP1 >> 1
{
- int_range_max lhs (INT (3), TYPE_MAX_VALUE (integer_type_node));
- int_range_max one (INT (1), INT (1));
+ int_range_max lhs (integer_type_node,
+ INT (3), max_limit (integer_type_node));
+ int_range_max one (integer_type_node, INT (1), INT (1));
int_range_max op1;
op_rshift.op1_range (op1, integer_type_node, lhs, one);
ASSERT_FALSE (op1.contains_p (INT (-2)));
@@ -5111,9 +5111,10 @@ range_op_rshift_tests ()
// This is impossible, so OP1 should be [].
// signed: [MIN, MIN] = OP1 >> 1
{
- int_range_max lhs (TYPE_MIN_VALUE (integer_type_node),
- TYPE_MIN_VALUE (integer_type_node));
- int_range_max one (INT (1), INT (1));
+ int_range_max lhs (integer_type_node,
+ min_limit (integer_type_node),
+ min_limit (integer_type_node));
+ int_range_max one (integer_type_node, INT (1), INT (1));
int_range_max op1;
op_rshift.op1_range (op1, integer_type_node, lhs, one);
ASSERT_TRUE (op1.undefined_p ());
@@ -5122,8 +5123,8 @@ range_op_rshift_tests ()
// signed: ~[-1] = OP1 >> 31
if (TYPE_PRECISION (integer_type_node) > 31)
{
- int_range_max lhs (INT (-1), INT (-1), VR_ANTI_RANGE);
- int_range_max shift (INT (31), INT (31));
+ int_range_max lhs (integer_type_node, INT (-1), INT (-1), VR_ANTI_RANGE);
+ int_range_max shift (integer_type_node, INT (31), INT (31));
int_range_max op1;
op_rshift.op1_range (op1, integer_type_node, lhs, shift);
int_range_max negatives = range_negatives (integer_type_node);
@@ -5136,13 +5137,11 @@ static void
range_op_bitwise_and_tests ()
{
int_range_max res;
- tree min = vrp_val_min (integer_type_node);
- tree max = vrp_val_max (integer_type_node);
- tree tiny = fold_build2 (PLUS_EXPR, integer_type_node, min,
- build_one_cst (integer_type_node));
- int_range_max i1 (tiny, max);
- int_range_max i2 (build_int_cst (integer_type_node, 255),
- build_int_cst (integer_type_node, 255));
+ wide_int min = min_limit (integer_type_node);
+ wide_int max = max_limit (integer_type_node);
+ wide_int tiny = wi::add (min, wi::one (TYPE_PRECISION (integer_type_node)));
+ int_range_max i1 (integer_type_node, tiny, max);
+ int_range_max i2 (integer_type_node, INT (255), INT (255));
// [MIN+1, MAX] = OP1 & 255: OP1 is VARYING
op_bitwise_and.op1_range (res, integer_type_node, i1, i2);
@@ -5155,8 +5154,8 @@ range_op_bitwise_and_tests ()
// For 0 = x & MASK, x is ~MASK.
{
- int_range<2> zero (integer_zero_node, integer_zero_node);
- int_range<2> mask = int_range<2> (INT (7), INT (7));
+ int_range<2> zero (integer_type_node, INT (0), INT (0));
+ int_range<2> mask = int_range<2> (integer_type_node, INT (7), INT (7));
op_bitwise_and.op1_range (res, integer_type_node, zero, mask);
wide_int inv = wi::shwi (~7U, TYPE_PRECISION (integer_type_node));
ASSERT_TRUE (res.get_nonzero_bits () == inv);
@@ -5169,7 +5168,7 @@ range_op_bitwise_and_tests ()
ASSERT_TRUE (res.nonzero_p ());
// (NEGATIVE | X) is nonzero.
- i1 = int_range<1> (INT (-5), INT (-3));
+ i1 = int_range<1> (integer_type_node, INT (-5), INT (-3));
i2.set_varying (integer_type_node);
op_bitwise_or.fold_range (res, integer_type_node, i1, i2);
ASSERT_FALSE (res.contains_p (INT (0)));
@@ -5179,22 +5178,22 @@ static void
range_relational_tests ()
{
int_range<2> lhs (unsigned_char_type_node);
- int_range<2> op1 (UCHAR (8), UCHAR (10));
- int_range<2> op2 (UCHAR (20), UCHAR (20));
+ int_range<2> op1 (unsigned_char_type_node, UCHAR (8), UCHAR (10));
+ int_range<2> op2 (unsigned_char_type_node, UCHAR (20), UCHAR (20));
// Never wrapping additions mean LHS > OP1.
relation_kind code = op_plus.lhs_op1_relation (lhs, op1, op2, VREL_VARYING);
ASSERT_TRUE (code == VREL_GT);
// Most wrapping additions mean nothing...
- op1 = int_range<2> (UCHAR (8), UCHAR (10));
- op2 = int_range<2> (UCHAR (0), UCHAR (255));
+ op1 = int_range<2> (unsigned_char_type_node, UCHAR (8), UCHAR (10));
+ op2 = int_range<2> (unsigned_char_type_node, UCHAR (0), UCHAR (255));
code = op_plus.lhs_op1_relation (lhs, op1, op2, VREL_VARYING);
ASSERT_TRUE (code == VREL_VARYING);
// However, always wrapping additions mean LHS < OP1.
- op1 = int_range<2> (UCHAR (1), UCHAR (255));
- op2 = int_range<2> (UCHAR (255), UCHAR (255));
+ op1 = int_range<2> (unsigned_char_type_node, UCHAR (1), UCHAR (255));
+ op2 = int_range<2> (unsigned_char_type_node, UCHAR (255), UCHAR (255));
code = op_plus.lhs_op1_relation (lhs, op1, op2, VREL_VARYING);
ASSERT_TRUE (code == VREL_LT);
}
@@ -32,14 +32,15 @@ along with GCC; see the file COPYING3. If not see
value_range
range_zero (tree type)
{
- return value_range (build_zero_cst (type), build_zero_cst (type));
+ wide_int zero = wi::zero (TYPE_PRECISION (type));
+ return value_range (type, zero, zero);
}
value_range
range_nonzero (tree type)
{
- return value_range (build_zero_cst (type), build_zero_cst (type),
- VR_ANTI_RANGE);
+ wide_int zero = wi::zero (TYPE_PRECISION (type));
+ return value_range (type, zero, zero, VR_ANTI_RANGE);
}
value_range
@@ -29,30 +29,30 @@ value_range range_negatives (tree type);
// Return an irange instance that is a boolean TRUE.
inline int_range<1>
-range_true (tree type)
+range_true (tree type = boolean_type_node)
{
unsigned prec = TYPE_PRECISION (type);
- return int_range<2> (type, wi::one (prec), wi::one (prec));
+ return int_range<1> (type, wi::one (prec), wi::one (prec));
}
// Return an irange instance that is a boolean FALSE.
inline int_range<1>
-range_false (tree type)
+range_false (tree type = boolean_type_node)
{
unsigned prec = TYPE_PRECISION (type);
- return int_range<2> (type, wi::zero (prec), wi::zero (prec));
+ return int_range<1> (type, wi::zero (prec), wi::zero (prec));
}
// Return an irange that covers both true and false.
inline int_range<1>
-range_true_and_false (tree type)
+range_true_and_false (tree type = boolean_type_node)
{
unsigned prec = TYPE_PRECISION (type);
if (prec == 1)
- return int_range<2> (type);
- return int_range<2> (type, wi::zero (prec), wi::one (prec));
+ return int_range<1> (type);
+ return int_range<1> (type, wi::zero (prec), wi::one (prec));
}
#endif // GCC_RANGE_H
@@ -769,7 +769,10 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1,
*var = size_int (0);
*off = fold_convert (ssizetype, op0);
if (result_range)
- result_range->set (op0, op0);
+ {
+ wide_int w = wi::to_wide (op0);
+ result_range->set (TREE_TYPE (op0), w, w);
+ }
return true;
case POINTER_PLUS_EXPR:
@@ -795,7 +798,7 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1,
return false;
split_constant_offset (op0, &var0, &off0, &op0_range, cache, limit);
- op1_range.set (op1, op1);
+ op1_range.set (TREE_TYPE (op1), wi::to_wide (op1), wi::to_wide (op1));
*off = size_binop (MULT_EXPR, off0, fold_convert (ssizetype, op1));
if (!compute_distributive_range (type, op0_range, code, op1_range,
off, result_range))
@@ -79,15 +79,15 @@ entry_loop_condition_is_static (class loop *l, gimple_ranger *ranger)
if (!loop_exit_edge_p (l, true_e) && !loop_exit_edge_p (l, false_e))
return false;
- tree desired_static_value;
+ int_range<1> desired_static_range;
if (loop_exit_edge_p (l, true_e))
- desired_static_value = boolean_false_node;
+ desired_static_range = range_false ();
else
- desired_static_value = boolean_true_node;
+ desired_static_range = range_true ();
int_range<2> r;
edge_range_query (r, e, last, *ranger);
- return r == int_range<2> (desired_static_value, desired_static_value);
+ return r == desired_static_range;
}
/* Check whether we should duplicate HEADER of LOOP. At most *LIMIT
@@ -142,14 +142,14 @@ struct unswitch_predicate
auto range_op = range_op_handler (code, TREE_TYPE (lhs));
int_range<2> rhs_range (TREE_TYPE (rhs));
if (CONSTANT_CLASS_P (rhs))
- rhs_range.set (rhs, rhs);
+ {
+ wide_int w = wi::to_wide (rhs);
+ rhs_range.set (TREE_TYPE (rhs), w, w);
+ }
if (!range_op.op1_range (true_range, TREE_TYPE (lhs),
- int_range<2> (boolean_true_node,
- boolean_true_node), rhs_range)
+ range_true (), rhs_range)
|| !range_op.op1_range (false_range, TREE_TYPE (lhs),
- int_range<2> (boolean_false_node,
- boolean_false_node),
- rhs_range))
+ range_false (), rhs_range))
{
true_range.set_varying (TREE_TYPE (lhs));
false_range.set_varying (TREE_TYPE (lhs));
@@ -605,12 +605,13 @@ find_unswitching_predicates_for_bb (basic_block bb, class loop *loop,
tree cmp1 = fold_build2 (GE_EXPR, boolean_type_node, idx, low);
tree cmp2 = fold_build2 (LE_EXPR, boolean_type_node, idx, high);
cmp = fold_build2 (BIT_AND_EXPR, boolean_type_node, cmp1, cmp2);
- lab_range.set (low, high);
+ lab_range.set (idx_type, wi::to_wide (low), wi::to_wide (high));
}
else
{
cmp = fold_build2 (EQ_EXPR, boolean_type_node, idx, low);
- lab_range.set (low, low);
+ wide_int w = wi::to_wide (low);
+ lab_range.set (idx_type, w, w);
}
/* Combine the expression with the existing one. */
@@ -1138,7 +1138,8 @@ value_replacement (basic_block cond_bb, basic_block middle_bb,
if (get_global_range_query ()->range_of_expr (r, phires,
phi))
{
- int_range<2> tmp (carg, carg);
+ wide_int warg = wi::to_wide (carg);
+ int_range<2> tmp (TREE_TYPE (carg), warg, warg);
r.union_ (tmp);
reset_flow_sensitive_info (phires);
set_range_info (phires, r);
@@ -327,8 +327,8 @@ back_threader::find_taken_edge_cond (const vec<basic_block> &path,
if (solver.unreachable_path_p ())
return UNREACHABLE_EDGE;
- int_range<2> true_range (boolean_true_node, boolean_true_node);
- int_range<2> false_range (boolean_false_node, boolean_false_node);
+ int_range<2> true_range = range_true ();
+ int_range<2> false_range = range_false ();
if (r == true_range || r == false_range)
{
@@ -522,10 +522,9 @@ ssa_name_has_boolean_range (tree op)
if (INTEGRAL_TYPE_P (TREE_TYPE (op))
&& (TYPE_PRECISION (TREE_TYPE (op)) > 1))
{
- int_range<2> onezero (build_zero_cst (TREE_TYPE (op)),
- build_one_cst (TREE_TYPE (op)));
int_range<2> r;
- if (get_range_query (cfun)->range_of_expr (r, op) && r == onezero)
+ if (get_range_query (cfun)->range_of_expr (r, op)
+ && r == range_true_and_false (TREE_TYPE (op)))
return true;
if (wi::eq_p (get_nonzero_bits (op), 1))
@@ -837,7 +837,9 @@ find_case_label_range (gswitch *switch_stmt, const irange *range_of_op)
tree label = gimple_switch_label (switch_stmt, i);
tree case_high
= CASE_HIGH (label) ? CASE_HIGH (label) : CASE_LOW (label);
- int_range_max label_range (CASE_LOW (label), case_high);
+ int_range_max label_range (type,
+ wi::to_wide (CASE_LOW (label)),
+ wi::to_wide (case_high));
if (!types_compatible_p (label_range.type (), range_of_op->type ()))
range_cast (label_range, range_of_op->type ());
label_range.intersect (*range_of_op);
@@ -861,7 +863,9 @@ find_case_label_range (gswitch *switch_stmt, const irange *range_of_op)
tree case_high = CASE_HIGH (max_label);
if (!case_high)
case_high = CASE_LOW (max_label);
- int_range_max label_range (CASE_LOW (min_label), case_high);
+ int_range_max label_range (TREE_TYPE (CASE_LOW (min_label)),
+ wi::to_wide (CASE_LOW (min_label)),
+ wi::to_wide (case_high));
if (!types_compatible_p (label_range.type (), range_of_op->type ()))
range_cast (label_range, range_of_op->type ());
label_range.intersect (*range_of_op);
@@ -176,16 +176,21 @@ range_query::get_tree_range (vrange &r, tree expr, gimple *stmt)
switch (TREE_CODE (expr))
{
case INTEGER_CST:
- if (TREE_OVERFLOW_P (expr))
- expr = drop_tree_overflow (expr);
- r.set (expr, expr);
- return true;
+ {
+ irange &i = as_a <irange> (r);
+ if (TREE_OVERFLOW_P (expr))
+ expr = drop_tree_overflow (expr);
+ wide_int w = wi::to_wide (expr);
+ i.set (TREE_TYPE (expr), w, w);
+ return true;
+ }
case REAL_CST:
{
frange &f = as_a <frange> (r);
- f.set (expr, expr);
- if (!real_isnan (TREE_REAL_CST_PTR (expr)))
+ REAL_VALUE_TYPE *rv = TREE_REAL_CST_PTR (expr);
+ f.set (TREE_TYPE (expr), *rv, *rv);
+ if (!real_isnan (rv))
f.clear_nan ();
return true;
}
@@ -301,7 +301,9 @@ irange::fits_p (const vrange &r) const
void
irange::set_nonnegative (tree type)
{
- set (build_int_cst (type, 0), TYPE_MAX_VALUE (type));
+ set (type,
+ wi::zero (TYPE_PRECISION (type)),
+ wi::to_wide (TYPE_MAX_VALUE (type)));
}
void
@@ -700,13 +702,12 @@ frange::operator== (const frange &src) const
return false;
}
-// Return TRUE if range contains the TREE_REAL_CST_PTR in CST.
+// Return TRUE if range contains R.
bool
-frange::contains_p (tree cst) const
+frange::contains_p (const REAL_VALUE_TYPE &r) const
{
gcc_checking_assert (m_kind != VR_ANTI_RANGE);
- const REAL_VALUE_TYPE *rv = TREE_REAL_CST_PTR (cst);
if (undefined_p ())
return false;
@@ -714,7 +715,7 @@ frange::contains_p (tree cst) const
if (varying_p ())
return true;
- if (real_isnan (rv))
+ if (real_isnan (&r))
{
// No NAN in range.
if (!m_pos_nan && !m_neg_nan)
@@ -722,16 +723,16 @@ frange::contains_p (tree cst) const
// Both +NAN and -NAN are present.
if (m_pos_nan && m_neg_nan)
return true;
- return m_neg_nan == rv->sign;
+ return m_neg_nan == r.sign;
}
if (known_isnan ())
return false;
- if (real_compare (GE_EXPR, rv, &m_min) && real_compare (LE_EXPR, rv, &m_max))
+ if (real_compare (GE_EXPR, &r, &m_min) && real_compare (LE_EXPR, &r, &m_max))
{
// Make sure the signs are equal for signed zeros.
- if (HONOR_SIGNED_ZEROS (m_type) && real_iszero (rv))
- return rv->sign == m_min.sign || rv->sign == m_max.sign;
+ if (HONOR_SIGNED_ZEROS (m_type) && real_iszero (&r))
+ return r.sign == m_min.sign || r.sign == m_max.sign;
return true;
}
return false;
@@ -743,7 +744,7 @@ frange::contains_p (tree cst) const
// A NAN can never be a singleton.
bool
-frange::singleton_p (tree *result) const
+frange::internal_singleton_p (REAL_VALUE_TYPE *result) const
{
if (m_kind == VR_RANGE && real_identical (&m_min, &m_max))
{
@@ -766,6 +767,18 @@ frange::singleton_p (tree *result) const
return false;
}
+ if (result)
+ *result = m_min;
+ return true;
+ }
+ return false;
+}
+
+bool
+frange::singleton_p (tree *result) const
+{
+ if (internal_singleton_p ())
+ {
if (result)
*result = build_real (m_type, m_min);
return true;
@@ -773,6 +786,12 @@ frange::singleton_p (tree *result) const
return false;
}
+bool
+frange::singleton_p (REAL_VALUE_TYPE &r) const
+{
+ return internal_singleton_p (&r);
+}
+
bool
frange::supports_type_p (const_tree type) const
{
@@ -942,13 +961,10 @@ get_legacy_range (const irange &r, tree &min, tree &max)
}
void
-irange::irange_set (tree min, tree max)
+irange::irange_set (tree type, const wide_int &min, const wide_int &max)
{
- gcc_checking_assert (!POLY_INT_CST_P (min));
- gcc_checking_assert (!POLY_INT_CST_P (max));
-
- m_base[0] = min;
- m_base[1] = max;
+ m_base[0] = wide_int_to_tree (type, min);
+ m_base[1] = wide_int_to_tree (type, max);
m_num_ranges = 1;
m_kind = VR_RANGE;
m_nonzero_mask = NULL;
@@ -959,26 +975,31 @@ irange::irange_set (tree min, tree max)
}
void
-irange::irange_set_1bit_anti_range (tree min, tree max)
+irange::irange_set_1bit_anti_range (tree type,
+ const wide_int &min, const wide_int &max)
{
- tree type = TREE_TYPE (min);
gcc_checking_assert (TYPE_PRECISION (type) == 1);
- if (operand_equal_p (min, max))
+ if (min == max)
{
// Since these are 1-bit quantities, they can only be [MIN,MIN]
// or [MAX,MAX].
- if (vrp_val_is_min (min))
- min = max = vrp_val_max (type);
+ if (min == wi::to_wide (TYPE_MIN_VALUE (type)))
+ {
+ wide_int tmp = wi::to_wide (TYPE_MAX_VALUE (type));
+ set (type, tmp, tmp);
+ }
else
- min = max = vrp_val_min (type);
- set (min, max);
+ {
+ wide_int tmp = wi::to_wide (TYPE_MIN_VALUE (type));
+ set (type, tmp, tmp);
+ }
}
else
{
// The only alternative is [MIN,MAX], which is the empty range.
- gcc_checking_assert (vrp_val_is_min (min));
- gcc_checking_assert (vrp_val_is_max (max));
+ gcc_checking_assert (min == wi::to_wide (TYPE_MIN_VALUE (type)));
+ gcc_checking_assert (max == wi::to_wide (TYPE_MAX_VALUE (type)));
set_undefined ();
}
if (flag_checking)
@@ -986,43 +1007,38 @@ irange::irange_set_1bit_anti_range (tree min, tree max)
}
void
-irange::irange_set_anti_range (tree min, tree max)
+irange::irange_set_anti_range (tree type,
+ const wide_int &min, const wide_int &max)
{
- gcc_checking_assert (!POLY_INT_CST_P (min));
- gcc_checking_assert (!POLY_INT_CST_P (max));
-
- if (TYPE_PRECISION (TREE_TYPE (min)) == 1)
+ if (TYPE_PRECISION (type) == 1)
{
- irange_set_1bit_anti_range (min, max);
+ irange_set_1bit_anti_range (type, min, max);
return;
}
// set an anti-range
- tree type = TREE_TYPE (min);
signop sign = TYPE_SIGN (type);
int_range<2> type_range (type);
// Calculate INVERSE([I,J]) as [-MIN, I-1][J+1, +MAX].
m_num_ranges = 0;
wi::overflow_type ovf;
- wide_int w_min = wi::to_wide (min);
- if (wi::ne_p (w_min, type_range.lower_bound ()))
+ if (wi::ne_p (min, type_range.lower_bound ()))
{
- wide_int lim1 = wi::sub (w_min, 1, sign, &ovf);
+ wide_int lim1 = wi::sub (min, 1, sign, &ovf);
gcc_checking_assert (ovf != wi::OVF_OVERFLOW);
m_base[0] = wide_int_to_tree (type, type_range.lower_bound (0));
m_base[1] = wide_int_to_tree (type, lim1);
m_num_ranges = 1;
}
- wide_int w_max = wi::to_wide (max);
- if (wi::ne_p (w_max, type_range.upper_bound ()))
+ if (wi::ne_p (max, type_range.upper_bound ()))
{
if (m_max_ranges == 1 && m_num_ranges)
{
set_varying (type);
return;
}
- wide_int lim2 = wi::add (w_max, 1, sign, &ovf);
+ wide_int lim2 = wi::add (max, 1, sign, &ovf);
gcc_checking_assert (ovf != wi::OVF_OVERFLOW);
m_base[m_num_ranges * 2] = wide_int_to_tree (type, lim2);
m_base[m_num_ranges * 2 + 1]
@@ -1047,6 +1063,36 @@ irange::irange_set_anti_range (tree min, tree max)
This routine exists to ease canonicalization in the case where we
extract ranges from var + CST op limit. */
+void
+irange::set (tree type, const wide_int &rmin, const wide_int &rmax,
+ value_range_kind kind)
+{
+ if (kind == VR_UNDEFINED)
+ {
+ irange::set_undefined ();
+ return;
+ }
+
+ if (kind == VR_VARYING)
+ {
+ set_varying (type);
+ return;
+ }
+
+ signop sign = TYPE_SIGN (type);
+ unsigned prec = TYPE_PRECISION (type);
+ wide_int min = wide_int::from (rmin, prec, sign);
+ wide_int max = wide_int::from (rmax, prec, sign);
+
+ if (kind == VR_RANGE)
+ irange_set (type, min, max);
+ else
+ {
+ gcc_checking_assert (kind == VR_ANTI_RANGE);
+ irange_set_anti_range (type, min, max);
+ }
+}
+
void
irange::set (tree min, tree max, value_range_kind kind)
{
@@ -1072,13 +1118,8 @@ irange::set (tree min, tree max, value_range_kind kind)
if (TREE_OVERFLOW_P (max))
max = drop_tree_overflow (max);
- if (kind == VR_RANGE)
- irange_set (min, max);
- else
- {
- gcc_checking_assert (kind == VR_ANTI_RANGE);
- irange_set_anti_range (min, max);
- }
+ return set (TREE_TYPE (min),
+ wi::to_wide (min), wi::to_wide (max), kind);
}
// Check the validity of the range.
@@ -1138,9 +1179,7 @@ irange::operator== (const irange &other) const
return nz1 == nz2;
}
-/* If range is a singleton, place it in RESULT and return TRUE.
- Note: A singleton can be any gimple invariant, not just constants.
- So, [&x, &x] counts as a singleton. */
+/* If range is a singleton, place it in RESULT and return TRUE. */
bool
irange::singleton_p (tree *result) const
@@ -1154,37 +1193,41 @@ irange::singleton_p (tree *result) const
return false;
}
-/* Return TRUE if range contains INTEGER_CST. */
-/* Return 1 if VAL is inside value range.
- 0 if VAL is not inside value range.
+bool
+irange::singleton_p (wide_int &w) const
+{
+ if (num_pairs () == 1 && lower_bound () == upper_bound ())
+ {
+ w = lower_bound ();
+ return true;
+ }
+ return false;
+}
+
+/* Return 1 if CST is inside value range.
+ 0 if CST is not inside value range.
Benchmark compile/20001226-1.c compilation time after changing this
function. */
-
bool
-irange::contains_p (tree cst) const
+irange::contains_p (const wide_int &cst) const
{
if (undefined_p ())
return false;
- gcc_checking_assert (TREE_CODE (cst) == INTEGER_CST);
-
// See if we can exclude CST based on the nonzero bits.
- if (m_nonzero_mask)
- {
- wide_int cstw = wi::to_wide (cst);
- if (cstw != 0 && wi::bit_and (wi::to_wide (m_nonzero_mask), cstw) == 0)
- return false;
- }
+ if (m_nonzero_mask
+ && cst != 0
+ && wi::bit_and (wi::to_wide (m_nonzero_mask), cst) == 0)
+ return false;
- signop sign = TYPE_SIGN (TREE_TYPE (cst));
- wide_int v = wi::to_wide (cst);
+ signop sign = TYPE_SIGN (type ());
for (unsigned r = 0; r < m_num_ranges; ++r)
{
- if (wi::lt_p (v, lower_bound (r), sign))
+ if (wi::lt_p (cst, lower_bound (r), sign))
return false;
- if (wi::le_p (v, upper_bound (r), sign))
+ if (wi::le_p (cst, upper_bound (r), sign))
return true;
}
@@ -1760,10 +1803,10 @@ irange::set_range_from_nonzero_bits ()
if (popcount == 1)
{
// Make sure we don't pessimize the range.
- if (!contains_p (m_nonzero_mask))
+ if (!contains_p (wi::to_wide (m_nonzero_mask)))
return false;
- bool has_zero = contains_p (build_zero_cst (type ()));
+ bool has_zero = contains_zero_p (*this);
tree nz = m_nonzero_mask;
set (nz, nz);
m_nonzero_mask = nz;
@@ -2085,7 +2128,6 @@ gt_ggc_mx (int_range<2> *&x)
}
#define DEFINE_INT_RANGE_INSTANCE(N) \
- template int_range<N>::int_range(tree, tree, value_range_kind); \
template int_range<N>::int_range(tree_node *, \
const wide_int &, \
const wide_int &, \
@@ -2103,20 +2145,73 @@ DEFINE_INT_RANGE_INSTANCE(255)
#if CHECKING_P
#include "selftest.h"
+#define INT(x) wi::shwi ((x), TYPE_PRECISION (integer_type_node))
+#define UINT(x) wi::uhwi ((x), TYPE_PRECISION (unsigned_type_node))
+#define SCHAR(x) wi::shwi ((x), TYPE_PRECISION (signed_char_type_node))
+
namespace selftest
{
-#define INT(N) build_int_cst (integer_type_node, (N))
-#define UINT(N) build_int_cstu (unsigned_type_node, (N))
-#define UINT128(N) build_int_cstu (u128_type, (N))
-#define UCHAR(N) build_int_cstu (unsigned_char_type_node, (N))
-#define SCHAR(N) build_int_cst (signed_char_type_node, (N))
+
+static int_range<2>
+range (tree type, int a, int b, value_range_kind kind = VR_RANGE)
+{
+ wide_int w1, w2;
+ if (TYPE_UNSIGNED (type))
+ {
+ w1 = wi::uhwi (a, TYPE_PRECISION (type));
+ w2 = wi::uhwi (b, TYPE_PRECISION (type));
+ }
+ else
+ {
+ w1 = wi::shwi (a, TYPE_PRECISION (type));
+ w2 = wi::shwi (b, TYPE_PRECISION (type));
+ }
+ return int_range<2> (type, w1, w2, kind);
+}
+
+static int_range<2>
+tree_range (tree a, tree b, value_range_kind kind = VR_RANGE)
+{
+ return int_range<2> (TREE_TYPE (a), wi::to_wide (a), wi::to_wide (b), kind);
+}
+
+static int_range<2>
+range_int (int a, int b, value_range_kind kind = VR_RANGE)
+{
+ return range (integer_type_node, a, b, kind);
+}
+
+static int_range<2>
+range_uint (int a, int b, value_range_kind kind = VR_RANGE)
+{
+ return range (unsigned_type_node, a, b, kind);
+}
+
+static int_range<2>
+range_uint128 (int a, int b, value_range_kind kind = VR_RANGE)
+{
+ tree u128_type_node = build_nonstandard_integer_type (128, 1);
+ return range (u128_type_node, a, b, kind);
+}
+
+static int_range<2>
+range_uchar (int a, int b, value_range_kind kind = VR_RANGE)
+{
+ return range (unsigned_char_type_node, a, b, kind);
+}
+
+static int_range<2>
+range_char (int a, int b, value_range_kind kind = VR_RANGE)
+{
+ return range (signed_char_type_node, a, b, kind);
+}
static int_range<3>
build_range3 (int a, int b, int c, int d, int e, int f)
{
- int_range<3> i1 (INT (a), INT (b));
- int_range<3> i2 (INT (c), INT (d));
- int_range<3> i3 (INT (e), INT (f));
+ int_range<3> i1 = range_int (a, b);
+ int_range<3> i2 = range_int (c, d);
+ int_range<3> i3 = range_int (e, f);
i1.union_ (i2);
i1.union_ (i3);
return i1;
@@ -2125,76 +2220,75 @@ build_range3 (int a, int b, int c, int d, int e, int f)
static void
range_tests_irange3 ()
{
- typedef int_range<3> int_range3;
- int_range3 r0, r1, r2;
- int_range3 i1, i2, i3;
+ int_range<3> r0, r1, r2;
+ int_range<3> i1, i2, i3;
// ([10,20] U [5,8]) U [1,3] ==> [1,3][5,8][10,20].
- r0 = int_range3 (INT (10), INT (20));
- r1 = int_range3 (INT (5), INT (8));
+ r0 = range_int (10, 20);
+ r1 = range_int (5, 8);
r0.union_ (r1);
- r1 = int_range3 (INT (1), INT (3));
+ r1 = range_int (1, 3);
r0.union_ (r1);
ASSERT_TRUE (r0 == build_range3 (1, 3, 5, 8, 10, 20));
// [1,3][5,8][10,20] U [-5,0] => [-5,3][5,8][10,20].
- r1 = int_range3 (INT (-5), INT (0));
+ r1 = range_int (-5, 0);
r0.union_ (r1);
ASSERT_TRUE (r0 == build_range3 (-5, 3, 5, 8, 10, 20));
// [10,20][30,40] U [50,60] ==> [10,20][30,40][50,60].
- r1 = int_range3 (INT (50), INT (60));
- r0 = int_range3 (INT (10), INT (20));
- r0.union_ (int_range3 (INT (30), INT (40)));
+ r1 = range_int (50, 60);
+ r0 = range_int (10, 20);
+ r0.union_ (range_int (30, 40));
r0.union_ (r1);
ASSERT_TRUE (r0 == build_range3 (10, 20, 30, 40, 50, 60));
// [10,20][30,40][50,60] U [70, 80] ==> [10,20][30,40][50,60][70,80].
- r1 = int_range3 (INT (70), INT (80));
+ r1 = range_int (70, 80);
r0.union_ (r1);
r2 = build_range3 (10, 20, 30, 40, 50, 60);
- r2.union_ (int_range3 (INT (70), INT (80)));
+ r2.union_ (range_int (70, 80));
ASSERT_TRUE (r0 == r2);
// [10,20][30,40][50,60] U [6,35] => [6,40][50,60].
r0 = build_range3 (10, 20, 30, 40, 50, 60);
- r1 = int_range3 (INT (6), INT (35));
+ r1 = range_int (6, 35);
r0.union_ (r1);
- r1 = int_range3 (INT (6), INT (40));
- r1.union_ (int_range3 (INT (50), INT (60)));
+ r1 = range_int (6, 40);
+ r1.union_ (range_int (50, 60));
ASSERT_TRUE (r0 == r1);
// [10,20][30,40][50,60] U [6,60] => [6,60].
r0 = build_range3 (10, 20, 30, 40, 50, 60);
- r1 = int_range3 (INT (6), INT (60));
+ r1 = range_int (6, 60);
r0.union_ (r1);
- ASSERT_TRUE (r0 == int_range3 (INT (6), INT (60)));
+ ASSERT_TRUE (r0 == range_int (6, 60));
// [10,20][30,40][50,60] U [6,70] => [6,70].
r0 = build_range3 (10, 20, 30, 40, 50, 60);
- r1 = int_range3 (INT (6), INT (70));
+ r1 = range_int (6, 70);
r0.union_ (r1);
- ASSERT_TRUE (r0 == int_range3 (INT (6), INT (70)));
+ ASSERT_TRUE (r0 == range_int (6, 70));
// [10,20][30,40][50,60] U [35,70] => [10,20][30,70].
r0 = build_range3 (10, 20, 30, 40, 50, 60);
- r1 = int_range3 (INT (35), INT (70));
+ r1 = range_int (35, 70);
r0.union_ (r1);
- r1 = int_range3 (INT (10), INT (20));
- r1.union_ (int_range3 (INT (30), INT (70)));
+ r1 = range_int (10, 20);
+ r1.union_ (range_int (30, 70));
ASSERT_TRUE (r0 == r1);
// [10,20][30,40][50,60] U [15,35] => [10,40][50,60].
r0 = build_range3 (10, 20, 30, 40, 50, 60);
- r1 = int_range3 (INT (15), INT (35));
+ r1 = range_int (15, 35);
r0.union_ (r1);
- r1 = int_range3 (INT (10), INT (40));
- r1.union_ (int_range3 (INT (50), INT (60)));
+ r1 = range_int (10, 40);
+ r1.union_ (range_int (50, 60));
ASSERT_TRUE (r0 == r1);
// [10,20][30,40][50,60] U [35,35] => [10,20][30,40][50,60].
r0 = build_range3 (10, 20, 30, 40, 50, 60);
- r1 = int_range3 (INT (35), INT (35));
+ r1 = range_int (35, 35);
r0.union_ (r1);
ASSERT_TRUE (r0 == build_range3 (10, 20, 30, 40, 50, 60));
}
@@ -2208,7 +2302,7 @@ range_tests_int_range_max ()
// Build a huge multi-range range.
for (nrange = 0; nrange < 50; ++nrange)
{
- int_range<1> tmp (INT (nrange*10), INT (nrange*10 + 5));
+ int_range<1> tmp = range_int (nrange*10, nrange *10 + 5);
big.union_ (tmp);
}
ASSERT_TRUE (big.num_pairs () == nrange);
@@ -2221,18 +2315,16 @@ range_tests_int_range_max ()
big.invert ();
ASSERT_TRUE (big.num_pairs () == nrange + 1);
- int_range<1> tmp (INT (5), INT (37));
+ int_range<1> tmp = range_int (5, 37);
big.intersect (tmp);
ASSERT_TRUE (big.num_pairs () == 4);
// Test that [10,10][20,20] does NOT contain 15.
{
- int_range_max i1 (build_int_cst (integer_type_node, 10),
- build_int_cst (integer_type_node, 10));
- int_range_max i2 (build_int_cst (integer_type_node, 20),
- build_int_cst (integer_type_node, 20));
+ int_range_max i1 = range_int (10, 10);
+ int_range_max i2 = range_int (20, 20);
i1.union_ (i2);
- ASSERT_FALSE (i1.contains_p (build_int_cst (integer_type_node, 15)));
+ ASSERT_FALSE (i1.contains_p (INT (15)));
}
}
@@ -2249,11 +2341,10 @@ range_tests_strict_enum ()
// Test that even though vr1 covers the strict enum domain ([0, 3]),
// it does not cover the domain of the underlying type.
- int_range<1> vr1 (build_int_cstu (rtype, 0), build_int_cstu (rtype, 1));
- int_range<1> vr2 (build_int_cstu (rtype, 2), build_int_cstu (rtype, 3));
+ int_range<1> vr1 = range (rtype, 0, 1);
+ int_range<1> vr2 = range (rtype, 2, 3);
vr1.union_ (vr2);
- ASSERT_TRUE (vr1 == int_range<1> (build_int_cstu (rtype, 0),
- build_int_cstu (rtype, 3)));
+ ASSERT_TRUE (vr1 == range (rtype, 0, 3));
ASSERT_FALSE (vr1.varying_p ());
// Test that copying to a multi-range does not change things.
@@ -2262,7 +2353,7 @@ range_tests_strict_enum ()
ASSERT_FALSE (ir1.varying_p ());
// The same test as above, but using TYPE_{MIN,MAX}_VALUE instead of [0,3].
- vr1 = int_range<1> (TYPE_MIN_VALUE (rtype), TYPE_MAX_VALUE (rtype));
+ vr1 = tree_range (TYPE_MIN_VALUE (rtype), TYPE_MAX_VALUE (rtype));
ir1 = vr1;
ASSERT_TRUE (ir1 == vr1);
ASSERT_FALSE (ir1.varying_p ());
@@ -2281,8 +2372,8 @@ range_tests_misc ()
tree one_bit_min = vrp_val_min (one_bit_type);
tree one_bit_max = vrp_val_max (one_bit_type);
{
- int_range<2> min (one_bit_min, one_bit_min);
- int_range<2> max (one_bit_max, one_bit_max);
+ int_range<2> min = tree_range (one_bit_min, one_bit_min);
+ int_range<2> max = tree_range (one_bit_max, one_bit_max);
max.union_ (min);
ASSERT_TRUE (max.varying_p ());
}
@@ -2291,8 +2382,8 @@ range_tests_misc ()
// Test inversion of 1-bit signed integers.
{
- int_range<2> min (one_bit_min, one_bit_min);
- int_range<2> max (one_bit_max, one_bit_max);
+ int_range<2> min = tree_range (one_bit_min, one_bit_min);
+ int_range<2> max = tree_range (one_bit_max, one_bit_max);
int_range<2> t;
t = min;
t.invert ();
@@ -2303,79 +2394,81 @@ range_tests_misc ()
}
// Test that NOT(255) is [0..254] in 8-bit land.
- int_range<1> not_255 (UCHAR (255), UCHAR (255), VR_ANTI_RANGE);
- ASSERT_TRUE (not_255 == int_range<1> (UCHAR (0), UCHAR (254)));
+ int_range<1> not_255 = range_uchar (255, 255, VR_ANTI_RANGE);
+ ASSERT_TRUE (not_255 == range_uchar (0, 254));
// Test that NOT(0) is [1..255] in 8-bit land.
int_range<2> not_zero = range_nonzero (unsigned_char_type_node);
- ASSERT_TRUE (not_zero == int_range<1> (UCHAR (1), UCHAR (255)));
+ ASSERT_TRUE (not_zero == range_uchar (1, 255));
// Check that [0,127][0x..ffffff80,0x..ffffff]
// => ~[128, 0x..ffffff7f].
- r0 = int_range<1> (UINT128 (0), UINT128 (127));
- tree high = build_minus_one_cst (u128_type);
+ r0 = range_uint128 (0, 127);
+ wide_int high = wi::minus_one (128);
// low = -1 - 127 => 0x..ffffff80.
- tree low = fold_build2 (MINUS_EXPR, u128_type, high, UINT128(127));
- r1 = int_range<1> (low, high); // [0x..ffffff80, 0x..ffffffff]
+ wide_int low = wi::sub (high, wi::uhwi (127, 128));
+ r1 = int_range<1> (u128_type, low, high); // [0x..ffffff80, 0x..ffffffff]
// r0 = [0,127][0x..ffffff80,0x..fffffff].
r0.union_ (r1);
// r1 = [128, 0x..ffffff7f].
- r1 = int_range<1> (UINT128(128),
- fold_build2 (MINUS_EXPR, u128_type,
- build_minus_one_cst (u128_type),
- UINT128(128)));
+ r1 = int_range<1> (u128_type,
+ wi::uhwi (128, 128),
+ wi::sub (wi::minus_one (128), wi::uhwi (128, 128)));
r0.invert ();
ASSERT_TRUE (r0 == r1);
r0.set_varying (integer_type_node);
- tree minint = wide_int_to_tree (integer_type_node, r0.lower_bound ());
- tree maxint = wide_int_to_tree (integer_type_node, r0.upper_bound ());
+ wide_int minint = r0.lower_bound ();
+ wide_int maxint = r0.upper_bound ();
r0.set_varying (short_integer_type_node);
r0.set_varying (unsigned_type_node);
- tree maxuint = wide_int_to_tree (unsigned_type_node, r0.upper_bound ());
+ wide_int maxuint = r0.upper_bound ();
// Check that ~[0,5] => [6,MAX] for unsigned int.
- r0 = int_range<1> (UINT (0), UINT (5));
+ r0 = range_uint (0, 5);
r0.invert ();
- ASSERT_TRUE (r0 == int_range<1> (UINT(6), maxuint));
+ ASSERT_TRUE (r0 == int_range<1> (unsigned_type_node,
+ wi::uhwi (6, TYPE_PRECISION (unsigned_type_node)),
+ maxuint));
// Check that ~[10,MAX] => [0,9] for unsigned int.
- r0 = int_range<1> (UINT(10), maxuint);
+ r0 = int_range<1> (unsigned_type_node,
+ wi::uhwi (10, TYPE_PRECISION (unsigned_type_node)),
+ maxuint);
r0.invert ();
- ASSERT_TRUE (r0 == int_range<1> (UINT (0), UINT (9)));
+ ASSERT_TRUE (r0 == range_uint (0, 9));
// Check that ~[0,5] => [6,MAX] for unsigned 128-bit numbers.
- r0 = int_range<1> (UINT128 (0), UINT128 (5), VR_ANTI_RANGE);
- r1 = int_range<1> (UINT128(6), build_minus_one_cst (u128_type));
+ r0 = range_uint128 (0, 5, VR_ANTI_RANGE);
+ r1 = int_range<1> (u128_type, wi::uhwi (6, 128), wi::minus_one (128));
ASSERT_TRUE (r0 == r1);
// Check that [~5] is really [-MIN,4][6,MAX].
- r0 = int_range<2> (INT (5), INT (5), VR_ANTI_RANGE);
- r1 = int_range<1> (minint, INT (4));
- r1.union_ (int_range<1> (INT (6), maxint));
+ r0 = range_int (5, 5, VR_ANTI_RANGE);
+ r1 = int_range<1> (integer_type_node, minint, INT (4));
+ r1.union_ (int_range<1> (integer_type_node, INT (6), maxint));
ASSERT_FALSE (r1.undefined_p ());
ASSERT_TRUE (r0 == r1);
- r1 = int_range<1> (INT (5), INT (5));
+ r1 = range_int (5, 5);
int_range<2> r2 (r1);
ASSERT_TRUE (r1 == r2);
- r1 = int_range<1> (INT (5), INT (10));
+ r1 = range_int (5, 10);
- r1 = int_range<1> (integer_type_node,
- wi::to_wide (INT (5)), wi::to_wide (INT (10)));
+ r1 = range_int (5, 10);
ASSERT_TRUE (r1.contains_p (INT (7)));
- r1 = int_range<1> (SCHAR (0), SCHAR (20));
+ r1 = range_char (0, 20);
ASSERT_TRUE (r1.contains_p (SCHAR(15)));
ASSERT_FALSE (r1.contains_p (SCHAR(300)));
// NOT([10,20]) ==> [-MIN,9][21,MAX].
- r0 = r1 = int_range<1> (INT (10), INT (20));
- r2 = int_range<1> (minint, INT(9));
- r2.union_ (int_range<1> (INT(21), maxint));
+ r0 = r1 = range_int (10, 20);
+ r2 = int_range<1> (integer_type_node, minint, INT(9));
+ r2.union_ (int_range<1> (integer_type_node, INT(21), maxint));
ASSERT_FALSE (r2.undefined_p ());
r1.invert ();
ASSERT_TRUE (r1 == r2);
@@ -2385,11 +2478,9 @@ range_tests_misc ()
// Test that booleans and their inverse work as expected.
r0 = range_zero (boolean_type_node);
- ASSERT_TRUE (r0 == int_range<1> (build_zero_cst (boolean_type_node),
- build_zero_cst (boolean_type_node)));
+ ASSERT_TRUE (r0 == range_false ());
r0.invert ();
- ASSERT_TRUE (r0 == int_range<1> (build_one_cst (boolean_type_node),
- build_one_cst (boolean_type_node)));
+ ASSERT_TRUE (r0 == range_true ());
// Make sure NULL and non-NULL of pointer types work, and that
// inverses of them are consistent.
@@ -2401,34 +2492,34 @@ range_tests_misc ()
ASSERT_TRUE (r0 == r1);
// [10,20] U [15, 30] => [10, 30].
- r0 = int_range<1> (INT (10), INT (20));
- r1 = int_range<1> (INT (15), INT (30));
+ r0 = range_int (10, 20);
+ r1 = range_int (15, 30);
r0.union_ (r1);
- ASSERT_TRUE (r0 == int_range<1> (INT (10), INT (30)));
+ ASSERT_TRUE (r0 == range_int (10, 30));
// [15,40] U [] => [15,40].
- r0 = int_range<1> (INT (15), INT (40));
+ r0 = range_int (15, 40);
r1.set_undefined ();
r0.union_ (r1);
- ASSERT_TRUE (r0 == int_range<1> (INT (15), INT (40)));
+ ASSERT_TRUE (r0 == range_int (15, 40));
// [10,20] U [10,10] => [10,20].
- r0 = int_range<1> (INT (10), INT (20));
- r1 = int_range<1> (INT (10), INT (10));
+ r0 = range_int (10, 20);
+ r1 = range_int (10, 10);
r0.union_ (r1);
- ASSERT_TRUE (r0 == int_range<1> (INT (10), INT (20)));
+ ASSERT_TRUE (r0 == range_int (10, 20));
// [10,20] U [9,9] => [9,20].
- r0 = int_range<1> (INT (10), INT (20));
- r1 = int_range<1> (INT (9), INT (9));
+ r0 = range_int (10, 20);
+ r1 = range_int (9, 9);
r0.union_ (r1);
- ASSERT_TRUE (r0 == int_range<1> (INT (9), INT (20)));
+ ASSERT_TRUE (r0 == range_int (9, 20));
// [10,20] ^ [15,30] => [15,20].
- r0 = int_range<1> (INT (10), INT (20));
- r1 = int_range<1> (INT (15), INT (30));
+ r0 = range_int (10, 20);
+ r1 = range_int (15, 30);
r0.intersect (r1);
- ASSERT_TRUE (r0 == int_range<1> (INT (15), INT (20)));
+ ASSERT_TRUE (r0 == range_int (15, 20));
// Test the internal sanity of wide_int's wrt HWIs.
ASSERT_TRUE (wi::max_value (TYPE_PRECISION (boolean_type_node),
@@ -2436,18 +2527,18 @@ range_tests_misc ()
== wi::uhwi (1, TYPE_PRECISION (boolean_type_node)));
// Test zero_p().
- r0 = int_range<1> (INT (0), INT (0));
+ r0 = range_int (0, 0);
ASSERT_TRUE (r0.zero_p ());
// Test nonzero_p().
- r0 = int_range<1> (INT (0), INT (0));
+ r0 = range_int (0, 0);
r0.invert ();
ASSERT_TRUE (r0.nonzero_p ());
// r0 = ~[1,1]
- r0 = int_range<2> (UINT (1), UINT (1), VR_ANTI_RANGE);
+ r0 = range_int (1, 1, VR_ANTI_RANGE);
// r1 = ~[3,3]
- r1 = int_range<2> (UINT (3), UINT (3), VR_ANTI_RANGE);
+ r1 = range_int (3, 3, VR_ANTI_RANGE);
// vv = [0,0][2,2][4, MAX]
int_range<3> vv = r0;
@@ -2456,7 +2547,7 @@ range_tests_misc ()
ASSERT_TRUE (vv.contains_p (UINT (2)));
ASSERT_TRUE (vv.num_pairs () == 3);
- r0 = int_range<1> (UINT (1), UINT (1));
+ r0 = range_uint (1, 1);
// And union it with [0,0][2,2][4,MAX] multi range
r0.union_ (vv);
// The result should be [0,2][4,MAX], or ~[3,3] but it must contain 2
@@ -2493,7 +2584,7 @@ range_tests_nonzero_bits ()
ASSERT_TRUE (r0.get_nonzero_bits () == 0xff);
// Intersect of nonzero bits.
- r0.set (INT (0), INT (255));
+ r0 = range_int (0, 255);
r0.set_nonzero_bits (0xfe);
r1.set_varying (integer_type_node);
r1.set_nonzero_bits (0xf0);
@@ -2502,7 +2593,7 @@ range_tests_nonzero_bits ()
// Intersect where the mask of nonzero bits is implicit from the range.
r0.set_varying (integer_type_node);
- r1.set (INT (0), INT (255));
+ r1 = range_int (0, 255);
r0.intersect (r1);
ASSERT_TRUE (r0.get_nonzero_bits () == 0xff);
@@ -2631,13 +2722,13 @@ range_tests_nan ()
// NAN is in a VARYING.
r0.set_varying (float_type_node);
real_nan (&r, "", 1, TYPE_MODE (float_type_node));
- tree nan = build_real (float_type_node, r);
+ REAL_VALUE_TYPE nan = r;
ASSERT_TRUE (r0.contains_p (nan));
// -NAN is in a VARYING.
r0.set_varying (float_type_node);
q = real_value_negate (&r);
- tree neg_nan = build_real (float_type_node, q);
+ REAL_VALUE_TYPE neg_nan = q;
ASSERT_TRUE (r0.contains_p (neg_nan));
// Clearing the NAN on a [] NAN is the empty set.
@@ -2669,28 +2760,29 @@ range_tests_nan ()
static void
range_tests_signed_zeros ()
{
- tree zero = build_zero_cst (float_type_node);
- tree neg_zero = fold_build1 (NEGATE_EXPR, float_type_node, zero);
+ REAL_VALUE_TYPE zero = dconst0;
+ REAL_VALUE_TYPE neg_zero = zero;
+ neg_zero.sign = 1;
frange r0, r1;
bool signbit;
// [0,0] contains [0,0] but not [-0,-0] and vice versa.
- r0 = frange (zero, zero);
- r1 = frange (neg_zero, neg_zero);
+ r0 = frange_float ("0.0", "0.0");
+ r1 = frange_float ("-0.0", "-0.0");
ASSERT_TRUE (r0.contains_p (zero));
ASSERT_TRUE (!r0.contains_p (neg_zero));
ASSERT_TRUE (r1.contains_p (neg_zero));
ASSERT_TRUE (!r1.contains_p (zero));
// Test contains_p() when we know the sign of the zero.
- r0 = frange (zero, zero);
+ r0 = frange_float ("0.0", "0.0");
ASSERT_TRUE (r0.contains_p (zero));
ASSERT_FALSE (r0.contains_p (neg_zero));
- r0 = frange (neg_zero, neg_zero);
+ r0 = frange_float ("-0.0", "-0.0");
ASSERT_TRUE (r0.contains_p (neg_zero));
ASSERT_FALSE (r0.contains_p (zero));
- r0 = frange (neg_zero, zero);
+ r0 = frange_float ("-0.0", "0.0");
ASSERT_TRUE (r0.contains_p (neg_zero));
ASSERT_TRUE (r0.contains_p (zero));
@@ -2700,8 +2792,8 @@ range_tests_signed_zeros ()
// The intersection of zeros that differ in sign is a NAN (or
// undefined if not honoring NANs).
- r0 = frange (neg_zero, neg_zero);
- r1 = frange (zero, zero);
+ r0 = frange_float ("-0.0", "-0.0");
+ r1 = frange_float ("0.0", "0.0");
r0.intersect (r1);
if (HONOR_NANS (float_type_node))
ASSERT_TRUE (r0.known_isnan ());
@@ -2709,18 +2801,18 @@ range_tests_signed_zeros ()
ASSERT_TRUE (r0.undefined_p ());
// The union of zeros that differ in sign is a zero with unknown sign.
- r0 = frange (zero, zero);
- r1 = frange (neg_zero, neg_zero);
+ r0 = frange_float ("0.0", "0.0");
+ r1 = frange_float ("-0.0", "-0.0");
r0.union_ (r1);
ASSERT_TRUE (r0.zero_p () && !r0.signbit_p (signbit));
// [-0, +0] has an unknown sign.
- r0 = frange (neg_zero, zero);
+ r0 = frange_float ("-0.0", "0.0");
ASSERT_TRUE (r0.zero_p () && !r0.signbit_p (signbit));
// [-0, +0] ^ [0, 0] is [0, 0]
- r0 = frange (neg_zero, zero);
- r1 = frange (zero, zero);
+ r0 = frange_float ("-0.0", "0.0");
+ r1 = frange_float ("0.0", "0.0");
r0.intersect (r1);
ASSERT_TRUE (r0.zero_p ());
@@ -122,8 +122,7 @@ class GTY((user)) irange : public vrange
friend class irange_storage;
public:
// In-place setters.
- virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
- void set (tree type, const wide_int_ref &, const wide_int_ref &,
+ void set (tree type, const wide_int &, const wide_int &,
value_range_kind = VR_RANGE);
virtual void set_nonzero (tree type) override;
virtual void set_zero (tree type) override;
@@ -146,7 +145,8 @@ public:
virtual bool zero_p () const override;
virtual bool nonzero_p () const override;
virtual bool singleton_p (tree *result = NULL) const override;
- virtual bool contains_p (tree cst) const override;
+ bool singleton_p (wide_int &) const;
+ bool contains_p (const wide_int &) const;
// In-place operators.
virtual bool union_ (const vrange &) override;
@@ -167,11 +167,13 @@ public:
void set_nonzero_bits (const wide_int_ref &bits);
protected:
+ virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
+ virtual bool contains_p (tree cst) const override;
irange (tree *, unsigned);
// In-place operators.
- void irange_set (tree, tree);
- void irange_set_anti_range (tree, tree);
+ void irange_set (tree type, const wide_int &, const wide_int &);
+ void irange_set_anti_range (tree type, const wide_int &, const wide_int &);
bool irange_contains_p (const irange &) const;
bool irange_single_pair_union (const irange &r);
@@ -184,7 +186,8 @@ private:
friend void gt_pch_nx (irange *);
friend void gt_pch_nx (irange *, gt_pointer_operator, void *);
- void irange_set_1bit_anti_range (tree, tree);
+ void irange_set_1bit_anti_range (tree type,
+ const wide_int &, const wide_int &);
bool varying_compatible_p () const;
bool intersect_nonzero_bits (const irange &r);
bool union_nonzero_bits (const irange &r);
@@ -206,7 +209,6 @@ class GTY((user)) int_range : public irange
{
public:
int_range ();
- int_range (tree, tree, value_range_kind = VR_RANGE);
int_range (tree type, const wide_int &, const wide_int &,
value_range_kind = VR_RANGE);
int_range (tree type);
@@ -214,6 +216,8 @@ public:
int_range (const irange &);
virtual ~int_range () = default;
int_range& operator= (const int_range &);
+protected:
+ int_range (tree, tree, value_range_kind = VR_RANGE);
private:
template <unsigned X> friend void gt_ggc_mx (int_range<X> *);
template <unsigned X> friend void gt_pch_nx (int_range<X> *);
@@ -319,7 +323,6 @@ public:
return SCALAR_FLOAT_TYPE_P (type) && !DECIMAL_FLOAT_TYPE_P (type);
}
virtual tree type () const override;
- virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
value_range_kind = VR_RANGE);
void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
@@ -330,8 +333,9 @@ public:
virtual void set_undefined () override;
virtual bool union_ (const vrange &) override;
virtual bool intersect (const vrange &) override;
- virtual bool contains_p (tree) const override;
+ bool contains_p (const REAL_VALUE_TYPE &) const;
virtual bool singleton_p (tree *result = NULL) const override;
+ bool singleton_p (REAL_VALUE_TYPE &r) const;
virtual bool supports_type_p (const_tree type) const override;
virtual void accept (const vrange_visitor &v) const override;
virtual bool zero_p () const override;
@@ -361,7 +365,13 @@ public:
bool maybe_isinf () const;
bool signbit_p (bool &signbit) const;
bool nan_signbit_p (bool &signbit) const;
+
+protected:
+ virtual bool contains_p (tree cst) const override;
+ virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
+
private:
+ bool internal_singleton_p (REAL_VALUE_TYPE * = NULL) const;
void verify_range ();
bool normalize_kind ();
bool union_nans (const frange &);
@@ -485,8 +495,6 @@ public:
static bool supports_type_p (const_tree type);
// Convenience methods for vrange compatibility.
- void set (tree min, tree max, value_range_kind kind = VR_RANGE)
- { return m_vrange->set (min, max, kind); }
tree type () { return m_vrange->type (); }
bool varying_p () const { return m_vrange->varying_p (); }
bool undefined_p () const { return m_vrange->undefined_p (); }
@@ -536,7 +544,7 @@ inline
Value_Range::Value_Range (tree min, tree max, value_range_kind kind)
{
init (TREE_TYPE (min));
- set (min, max, kind);
+ m_vrange->set (min, max, kind);
}
inline
@@ -674,13 +682,6 @@ irange::varying_compatible_p () const
return true;
}
-inline void
-irange::set (tree type, const wide_int_ref &min, const wide_int_ref &max,
- value_range_kind kind)
-{
- set (wide_int_to_tree (type, min), wide_int_to_tree (type, max), kind);
-}
-
inline bool
vrange::varying_p () const
{
@@ -707,8 +708,8 @@ irange::nonzero_p () const
if (undefined_p ())
return false;
- tree zero = build_zero_cst (type ());
- return *this == int_range<2> (zero, zero, VR_ANTI_RANGE);
+ wide_int zero = wi::zero (TYPE_PRECISION (type ()));
+ return *this == int_range<2> (type (), zero, zero, VR_ANTI_RANGE);
}
inline bool
@@ -717,6 +718,12 @@ irange::supports_p (const_tree type)
return INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type);
}
+inline bool
+irange::contains_p (tree cst) const
+{
+ return contains_p (wi::to_wide (cst));
+}
+
inline bool
range_includes_zero_p (const irange *vr)
{
@@ -726,7 +733,7 @@ range_includes_zero_p (const irange *vr)
if (vr->varying_p ())
return true;
- tree zero = build_zero_cst (vr->type ());
+ wide_int zero = wi::zero (TYPE_PRECISION (vr->type ()));
return vr->contains_p (zero);
}
@@ -906,8 +913,8 @@ irange::upper_bound () const
inline void
irange::set_nonzero (tree type)
{
- tree zero = build_int_cst (type, 0);
- irange_set_anti_range (zero, zero);
+ wide_int zero = wi::zero (TYPE_PRECISION (type));
+ set (type, zero, zero, VR_ANTI_RANGE);
}
// Set value range VR to a ZERO range of type TYPE.
@@ -915,8 +922,8 @@ irange::set_nonzero (tree type)
inline void
irange::set_zero (tree type)
{
- tree z = build_int_cst (type, 0);
- irange_set (z, z);
+ wide_int zero = wi::zero (TYPE_PRECISION (type));
+ set (type, zero, zero);
}
// Normalize a range to VARYING or UNDEFINED if possible.
@@ -935,6 +942,16 @@ irange::normalize_kind ()
}
}
+inline bool
+contains_zero_p (const irange &r)
+{
+ if (r.undefined_p ())
+ return true;
+
+ wide_int zero = wi::zero (TYPE_PRECISION (r.type ()));
+ return r.contains_p (zero);
+}
+
// Return the maximum value for TYPE.
inline tree
@@ -1083,6 +1100,12 @@ frange::update_nan (bool sign)
}
}
+inline bool
+frange::contains_p (tree cst) const
+{
+ return contains_p (*TREE_REAL_CST_PTR (cst));
+}
+
// Clear the NAN bit and adjust the range.
inline void
@@ -88,8 +88,7 @@ simplify_using_ranges::op_with_boolean_value_range_p (tree op, gimple *s)
as [0,1]. */
value_range vr;
return (query->range_of_expr (vr, op, s)
- && vr == value_range (build_zero_cst (TREE_TYPE (op)),
- build_one_cst (TREE_TYPE (op))));
+ && vr == range_true_and_false (TREE_TYPE (op)));
}
/* Helper function for simplify_internal_call_using_ranges and
@@ -316,7 +315,11 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
value_range maxvr, vr0, vr1;
if (!query->range_of_expr (vr0, init, stmt))
vr0.set_varying (TREE_TYPE (init));
- vr1.set (TREE_TYPE (init), wtmp, wtmp);
+ tree tinit = TREE_TYPE (init);
+ wide_int winit = wide_int::from (wtmp,
+ TYPE_PRECISION (tinit),
+ TYPE_SIGN (tinit));
+ vr1.set (TREE_TYPE (init), winit, winit);
range_op_handler handler (PLUS_EXPR, TREE_TYPE (init));
if (!handler.fold_range (maxvr, TREE_TYPE (init), vr0, vr1))
@@ -444,15 +447,25 @@ simplify_using_ranges::legacy_fold_cond_overflow (gimple *stmt)
else
{
value_range vro, vri;
+ tree type = TREE_TYPE (op0);
if (code == GT_EXPR || code == GE_EXPR)
{
- vro.set (TYPE_MIN_VALUE (TREE_TYPE (op0)), x, VR_ANTI_RANGE);
- vri.set (TYPE_MIN_VALUE (TREE_TYPE (op0)), x);
+ vro.set (type,
+ wi::to_wide (TYPE_MIN_VALUE (type)),
+ wi::to_wide (x), VR_ANTI_RANGE);
+ vri.set (type,
+ wi::to_wide (TYPE_MIN_VALUE (type)),
+ wi::to_wide (x));
}
else if (code == LT_EXPR || code == LE_EXPR)
{
- vro.set (TYPE_MIN_VALUE (TREE_TYPE (op0)), x);
- vri.set (TYPE_MIN_VALUE (TREE_TYPE (op0)), x, VR_ANTI_RANGE);
+ vro.set (type,
+ wi::to_wide (TYPE_MIN_VALUE (type)),
+ wi::to_wide (x));
+ vri.set (type,
+ wi::to_wide (TYPE_MIN_VALUE (type)),
+ wi::to_wide (x),
+ VR_ANTI_RANGE);
}
else
gcc_unreachable ();