@@ -3570,12 +3570,13 @@ determine_block_size (tree len, rtx len_rtx,
if (TREE_CODE (len) == SSA_NAME)
{
value_range r;
+ tree tmin, tmax;
get_global_range_query ()->range_of_expr (r, len);
- range_type = r.kind ();
+ range_type = get_legacy_range (r, tmin, tmax);
if (range_type != VR_UNDEFINED)
{
- min = wi::to_wide (r.min ());
- max = wi::to_wide (r.max ());
+ min = wi::to_wide (tmin);
+ max = wi::to_wide (tmax);
}
}
if (range_type == VR_RANGE)
@@ -266,6 +266,7 @@ check_out_of_bounds_and_warn (location_t location, tree ref,
bool ignore_off_by_one, bool for_array_bound,
bool *out_of_bound)
{
+ tree min, max;
tree low_bound = array_ref_low_bound (ref);
tree artype = TREE_TYPE (TREE_OPERAND (ref, 0));
@@ -284,7 +285,7 @@ check_out_of_bounds_and_warn (location_t location, tree ref,
if (warned)
; /* Do nothing. */
- else if (vr->kind () == VR_ANTI_RANGE)
+ else if (get_legacy_range (*vr, min, max) == VR_ANTI_RANGE)
{
if (up_bound
&& TREE_CODE (up_sub) == INTEGER_CST
@@ -378,8 +379,10 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
get_value_range (vr, low_sub_org, stmt);
if (!vr.undefined_p () && !vr.varying_p ())
{
- low_sub = vr.kind () == VR_RANGE ? vr.max () : vr.min ();
- up_sub = vr.kind () == VR_RANGE ? vr.min () : vr.max ();
+ tree min, max;
+ value_range_kind kind = get_legacy_range (vr, min, max);
+ low_sub = kind == VR_RANGE ? max : min;
+ up_sub = kind == VR_RANGE ? min : max;
}
}
@@ -355,11 +355,12 @@ builtin_memref::extend_offset_range (tree offset)
value_range vr;
if (m_ptr_qry.rvals->range_of_expr (vr, offset, stmt))
{
- rng = vr.kind ();
+ tree vr_min, vr_max;
+ rng = get_legacy_range (vr, vr_min, vr_max);
if (!vr.undefined_p ())
{
- min = wi::to_wide (vr.min ());
- max = wi::to_wide (vr.max ());
+ min = wi::to_wide (vr_min);
+ max = wi::to_wide (vr_max);
}
}
@@ -6614,10 +6614,11 @@ ipcp_store_vr_results (void)
&& !plats->m_value_range.top_p ()
&& dbg_cnt (ipa_cp_vr))
{
+ tree min, max;
vr.known = true;
- vr.type = plats->m_value_range.m_vr.kind ();
- vr.min = wi::to_wide (plats->m_value_range.m_vr.min ());
- vr.max = wi::to_wide (plats->m_value_range.m_vr.max ());
+ vr.type = get_legacy_range (plats->m_value_range.m_vr, min, max);
+ vr.min = wi::to_wide (min);
+ vr.max = wi::to_wide (max);
}
else
{
@@ -1692,9 +1692,10 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
get_range_query (cfun)->range_of_expr (vr, op);
if (vr.undefined_p ())
vr.set_varying (TREE_TYPE (op));
- value_range_kind vr_type = vr.kind ();
- wide_int vr_wmin = wi::to_wide (vr.min ());
- wide_int vr_wmax = wi::to_wide (vr.max ());
+ tree vr_min, vr_max;
+ value_range_kind vr_type = get_legacy_range (vr, vr_min, vr_max);
+ wide_int vr_wmin = wi::to_wide (vr_min);
+ wide_int vr_wmax = wi::to_wide (vr_max);
FOR_EACH_EDGE (e, ei, bb->succs)
{
@@ -118,9 +118,11 @@ struct ipa_vr_ggc_hash_traits : public ggc_cache_remove <value_range *>
static hashval_t
hash (const value_range *p)
{
- inchash::hash hstate (p->kind ());
- inchash::add_expr (p->min (), hstate);
- inchash::add_expr (p->max (), hstate);
+ tree min, max;
+ value_range_kind kind = get_legacy_range (*p, min, max);
+ inchash::hash hstate (kind);
+ inchash::add_expr (min, hstate);
+ inchash::add_expr (max, hstate);
return hstate.end ();
}
static bool
@@ -4783,10 +4785,12 @@ ipa_write_jump_function (struct output_block *ob,
streamer_write_bitpack (&bp);
if (jump_func->m_vr)
{
+ tree min, max;
+ value_range_kind kind = get_legacy_range (*jump_func->m_vr, min, max);
streamer_write_enum (ob->main_stream, value_rang_type,
- VR_LAST, jump_func->m_vr->kind ());
- stream_write_tree (ob, jump_func->m_vr->min (), true);
- stream_write_tree (ob, jump_func->m_vr->max (), true);
+ VR_LAST, kind);
+ stream_write_tree (ob, min, true);
+ stream_write_tree (ob, max, true);
}
}
@@ -317,14 +317,15 @@ get_size_range (range_query *query, tree exp, gimple *stmt, tree range[2],
if (integral)
{
value_range vr;
+ tree tmin, tmax;
query->range_of_expr (vr, exp, stmt);
if (vr.undefined_p ())
vr.set_varying (TREE_TYPE (exp));
- range_type = vr.kind ();
- min = wi::to_wide (vr.min ());
- max = wi::to_wide (vr.max ());
+ range_type = get_legacy_range (vr, tmin, tmax);
+ min = wi::to_wide (tmin);
+ max = wi::to_wide (tmax);
}
else
range_type = VR_VARYING;
@@ -1024,9 +1024,10 @@ split_constant_offset (tree exp, tree *var, tree *off, value_range *exp_range,
get_range_query (cfun)->range_of_expr (vr, exp);
if (vr.undefined_p ())
vr.set_varying (TREE_TYPE (exp));
- wide_int var_min = wi::to_wide (vr.min ());
- wide_int var_max = wi::to_wide (vr.max ());
- value_range_kind vr_kind = vr.kind ();
+ tree vr_min, vr_max;
+ value_range_kind vr_kind = get_legacy_range (vr, vr_min, vr_max);
+ wide_int var_min = wi::to_wide (vr_min);
+ wide_int var_max = wi::to_wide (vr_max);
wide_int var_nonzero = get_nonzero_bits (exp);
vr_kind = intersect_range_with_nonzero_bits (vr_kind,
&var_min, &var_max,
@@ -219,12 +219,13 @@ get_range (tree val, gimple *stmt, wide_int minmax[2],
if (!rvals->range_of_expr (vr, val, stmt))
return NULL_TREE;
- value_range_kind rng = vr.kind ();
+ tree vrmin, vrmax;
+ value_range_kind rng = get_legacy_range (vr, vrmin, vrmax);
if (rng == VR_RANGE)
{
/* Only handle straight ranges. */
- minmax[0] = wi::to_wide (vr.min ());
- minmax[1] = wi::to_wide (vr.max ());
+ minmax[0] = wi::to_wide (vrmin);
+ minmax[1] = wi::to_wide (vrmax);
return val;
}
@@ -2919,9 +2920,11 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt,
|| r.undefined_p ())
return false;
- cntrange[0] = wi::to_wide (r.min ());
- cntrange[1] = wi::to_wide (r.max ());
- if (r.kind () == VR_ANTI_RANGE)
+ tree min, max;
+ value_range_kind kind = get_legacy_range (r, min, max);
+ cntrange[0] = wi::to_wide (min);
+ cntrange[1] = wi::to_wide (max);
+ if (kind == VR_ANTI_RANGE)
{
wide_int maxobjsize = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node));
@@ -4086,8 +4089,9 @@ strlen_pass::get_len_or_size (gimple *stmt, tree arg, int idx,
else if (TREE_CODE (si->nonzero_chars) == SSA_NAME)
{
value_range r;
- get_range_query (cfun)->range_of_expr (r, si->nonzero_chars);
- if (r.kind () == VR_RANGE)
+ if (get_range_query (cfun)->range_of_expr (r, si->nonzero_chars)
+ && !r.undefined_p ()
+ && !r.varying_p ())
{
lenrng[0] = r.lower_bound ().to_uhwi ();
lenrng[1] = r.upper_bound ().to_uhwi ();
@@ -4808,12 +4812,13 @@ strlen_pass::count_nonzero_bytes_addr (tree exp, gimple *stmt,
&& TREE_CODE (si->nonzero_chars) == SSA_NAME)
{
value_range vr;
- ptr_qry.rvals->range_of_expr (vr, si->nonzero_chars, stmt);
- if (vr.kind () != VR_RANGE)
+ if (!ptr_qry.rvals->range_of_expr (vr, si->nonzero_chars, stmt)
+ || vr.undefined_p ()
+ || vr.varying_p ())
return false;
- minlen = tree_to_uhwi (vr.min ());
- maxlen = tree_to_uhwi (vr.max ());
+ minlen = vr.lower_bound ().to_uhwi ();
+ maxlen = vr.upper_bound ().to_uhwi ();
}
else
return false;
@@ -65,12 +65,13 @@ static bool
vect_get_range_info (tree var, wide_int *min_value, wide_int *max_value)
{
value_range vr;
+ tree vr_min, vr_max;
get_range_query (cfun)->range_of_expr (vr, var);
if (vr.undefined_p ())
vr.set_varying (TREE_TYPE (var));
- *min_value = wi::to_wide (vr.min ());
- *max_value = wi::to_wide (vr.max ());
- value_range_kind vr_type = vr.kind ();
+ value_range_kind vr_type = get_legacy_range (vr, vr_min, vr_max);
+ *min_value = wi::to_wide (vr_min);
+ *max_value = wi::to_wide (vr_max);
wide_int nonzero = get_nonzero_bits (var);
signop sgn = TYPE_SIGN (TREE_TYPE (var));
if (intersect_range_with_nonzero_bits (vr_type, min_value, max_value,
@@ -914,19 +914,58 @@ irange::operator= (const irange &src)
return *this;
}
-// Return TRUE if range is a multi-range that can be represented as a
-// VR_ANTI_RANGE.
-
-bool
-irange::maybe_anti_range () const
+value_range_kind
+get_legacy_range (const irange &r, tree &min, tree &max)
{
- tree ttype = type ();
- unsigned int precision = TYPE_PRECISION (ttype);
- signop sign = TYPE_SIGN (ttype);
- return (num_pairs () > 1
- && precision > 1
- && lower_bound () == wi::min_value (precision, sign)
- && upper_bound () == wi::max_value (precision, sign));
+ value_range_kind old_kind = r.kind ();
+ tree old_min = r.min ();
+ tree old_max = r.max ();
+
+ if (r.undefined_p ())
+ {
+ min = NULL_TREE;
+ max = NULL_TREE;
+ gcc_checking_assert (old_kind == VR_UNDEFINED);
+ return VR_UNDEFINED;
+ }
+
+ tree type = r.type ();
+ if (r.varying_p ())
+ {
+ min = wide_int_to_tree (type, r.lower_bound ());
+ max = wide_int_to_tree (type, r.upper_bound ());
+ gcc_checking_assert (old_kind == VR_VARYING);
+ gcc_checking_assert (vrp_operand_equal_p (old_min, min));
+ gcc_checking_assert (vrp_operand_equal_p (old_max, max));
+ return VR_VARYING;
+ }
+
+ unsigned int precision = TYPE_PRECISION (type);
+ signop sign = TYPE_SIGN (type);
+ if (r.num_pairs () > 1
+ && precision > 1
+ && r.lower_bound () == wi::min_value (precision, sign)
+ && r.upper_bound () == wi::max_value (precision, sign))
+ {
+ int_range<3> inv (r);
+ inv.invert ();
+ min = wide_int_to_tree (type, inv.lower_bound (0));
+ max = wide_int_to_tree (type, inv.upper_bound (0));
+ if (r.legacy_mode_p ())
+ {
+ gcc_checking_assert (old_kind == VR_ANTI_RANGE);
+ gcc_checking_assert (vrp_operand_equal_p (old_min, min));
+ gcc_checking_assert (vrp_operand_equal_p (old_max, max));
+ }
+ return VR_ANTI_RANGE;
+ }
+
+ min = wide_int_to_tree (type, r.lower_bound ());
+ max = wide_int_to_tree (type, r.upper_bound ());
+ gcc_checking_assert (old_kind == VR_RANGE);
+ gcc_checking_assert (vrp_operand_equal_p (old_min, min));
+ gcc_checking_assert (vrp_operand_equal_p (old_max, max));
+ return VR_RANGE;
}
void
@@ -968,13 +1007,9 @@ irange::copy_to_legacy (const irange &src)
return;
}
// Copy multi-range to legacy.
- if (src.maybe_anti_range ())
- {
- int_range<3> r (src);
- r.invert ();
- // Use tree variants to save on tree -> wi -> tree conversions.
- set (r.tree_lower_bound (0), r.tree_upper_bound (0), VR_ANTI_RANGE);
- }
+ tree min, max;
+ if (get_legacy_range (src, min, max) == VR_ANTI_RANGE)
+ set (min, max, VR_ANTI_RANGE);
else
set (src.tree_lower_bound (), src.tree_upper_bound ());
}
@@ -3056,18 +3091,20 @@ ranges_from_anti_range (const value_range *ar,
/* As a future improvement, we could handle ~[0, A] as: [-INF, -1] U
[A+1, +INF]. Not sure if this helps in practice, though. */
- if (ar->kind () != VR_ANTI_RANGE
- || TREE_CODE (ar->min ()) != INTEGER_CST
- || TREE_CODE (ar->max ()) != INTEGER_CST
+ tree ar_min, ar_max;
+ value_range_kind kind = get_legacy_range (*ar, ar_min, ar_max);
+ if (kind != VR_ANTI_RANGE
+ || TREE_CODE (ar_min) != INTEGER_CST
+ || TREE_CODE (ar_max) != INTEGER_CST
|| !vrp_val_min (type)
|| !vrp_val_max (type))
return false;
- if (tree_int_cst_lt (vrp_val_min (type), ar->min ()))
+ if (tree_int_cst_lt (vrp_val_min (type), ar_min))
vr0->set (vrp_val_min (type),
- wide_int_to_tree (type, wi::to_wide (ar->min ()) - 1));
- if (tree_int_cst_lt (ar->max (), vrp_val_max (type)))
- vr1->set (wide_int_to_tree (type, wi::to_wide (ar->max ()) + 1),
+ wide_int_to_tree (type, wi::to_wide (ar_min) - 1));
+ if (tree_int_cst_lt (ar_max, vrp_val_max (type)))
+ vr1->set (wide_int_to_tree (type, wi::to_wide (ar_max) + 1),
vrp_val_max (type));
if (vr0->undefined_p ())
{
@@ -118,6 +118,7 @@ namespace inchash
class GTY((user)) irange : public vrange
{
+ friend value_range_kind get_legacy_range (const irange &, tree &, tree &);
friend class vrange_allocator;
friend class irange_storage_slot; // For legacy_mode_p checks.
public:
@@ -197,7 +198,6 @@ protected:
wide_int legacy_lower_bound (unsigned = 0) const;
wide_int legacy_upper_bound (unsigned) const;
int value_inside_range (tree) const;
- bool maybe_anti_range () const;
void copy_to_legacy (const irange &);
void copy_legacy_to_multi_range (const irange &);
@@ -672,6 +672,7 @@ irange::legacy_mode_p () const
extern bool range_has_numeric_bounds_p (const irange *);
extern bool ranges_from_anti_range (const value_range *,
value_range *, value_range *);
+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);
@@ -124,8 +124,9 @@ check_for_binary_op_overflow (range_query *query,
else
vr1.set_varying (TREE_TYPE (op1));
- tree vr0min = vr0.min (), vr0max = vr0.max ();
- tree vr1min = vr1.min (), vr1max = vr1.max ();
+ tree vr0min, vr0max, vr1min, vr1max;
+ get_legacy_range (vr0, vr0min, vr0max);
+ get_legacy_range (vr1, vr1min, vr1max);
if (!range_int_cst_p (&vr0)
|| TREE_OVERFLOW (vr0min)
|| TREE_OVERFLOW (vr0max))
@@ -233,11 +234,14 @@ compare_ranges (enum tree_code comp, const value_range *vr0,
return NULL_TREE;
/* Anti-ranges need to be handled separately. */
- if (vr0->kind () == VR_ANTI_RANGE || vr1->kind () == VR_ANTI_RANGE)
+ tree vr0min, vr0max, vr1min, vr1max;
+ value_range_kind kind0 = get_legacy_range (*vr0, vr0min, vr0max);
+ value_range_kind kind1 = get_legacy_range (*vr1, vr1min, vr1max);
+ if (kind0 == VR_ANTI_RANGE || kind1 == VR_ANTI_RANGE)
{
/* If both are anti-ranges, then we cannot compute any
comparison. */
- if (vr0->kind () == VR_ANTI_RANGE && vr1->kind () == VR_ANTI_RANGE)
+ if (kind0 == VR_ANTI_RANGE && kind1 == VR_ANTI_RANGE)
return NULL_TREE;
/* These comparisons are never statically computable. */
@@ -249,14 +253,19 @@ compare_ranges (enum tree_code comp, const value_range *vr0,
/* Equality can be computed only between a range and an
anti-range. ~[VAL1, VAL2] == [VAL1, VAL2] is always false. */
- if (vr0->kind () == VR_RANGE)
- /* To simplify processing, make VR0 the anti-range. */
- std::swap (vr0, vr1);
+ if (kind0 == VR_RANGE)
+ {
+ /* To simplify processing, make VR0 the anti-range. */
+ kind0 = kind1;
+ vr0min = vr1min;
+ vr0max = vr1max;
+ kind1 = get_legacy_range (*vr0, vr1min, vr1max);
+ }
gcc_assert (comp == NE_EXPR || comp == EQ_EXPR);
- if (compare_values_warnv (vr0->min (), vr1->min (), strict_overflow_p) == 0
- && compare_values_warnv (vr0->max (), vr1->max (), strict_overflow_p) == 0)
+ if (compare_values_warnv (vr0min, vr1min, strict_overflow_p) == 0
+ && compare_values_warnv (vr0max, vr1max, strict_overflow_p) == 0)
return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node;
return NULL_TREE;
@@ -267,19 +276,22 @@ compare_ranges (enum tree_code comp, const value_range *vr0,
if (comp == GT_EXPR || comp == GE_EXPR)
{
comp = (comp == GT_EXPR) ? LT_EXPR : LE_EXPR;
- std::swap (vr0, vr1);
+ kind0 = kind1;
+ vr0min = vr1min;
+ vr0max = vr1max;
+ kind1 = get_legacy_range (*vr0, vr1min, vr1max);
}
if (comp == EQ_EXPR)
{
/* Equality may only be computed if both ranges represent
exactly one value. */
- if (compare_values_warnv (vr0->min (), vr0->max (), strict_overflow_p) == 0
- && compare_values_warnv (vr1->min (), vr1->max (), strict_overflow_p) == 0)
+ if (compare_values_warnv (vr0min, vr0max, strict_overflow_p) == 0
+ && compare_values_warnv (vr1min, vr1max, strict_overflow_p) == 0)
{
- int cmp_min = compare_values_warnv (vr0->min (), vr1->min (),
+ int cmp_min = compare_values_warnv (vr0min, vr1min,
strict_overflow_p);
- int cmp_max = compare_values_warnv (vr0->max (), vr1->max (),
+ int cmp_max = compare_values_warnv (vr0max, vr1max,
strict_overflow_p);
if (cmp_min == 0 && cmp_max == 0)
return boolean_true_node;
@@ -287,9 +299,9 @@ compare_ranges (enum tree_code comp, const value_range *vr0,
return boolean_false_node;
}
/* If [V0_MIN, V1_MAX] < [V1_MIN, V1_MAX] then V0 != V1. */
- else if (compare_values_warnv (vr0->min (), vr1->max (),
+ else if (compare_values_warnv (vr0min, vr1max,
strict_overflow_p) == 1
- || compare_values_warnv (vr1->min (), vr0->max (),
+ || compare_values_warnv (vr1min, vr0max,
strict_overflow_p) == 1)
return boolean_false_node;
@@ -304,20 +316,20 @@ compare_ranges (enum tree_code comp, const value_range *vr0,
make sure that both comparisons yield similar results to
avoid comparing values that cannot be compared at
compile-time. */
- cmp1 = compare_values_warnv (vr0->max (), vr1->min (), strict_overflow_p);
- cmp2 = compare_values_warnv (vr0->min (), vr1->max (), strict_overflow_p);
+ cmp1 = compare_values_warnv (vr0max, vr1min, strict_overflow_p);
+ cmp2 = compare_values_warnv (vr0min, vr1max, strict_overflow_p);
if ((cmp1 == -1 && cmp2 == -1) || (cmp1 == 1 && cmp2 == 1))
return boolean_true_node;
/* If VR0 and VR1 represent a single value and are identical,
return false. */
- else if (compare_values_warnv (vr0->min (), vr0->max (),
+ else if (compare_values_warnv (vr0min, vr0max,
strict_overflow_p) == 0
- && compare_values_warnv (vr1->min (), vr1->max (),
+ && compare_values_warnv (vr1min, vr1max,
strict_overflow_p) == 0
- && compare_values_warnv (vr0->min (), vr1->min (),
+ && compare_values_warnv (vr0min, vr1min,
strict_overflow_p) == 0
- && compare_values_warnv (vr0->max (), vr1->max (),
+ && compare_values_warnv (vr0max, vr1max,
strict_overflow_p) == 0)
return boolean_false_node;
@@ -330,13 +342,13 @@ compare_ranges (enum tree_code comp, const value_range *vr0,
int tst;
/* If VR0 is to the left of VR1, return true. */
- tst = compare_values_warnv (vr0->max (), vr1->min (), strict_overflow_p);
+ tst = compare_values_warnv (vr0max, vr1min, strict_overflow_p);
if ((comp == LT_EXPR && tst == -1)
|| (comp == LE_EXPR && (tst == -1 || tst == 0)))
return boolean_true_node;
/* If VR0 is to the right of VR1, return false. */
- tst = compare_values_warnv (vr0->min (), vr1->max (), strict_overflow_p);
+ tst = compare_values_warnv (vr0min, vr1max, strict_overflow_p);
if ((comp == LT_EXPR && (tst == 0 || tst == 1))
|| (comp == LE_EXPR && tst == 1))
return boolean_false_node;
@@ -364,7 +376,8 @@ compare_range_with_value (enum tree_code comp, const value_range *vr,
return NULL_TREE;
/* Anti-ranges need to be handled separately. */
- if (vr->kind () == VR_ANTI_RANGE)
+ tree min, max;
+ if (get_legacy_range (*vr, min, max) == VR_ANTI_RANGE)
{
/* For anti-ranges, the only predicates that we can compute at
compile time are equality and inequality. */
@@ -386,16 +399,16 @@ compare_range_with_value (enum tree_code comp, const value_range *vr,
{
/* EQ_EXPR may only be computed if VR represents exactly
one value. */
- if (compare_values_warnv (vr->min (), vr->max (), strict_overflow_p) == 0)
+ if (compare_values_warnv (min, max, strict_overflow_p) == 0)
{
- int cmp = compare_values_warnv (vr->min (), val, strict_overflow_p);
+ int cmp = compare_values_warnv (min, val, strict_overflow_p);
if (cmp == 0)
return boolean_true_node;
else if (cmp == -1 || cmp == 1 || cmp == 2)
return boolean_false_node;
}
- else if (compare_values_warnv (val, vr->min (), strict_overflow_p) == -1
- || compare_values_warnv (vr->max (), val, strict_overflow_p) == -1)
+ else if (compare_values_warnv (val, min, strict_overflow_p) == -1
+ || compare_values_warnv (max, val, strict_overflow_p) == -1)
return boolean_false_node;
return NULL_TREE;
@@ -403,14 +416,14 @@ compare_range_with_value (enum tree_code comp, const value_range *vr,
else if (comp == NE_EXPR)
{
/* If VAL is not inside VR, then they are always different. */
- if (compare_values_warnv (vr->max (), val, strict_overflow_p) == -1
- || compare_values_warnv (vr->min (), val, strict_overflow_p) == 1)
+ if (compare_values_warnv (max, val, strict_overflow_p) == -1
+ || compare_values_warnv (min, val, strict_overflow_p) == 1)
return boolean_true_node;
/* If VR represents exactly one value equal to VAL, then return
false. */
- if (compare_values_warnv (vr->min (), vr->max (), strict_overflow_p) == 0
- && compare_values_warnv (vr->min (), val, strict_overflow_p) == 0)
+ if (compare_values_warnv (min, max, strict_overflow_p) == 0
+ && compare_values_warnv (min, val, strict_overflow_p) == 0)
return boolean_false_node;
/* Otherwise, they may or may not be different. */
@@ -421,13 +434,13 @@ compare_range_with_value (enum tree_code comp, const value_range *vr,
int tst;
/* If VR is to the left of VAL, return true. */
- tst = compare_values_warnv (vr->max (), val, strict_overflow_p);
+ tst = compare_values_warnv (max, val, strict_overflow_p);
if ((comp == LT_EXPR && tst == -1)
|| (comp == LE_EXPR && (tst == -1 || tst == 0)))
return boolean_true_node;
/* If VR is to the right of VAL, return false. */
- tst = compare_values_warnv (vr->min (), val, strict_overflow_p);
+ tst = compare_values_warnv (min, val, strict_overflow_p);
if ((comp == LT_EXPR && (tst == 0 || tst == 1))
|| (comp == LE_EXPR && tst == 1))
return boolean_false_node;
@@ -440,13 +453,13 @@ compare_range_with_value (enum tree_code comp, const value_range *vr,
int tst;
/* If VR is to the right of VAL, return true. */
- tst = compare_values_warnv (vr->min (), val, strict_overflow_p);
+ tst = compare_values_warnv (min, val, strict_overflow_p);
if ((comp == GT_EXPR && tst == 1)
|| (comp == GE_EXPR && (tst == 0 || tst == 1)))
return boolean_true_node;
/* If VR is to the left of VAL, return false. */
- tst = compare_values_warnv (vr->max (), val, strict_overflow_p);
+ tst = compare_values_warnv (max, val, strict_overflow_p);
if ((comp == GT_EXPR && (tst == -1 || tst == 0))
|| (comp == GE_EXPR && tst == -1))
return boolean_false_node;
@@ -544,11 +557,12 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
/* Try to use estimated number of iterations for the loop to constrain the
final value in the evolution. */
+ tree rmin, rmax;
if (TREE_CODE (step) == INTEGER_CST
&& is_gimple_val (init)
&& (TREE_CODE (init) != SSA_NAME
|| (query->range_of_expr (r, init, stmt)
- && r.kind () == VR_RANGE)))
+ && get_legacy_range (r, rmin, rmax) == VR_RANGE)))
{
widest_int nit;
@@ -584,9 +598,12 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
range_op_handler handler (PLUS_EXPR, TREE_TYPE (init));
if (!handler.fold_range (maxvr, TREE_TYPE (init), vr0, vr1))
maxvr.set_varying (TREE_TYPE (init));
+ tree maxvr_min, maxvr_max;
+ value_range_kind maxvr_kind
+ = get_legacy_range (maxvr, maxvr_min, maxvr_max);
/* Likewise if the addition did. */
- if (maxvr.kind () == VR_RANGE)
+ if (maxvr_kind == VR_RANGE)
{
int_range<2> initvr;
@@ -597,18 +614,21 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
else
return false;
+ tree initvr_min, initvr_max;
+ get_legacy_range (initvr, initvr_min, initvr_max);
+
/* Check if init + nit * step overflows. Though we checked
scev {init, step}_loop doesn't wrap, it is not enough
because the loop may exit immediately. Overflow could
happen in the plus expression in this case. */
if ((dir == EV_DIR_DECREASES
- && compare_values (maxvr.min (), initvr.min ()) != -1)
+ && compare_values (maxvr_min, initvr_min) != -1)
|| (dir == EV_DIR_GROWS
- && compare_values (maxvr.max (), initvr.max ()) != 1))
+ && compare_values (maxvr_max, initvr_max) != 1))
return false;
- tmin = maxvr.min ();
- tmax = maxvr.max ();
+ tmin = maxvr_min;
+ tmax = maxvr_max;
}
}
}
@@ -810,7 +830,8 @@ find_case_label_ranges (gswitch *stmt, const value_range *vr,
unsigned int n = gimple_switch_num_labels (stmt);
bool take_default;
tree case_low, case_high;
- tree min = vr->min (), max = vr->max ();
+ tree min, max;
+ value_range_kind kind = get_legacy_range (*vr, min, max);
gcc_checking_assert (!vr->varying_p () && !vr->undefined_p ());
@@ -820,7 +841,7 @@ find_case_label_ranges (gswitch *stmt, const value_range *vr,
*min_idx2 = 1;
*max_idx2 = 0;
- if (vr->kind () == VR_RANGE)
+ if (kind == VR_RANGE)
{
*min_idx1 = i;
*max_idx1 = j;
@@ -1724,8 +1745,10 @@ simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt)
/* We can truncate the case label ranges that partially overlap with OP's
value range. */
size_t min_idx = 1, max_idx = 0;
+ tree min, max;
+ value_range_kind kind = get_legacy_range (vr, min, max);
if (!vr.undefined_p ())
- find_case_label_range (stmt, vr.min (), vr.max (), &min_idx, &max_idx);
+ find_case_label_range (stmt, min, max, &min_idx, &max_idx);
if (min_idx <= max_idx)
{
tree min_label = gimple_switch_label (stmt, min_idx);
@@ -1733,10 +1756,10 @@ simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt)
/* Avoid changing the type of the case labels when truncating. */
tree case_label_type = TREE_TYPE (CASE_LOW (min_label));
- tree vr_min = fold_convert (case_label_type, vr.min ());
- tree vr_max = fold_convert (case_label_type, vr.max ());
+ tree vr_min = fold_convert (case_label_type, min);
+ tree vr_max = fold_convert (case_label_type, max);
- if (vr.kind () == VR_RANGE)
+ if (kind == VR_RANGE)
{
/* If OP's value range is [2,8] and the low label range is
0 ... 3, truncate the label's range to 2 .. 3. */
@@ -1752,7 +1775,7 @@ simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt)
&& tree_int_cst_compare (CASE_HIGH (max_label), vr_max) > 0)
CASE_HIGH (max_label) = vr_max;
}
- else if (vr.kind () == VR_ANTI_RANGE)
+ else if (kind == VR_ANTI_RANGE)
{
tree one_cst = build_one_cst (case_label_type);