From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2136) id 322283855585; Wed, 26 Apr 2023 08:36:59 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 322283855585 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1682498219; bh=idNMEcFgqwk+sC+yJkLlaHT/XgtFOyOl8UQnSY1UXwM=; h=From:To:Subject:Date:From; b=nBzWg2mSyoGreO+hvJKC72tI4pUZHPSthPFMQZDs+L4qe8SZspJ1Mi+tLB299/HNV 3RrKGJTqHdmP1CweJYOrMPEkWsMGzF4hs0JawpWFe3nqkBWPpsxaT+d9A/gCjnqECW 0UHGHbClsMUnRcAQOzCBvM7TeiYKzUNSMJKYnZDQ= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Aldy Hernandez To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-254] Convert users of legacy API to get_legacy_range() function. X-Act-Checkin: gcc X-Git-Author: Aldy Hernandez X-Git-Refname: refs/heads/master X-Git-Oldrev: 964b02cb26df1016d036de6720e9d4decf87cc6f X-Git-Newrev: 5bdc5155138abeb244be1690998b359152445be6 Message-Id: <20230426083659.322283855585@sourceware.org> Date: Wed, 26 Apr 2023 08:36:59 +0000 (GMT) List-Id: https://gcc.gnu.org/g:5bdc5155138abeb244be1690998b359152445be6 commit r14-254-g5bdc5155138abeb244be1690998b359152445be6 Author: Aldy Hernandez Date: Thu Mar 2 15:43:20 2023 +0100 Convert users of legacy API to get_legacy_range() function. This patch converts the users of the legacy API to a function called get_legacy_range() which will return the pieces of the soon to be removed API (min, max, and kind). This is a temporary measure while these users are converted. In upcoming patches I will convert most users, but most of the middle-end warning uses will remain. Naive attempts to remove them showed that a lot of these uses are quite dependant on the anti-range idiom, and converting them to the new API broke the tests, even when the conversion was conceptually correct. Perhaps someone who understands these passes could take a stab at it. In the meantime, the legacy uses can be trivially found by grepping for get_legacy_range. gcc/ChangeLog: * builtins.cc (determine_block_size): Convert use of legacy API to get_legacy_range. * gimple-array-bounds.cc (check_out_of_bounds_and_warn): Same. (array_bounds_checker::check_array_ref): Same. * gimple-ssa-warn-restrict.cc (builtin_memref::extend_offset_range): Same. * ipa-cp.cc (ipcp_store_vr_results): Same. * ipa-fnsummary.cc (set_switch_stmt_execution_predicate): Same. * ipa-prop.cc (struct ipa_vr_ggc_hash_traits): Same. (ipa_write_jump_function): Same. * pointer-query.cc (get_size_range): Same. * tree-data-ref.cc (split_constant_offset): Same. * tree-ssa-strlen.cc (get_range): Same. (maybe_diag_stxncpy_trunc): Same. (strlen_pass::get_len_or_size): Same. (strlen_pass::count_nonzero_bytes_addr): Same. * tree-vect-patterns.cc (vect_get_range_info): Same. * value-range.cc (irange::maybe_anti_range): Remove. (get_legacy_range): New. (irange::copy_to_legacy): Use get_legacy_range. (ranges_from_anti_range): Same. * value-range.h (class irange): Remove maybe_anti_range. (get_legacy_range): New. * vr-values.cc (check_for_binary_op_overflow): Convert use of legacy API to get_legacy_range. (compare_ranges): Same. (compare_range_with_value): Same. (bounds_of_var_in_loop): Same. (find_case_label_ranges): Same. (simplify_using_ranges::simplify_switch_using_ranges): Same. Diff: --- gcc/builtins.cc | 7 ++- gcc/gimple-array-bounds.cc | 9 ++- gcc/gimple-ssa-warn-restrict.cc | 7 ++- gcc/ipa-cp.cc | 7 ++- gcc/ipa-fnsummary.cc | 7 ++- gcc/ipa-prop.cc | 16 ++++-- gcc/pointer-query.cc | 7 ++- gcc/tree-data-ref.cc | 7 ++- gcc/tree-ssa-strlen.cc | 29 ++++++---- gcc/tree-vect-patterns.cc | 7 ++- gcc/value-range.cc | 89 ++++++++++++++++++++--------- gcc/value-range.h | 3 +- gcc/vr-values.cc | 123 ++++++++++++++++++++++++---------------- 13 files changed, 199 insertions(+), 119 deletions(-) diff --git a/gcc/builtins.cc b/gcc/builtins.cc index 0e06fa5b2e0..bb931242c9c 100644 --- a/gcc/builtins.cc +++ b/gcc/builtins.cc @@ -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) diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc index 775f0c13258..e04c8e29d5a 100644 --- a/gcc/gimple-array-bounds.cc +++ b/gcc/gimple-array-bounds.cc @@ -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; } } diff --git a/gcc/gimple-ssa-warn-restrict.cc b/gcc/gimple-ssa-warn-restrict.cc index ee7040a881d..56aed519b6d 100644 --- a/gcc/gimple-ssa-warn-restrict.cc +++ b/gcc/gimple-ssa-warn-restrict.cc @@ -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); } } diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc index 6788883c40b..9ec86d77992 100644 --- a/gcc/ipa-cp.cc +++ b/gcc/ipa-cp.cc @@ -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 { diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc index 03142960e60..48093a8b623 100644 --- a/gcc/ipa-fnsummary.cc +++ b/gcc/ipa-fnsummary.cc @@ -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) { diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc index f706f099f7a..1a8ff7ebb95 100644 --- a/gcc/ipa-prop.cc +++ b/gcc/ipa-prop.cc @@ -118,9 +118,11 @@ struct ipa_vr_ggc_hash_traits : public ggc_cache_remove 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); } } diff --git a/gcc/pointer-query.cc b/gcc/pointer-query.cc index 5b05e9bedf8..9723358f965 100644 --- a/gcc/pointer-query.cc +++ b/gcc/pointer-query.cc @@ -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; diff --git a/gcc/tree-data-ref.cc b/gcc/tree-data-ref.cc index 23602518665..4ebd839db15 100644 --- a/gcc/tree-data-ref.cc +++ b/gcc/tree-data-ref.cc @@ -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, diff --git a/gcc/tree-ssa-strlen.cc b/gcc/tree-ssa-strlen.cc index 7508c1768a5..1d79034594b 100644 --- a/gcc/tree-ssa-strlen.cc +++ b/gcc/tree-ssa-strlen.cc @@ -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; diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc index a49b0953977..b964dcb8ad9 100644 --- a/gcc/tree-vect-patterns.cc +++ b/gcc/tree-vect-patterns.cc @@ -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, diff --git a/gcc/value-range.cc b/gcc/value-range.cc index 58ae2c157db..a50d1a63968 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -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 ()) { diff --git a/gcc/value-range.h b/gcc/value-range.h index 2442f8eed70..c1474a73eaf 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -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); diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc index ba569b3f72f..f43de63b4f4 100644 --- a/gcc/vr-values.cc +++ b/gcc/vr-values.cc @@ -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);