@@ -360,10 +360,10 @@ adjust_pointer_diff_expr (irange &res, const gimple *diff_stmt)
&& vrp_operand_equal_p (op1, gimple_call_arg (call, 0))
&& integer_zerop (gimple_call_arg (call, 1)))
{
- tree max = vrp_val_max (ptrdiff_type_node);
- unsigned prec = TYPE_PRECISION (TREE_TYPE (max));
- wide_int wmaxm1 = wi::to_wide (max, prec) - 1;
- res.intersect (int_range<2> (TREE_TYPE (max), wi::zero (prec), wmaxm1));
+ wide_int maxm1 = irange_val_max (ptrdiff_type_node) - 1;
+ res.intersect (int_range<2> (ptrdiff_type_node,
+ wi::zero (TYPE_PRECISION (ptrdiff_type_node)),
+ maxm1));
}
}
@@ -966,6 +966,38 @@ tree_upper_bound (const vrange &r, tree type)
return NULL;
}
+// Return the maximum value for TYPE.
+
+static inline tree
+vrp_val_max (const_tree type)
+{
+ if (INTEGRAL_TYPE_P (type)
+ || POINTER_TYPE_P (type))
+ return wide_int_to_tree (const_cast <tree> (type), irange_val_max (type));
+ if (frange::supports_p (type))
+ {
+ REAL_VALUE_TYPE r = frange_val_max (type);
+ return build_real (const_cast <tree> (type), r);
+ }
+ return NULL_TREE;
+}
+
+// Return the minimum value for TYPE.
+
+static inline tree
+vrp_val_min (const_tree type)
+{
+ if (INTEGRAL_TYPE_P (type)
+ || POINTER_TYPE_P (type))
+ return wide_int_to_tree (const_cast <tree> (type), irange_val_min (type));
+ if (frange::supports_p (type))
+ {
+ REAL_VALUE_TYPE r = frange_val_min (type);
+ return build_real (const_cast <tree> (type), r);
+ }
+ return NULL_TREE;
+}
+
// If SCEV has any information about phi node NAME, return it as a range in R.
void
@@ -900,15 +900,13 @@ public:
virtual bool fold_range (irange &r, tree type, const irange &,
const irange &, relation_trio) const
{
- tree max = vrp_val_max (ptrdiff_type_node);
- wide_int wmax
- = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max)));
+ wide_int max = irange_val_max (ptrdiff_type_node);
// 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.
- r.set (type, wi::zero (TYPE_PRECISION (type)), wmax - 2);
+ r.set (type, wi::zero (TYPE_PRECISION (type)), max - 2);
return true;
}
} op_cfn_strlen;
@@ -936,7 +934,7 @@ public:
wi::shwi (m_is_pos ? 0 : 1, TYPE_PRECISION (type)),
size
? wi::shwi (size - m_is_pos, TYPE_PRECISION (type))
- : wi::to_wide (vrp_val_max (type)));
+ : irange_val_max (type));
return true;
}
private:
@@ -97,7 +97,7 @@ update_known_bitmask (irange &r, tree_code code,
static inline wide_int
max_limit (const_tree type)
{
- return wi::max_value (TYPE_PRECISION (type) , TYPE_SIGN (type));
+ return irange_val_max (type);
}
// Return the lower limit for a type.
@@ -105,7 +105,7 @@ max_limit (const_tree type)
static inline wide_int
min_limit (const_tree type)
{
- return wi::min_value (TYPE_PRECISION (type) , TYPE_SIGN (type));
+ return irange_val_min (type);
}
// Return false if shifting by OP is undefined behavior. Otherwise, return
@@ -1463,14 +1463,14 @@ plus_minus_ranges (irange &r_ov, irange &r_normal, const irange &offset,
{
// [ 0 , INF - OFF]
lb = wi::zero (prec);
- ub = wi::sub (wi::to_wide (vrp_val_max (type)), off, UNSIGNED, &ov);
+ ub = wi::sub (irange_val_max (type), off, UNSIGNED, &ov);
kind = VREL_GT;
}
else
{
// [ OFF, INF ]
lb = off;
- ub = wi::to_wide (vrp_val_max (type));
+ ub = irange_val_max (type);
kind = VREL_LT;
}
int_range<2> normal_range (type, lb, ub);
@@ -2594,13 +2594,10 @@ operator_rshift::op1_range (irange &r,
// OP1 is anything from 0011 1000 to 0011 1111. That is, a
// range from LHS<<3 plus a mask of the 3 bits we shifted on the
// right hand side (0x07).
- tree mask = fold_build1 (BIT_NOT_EXPR, type,
- fold_build2 (LSHIFT_EXPR, type,
- build_minus_one_cst (type),
- wide_int_to_tree (op2.type (), shift)));
+ wide_int mask = wi::bit_not (wi::lshift (wi::minus_one (prec), shift));
int_range_max mask_range (type,
wi::zero (TYPE_PRECISION (type)),
- wi::to_wide (mask));
+ mask);
op_plus.fold_range (ub, type, lb, mask_range);
r = lb;
r.union_ (ub);
@@ -2731,8 +2728,8 @@ operator_cast::inside_domain_p (const wide_int &min,
const wide_int &max,
const irange &range) const
{
- wide_int domain_min = wi::to_wide (vrp_val_min (range.type ()));
- wide_int domain_max = wi::to_wide (vrp_val_max (range.type ()));
+ wide_int domain_min = irange_val_min (range.type ());
+ wide_int domain_max = irange_val_max (range.type ());
signop domain_sign = TYPE_SIGN (range.type ());
return (wi::le_p (min, domain_max, domain_sign)
&& wi::le_p (max, domain_max, domain_sign)
@@ -1990,31 +1990,6 @@ debug (const value_range &vr)
fprintf (stderr, "\n");
}
-/* Return whether VAL is equal to the maximum value of its type.
- We can't do a simple equality comparison with TYPE_MAX_VALUE because
- C typedefs and Ada subtypes can produce types whose TYPE_MAX_VALUE
- is not == to the integer constant with the same value in the type. */
-
-bool
-vrp_val_is_max (const_tree val)
-{
- tree type_max = vrp_val_max (TREE_TYPE (val));
- return (val == type_max
- || (type_max != NULL_TREE
- && operand_equal_p (val, type_max, 0)));
-}
-
-/* Return whether VAL is equal to the minimum value of its type. */
-
-bool
-vrp_val_is_min (const_tree val)
-{
- tree type_min = vrp_val_min (TREE_TYPE (val));
- return (val == type_min
- || (type_min != NULL_TREE
- && operand_equal_p (val, type_min, 0)));
-}
-
/* Return true, if VAL1 and VAL2 are equal values for VRP purposes. */
bool
@@ -2369,11 +2344,11 @@ range_tests_misc ()
// Test 1-bit signed integer union.
// [-1,-1] U [0,0] = VARYING.
tree one_bit_type = build_nonstandard_integer_type (1, 0);
- tree one_bit_min = vrp_val_min (one_bit_type);
- tree one_bit_max = vrp_val_max (one_bit_type);
+ wide_int one_bit_min = irange_val_min (one_bit_type);
+ wide_int one_bit_max = irange_val_max (one_bit_type);
{
- 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> min = int_range<2> (one_bit_type, one_bit_min, one_bit_min);
+ int_range<2> max = int_range<2> (one_bit_type, one_bit_max, one_bit_max);
max.union_ (min);
ASSERT_TRUE (max.varying_p ());
}
@@ -2382,8 +2357,8 @@ range_tests_misc ()
// Test inversion of 1-bit signed integers.
{
- 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> min = int_range<2> (one_bit_type, one_bit_min, one_bit_min);
+ int_range<2> max = int_range<2> (one_bit_type, one_bit_max, one_bit_max);
int_range<2> t;
t = min;
t.invert ();
@@ -635,8 +635,6 @@ Value_Range::supports_type_p (const_tree type)
extern value_range_kind get_legacy_range (const irange &, tree &min, tree &max);
extern void dump_value_range (FILE *, const vrange *);
-extern bool vrp_val_is_min (const_tree);
-extern bool vrp_val_is_max (const_tree);
extern bool vrp_operand_equal_p (const_tree, const_tree);
inline REAL_VALUE_TYPE frange_val_min (const_tree type);
inline REAL_VALUE_TYPE frange_val_max (const_tree type);
@@ -952,41 +950,18 @@ contains_zero_p (const irange &r)
return r.contains_p (zero);
}
-// Return the maximum value for TYPE.
-
-inline tree
-vrp_val_max (const_tree type)
+inline wide_int
+irange_val_min (const_tree type)
{
- if (INTEGRAL_TYPE_P (type))
- return TYPE_MAX_VALUE (type);
- if (POINTER_TYPE_P (type))
- {
- wide_int max = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
- return wide_int_to_tree (const_cast<tree> (type), max);
- }
- if (frange::supports_p (type))
- {
- REAL_VALUE_TYPE r = frange_val_max (type);
- return build_real (const_cast <tree> (type), r);
- }
- return NULL_TREE;
+ gcc_checking_assert (irange::supports_p (type));
+ return wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
}
-// Return the minimum value for TYPE.
-
-inline tree
-vrp_val_min (const_tree type)
+inline wide_int
+irange_val_max (const_tree type)
{
- if (INTEGRAL_TYPE_P (type))
- return TYPE_MIN_VALUE (type);
- if (POINTER_TYPE_P (type))
- return build_zero_cst (const_cast<tree> (type));
- if (frange::supports_p (type))
- {
- REAL_VALUE_TYPE r = frange_val_min (type);
- return build_real (const_cast <tree> (type), r);
- }
- return NULL_TREE;
+ gcc_checking_assert (irange::supports_p (type));
+ return wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
}
inline
@@ -103,34 +103,16 @@ check_for_binary_op_overflow (range_query *query,
tree op0, tree op1, bool *ovf, gimple *s = NULL)
{
value_range vr0, vr1;
- if (!query->range_of_expr (vr0, op0, s))
+ if (!query->range_of_expr (vr0, op0, s) || vr0.undefined_p ())
vr0.set_varying (TREE_TYPE (op0));
- if (!query->range_of_expr (vr1, op1, s))
+ if (!query->range_of_expr (vr1, op1, s) || vr1.undefined_p ())
vr1.set_varying (TREE_TYPE (op1));
- tree vr0min, vr0max, vr1min, vr1max;
- if (vr0.undefined_p () || vr0.varying_p ())
- {
- vr0min = vrp_val_min (TREE_TYPE (op0));
- vr0max = vrp_val_max (TREE_TYPE (op0));
- }
- else
- {
- tree type = vr0.type ();
- vr0min = wide_int_to_tree (type, vr0.lower_bound ());
- vr0max = wide_int_to_tree (type, vr0.upper_bound ());
- }
- if (vr1.undefined_p () || vr1.varying_p ())
- {
- vr1min = vrp_val_min (TREE_TYPE (op1));
- vr1max = vrp_val_max (TREE_TYPE (op1));
- }
- else
- {
- tree type = vr1.type ();
- vr1min = wide_int_to_tree (type, vr1.lower_bound ());
- vr1max = wide_int_to_tree (type, vr1.upper_bound ());
- }
+ tree vr0min = wide_int_to_tree (TREE_TYPE (op0), vr0.lower_bound ());
+ tree vr0max = wide_int_to_tree (TREE_TYPE (op0), vr0.upper_bound ());
+ tree vr1min = wide_int_to_tree (TREE_TYPE (op1), vr1.lower_bound ());
+ tree vr1max = wide_int_to_tree (TREE_TYPE (op1), vr1.upper_bound ());
+
*ovf = arith_overflowed_p (subcode, type, vr0min,
subcode == MINUS_EXPR ? vr1max : vr1min);
if (arith_overflowed_p (subcode, type, vr0max,
@@ -152,10 +134,12 @@ check_for_binary_op_overflow (range_query *query,
widest_int wmin, wmax;
widest_int w[4];
int i;
- w[0] = wi::to_widest (vr0min);
- w[1] = wi::to_widest (vr0max);
- w[2] = wi::to_widest (vr1min);
- w[3] = wi::to_widest (vr1max);
+ signop sign0 = TYPE_SIGN (TREE_TYPE (op0));
+ signop sign1 = TYPE_SIGN (TREE_TYPE (op1));
+ w[0] = widest_int::from (vr0.lower_bound (), sign0);
+ w[1] = widest_int::from (vr0.upper_bound (), sign0);
+ w[2] = widest_int::from (vr1.lower_bound (), sign1);
+ w[3] = widest_int::from (vr1.upper_bound (), sign1);
for (i = 0; i < 4; i++)
{
widest_int wt;
@@ -186,8 +170,10 @@ check_for_binary_op_overflow (range_query *query,
}
/* The result of op0 CODE op1 is known to be in range
[wmin, wmax]. */
- widest_int wtmin = wi::to_widest (vrp_val_min (type));
- widest_int wtmax = wi::to_widest (vrp_val_max (type));
+ widest_int wtmin
+ = widest_int::from (irange_val_min (type), TYPE_SIGN (type));
+ widest_int wtmax
+ = widest_int::from (irange_val_max (type), TYPE_SIGN (type));
/* If all values in [wmin, wmax] are smaller than
[wtmin, wtmax] or all are larger than [wtmin, wtmax],
the arithmetic operation will always overflow. */