Hi,

On Mon, 9 Nov 2020 at 15:43, Aldy Hernandez via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> [This is actually part of a larger patch that actually changes
> behavior, but I thought I'd commit the non-invasive cleanups first
> which will simplify the upcoming work.]
>
> irange::set was doing more work than it should for legacy ranges.
> I cleaned up various unnecessary calls to swap_out_of_order_endpoints,
> as well as some duplicate code that could be done with normalize_min_max.
>
> I also removed an obsolete comment wrt sticky infinite overflows.
> Not only did the -INF/+INF(OVF) code get removed in 2017,
> but normalize_min_max() uses wide ints, which ignored overflows
> altogether.
>
> Pushed.
>
> gcc/ChangeLog:
>
>         * value-range.cc (irange::swap_out_of_order_endpoints): Rewrite
>         into static function.
>         (irange::set): Cleanup redundant manipulations.
>         * value-range.h (irange::normalize_min_max): Modify object
>         in-place instead of modifying arguments.


This is causing regressions on aarch64, such as:
FAIL: gcc.target/aarch64/pr88838.c (internal compiler error)
FAIL: gcc.target/aarch64/pr88838.c (test for excess errors)
Excess errors:
during GIMPLE pass: dom
/gcc/testsuite/gcc.target/aarch64/pr88838.c:5:1: internal compiler
error: tree check: expected integer_cst, have poly_int_cst in to_wide,
at tree.h:5950
0x66741d tree_check_failed(tree_node const*, char const*, int, char const*, ...)
        /gcc/tree.c:9754
0x6404e8 tree_check
        /gcc/tree.h:3570
0x6404e8 to_wide
        /gcc/tree.h:5950
0x7f0816 wi::to_wide(tree_node const*)
        /gcc/tree.h:3505
0x1118bdc irange::legacy_upper_bound(unsigned int) const
        /gcc/value-range.cc:447
0x1122cd4 irange::upper_bound(unsigned int) const
        /gcc/value-range.h:510
0x19493be range_operator::fold_range(irange&, tree_node*, irange
const&, irange const&) const
        /gcc/range-op.cc:159
0x19494f4 range_operator::fold_range(irange&, tree_node*, irange
const&, irange const&) const
        /gcc/range-op.cc:74
0x10cfee6 range_fold_binary_expr(int_range<1u>*, tree_code,
tree_node*, int_range<1u> const*, int_range<1u> const*)
        /gcc/tree-vrp.c:1243
0x116fda4 vr_values::extract_range_from_binary_expr(value_range_equiv*,
tree_code, tree_node*, tree_node*, tree_node*)
        /gcc/vr-values.c:853
0x1178b3c vr_values::extract_range_from_assignment(value_range_equiv*, gassign*)
        /gcc/vr-values.c:1564
0x185bcbe evrp_range_analyzer::record_ranges_from_stmt(gimple*, bool)
        /gcc/gimple-ssa-evrp-analyze.c:304
0xee7f9b dom_opt_dom_walker::before_dom_children(basic_block_def*)
        /gcc/tree-ssa-dom.c:1458
0x1817487 dom_walker::walk(basic_block_def*)
        /gcc/domwalk.c:309
0xee4f8b execute
        /gcc/tree-ssa-dom.c:724


(actually I can see 3245 ICEs on aarch64)

Can you fix it?

Thanks

> ---
>  gcc/value-range.cc | 70 ++++++++++++++++------------------------------
>  gcc/value-range.h  | 28 +++++++++----------
>  2 files changed, 37 insertions(+), 61 deletions(-)
>
> diff --git a/gcc/value-range.cc b/gcc/value-range.cc
> index 5827e812216..2124e229e0c 100644
> --- a/gcc/value-range.cc
> +++ b/gcc/value-range.cc
> @@ -131,13 +131,14 @@ irange::copy_to_legacy (const irange &src)
>      set (src.tree_lower_bound (), src.tree_upper_bound ());
>  }
>
> -// Swap min/max if they are out of order.  Return TRUE if further
> -// processing of the range is necessary, FALSE otherwise.
> +// Swap MIN/MAX if they are out of order and adjust KIND appropriately.
>
> -bool
> -irange::swap_out_of_order_endpoints (tree &min, tree &max,
> -                                         value_range_kind &kind)
> +static void
> +swap_out_of_order_endpoints (tree &min, tree &max, value_range_kind &kind)
>  {
> +  gcc_checking_assert (kind != VR_UNDEFINED);
> +  if (kind == VR_VARYING)
> +    return;
>    /* Wrong order for min and max, to swap them and the VR type we need
>       to adjust them.  */
>    if (tree_int_cst_lt (max, min))
> @@ -149,8 +150,8 @@ irange::swap_out_of_order_endpoints (tree &min, tree &max,
>          for VR_ANTI_RANGE empty range, so drop to varying as well.  */
>        if (TYPE_PRECISION (TREE_TYPE (min)) == 1)
>         {
> -         set_varying (TREE_TYPE (min));
> -         return false;
> +         kind = VR_VARYING;
> +         return;
>         }
>
>        one = build_int_cst (TREE_TYPE (min), 1);
> @@ -163,12 +164,11 @@ irange::swap_out_of_order_endpoints (tree &min, tree 
> &max,
>          to varying in this case.  */
>        if (tree_int_cst_lt (max, min))
>         {
> -         set_varying (TREE_TYPE (min));
> -         return false;
> +         kind = VR_VARYING;
> +         return;
>         }
>        kind = kind == VR_RANGE ? VR_ANTI_RANGE : VR_RANGE;
>      }
> -  return true;
>  }
>
>  void
> @@ -253,13 +253,6 @@ irange::set (tree min, tree max, value_range_kind kind)
>        && (POLY_INT_CST_P (min) || POLY_INT_CST_P (max)))
>      kind = VR_VARYING;
>
> -  if (kind == VR_VARYING)
> -    {
> -      set_varying (TREE_TYPE (min));
> -      return;
> -    }
> -
> -  tree type = TREE_TYPE (min);
>    // Nothing to canonicalize for symbolic ranges.
>    if (TREE_CODE (min) != INTEGER_CST
>        || TREE_CODE (max) != INTEGER_CST)
> @@ -270,8 +263,13 @@ irange::set (tree min, tree max, value_range_kind kind)
>        m_num_ranges = 1;
>        return;
>      }
> -  if (!swap_out_of_order_endpoints (min, max, kind))
> -    goto cleanup_set;
> +
> +  swap_out_of_order_endpoints (min, max, kind);
> +  if (kind == VR_VARYING)
> +    {
> +      set_varying (TREE_TYPE (min));
> +      return;
> +    }
>
>    // Anti-ranges that can be represented as ranges should be so.
>    if (kind == VR_ANTI_RANGE)
> @@ -280,6 +278,7 @@ irange::set (tree min, tree max, value_range_kind kind)
>           values < -INF and values > INF as -INF/INF as well.  */
>        bool is_min = vrp_val_is_min (min);
>        bool is_max = vrp_val_is_max (max);
> +      tree type = TREE_TYPE (min);
>
>        if (is_min && is_max)
>         {
> @@ -314,38 +313,17 @@ irange::set (tree min, tree max, value_range_kind kind)
>           kind = VR_RANGE;
>          }
>      }
> -  else if (!swap_out_of_order_endpoints (min, max, kind))
> -    goto cleanup_set;
> -
> -  /* Do not drop [-INF(OVF), +INF(OVF)] to varying.  (OVF) has to be sticky
> -     to make sure VRP iteration terminates, otherwise we can get into
> -     oscillations.  */
> -  if (!normalize_min_max (type, min, max, kind))
> -    {
> -      m_kind = kind;
> -      m_base[0] = min;
> -      m_base[1] = max;
> -      m_num_ranges = 1;
> -      if (flag_checking)
> -       verify_range ();
> -    }
>
> - cleanup_set:
> -  // Avoid using TYPE_{MIN,MAX}_VALUE because -fstrict-enums can
> -  // restrict those to a subset of what actually fits in the type.
> -  // Instead use the extremes of the type precision
> -  unsigned prec = TYPE_PRECISION (type);
> -  signop sign = TYPE_SIGN (type);
> -  if (wi::eq_p (wi::to_wide (min), wi::min_value (prec, sign))
> -      && wi::eq_p (wi::to_wide (max), wi::max_value (prec, sign)))
> -    m_kind = VR_VARYING;
> -  else if (undefined_p ())
> -    m_kind = VR_UNDEFINED;
> +  m_kind = kind;
> +  m_base[0] = min;
> +  m_base[1] = max;
> +  m_num_ranges = 1;
> +  normalize_min_max ();
>    if (flag_checking)
>      verify_range ();
>  }
>
> -/* Check the validity of the range.  */
> +// Check the validity of the range.
>
>  void
>  irange::verify_range ()
> diff --git a/gcc/value-range.h b/gcc/value-range.h
> index 760ee772316..a483fc802dd 100644
> --- a/gcc/value-range.h
> +++ b/gcc/value-range.h
> @@ -111,8 +111,7 @@ protected:
>    void irange_set (tree, tree);
>    void irange_set_anti_range (tree, tree);
>
> -  bool swap_out_of_order_endpoints (tree &min, tree &max, value_range_kind 
> &);
> -  bool normalize_min_max (tree type, tree min, tree max, value_range_kind);
> +  void normalize_min_max ();
>
>    bool legacy_mode_p () const;
>    bool legacy_equal_p (const irange &) const;
> @@ -566,7 +565,7 @@ irange::set_zero (tree type)
>      irange_set (z, z);
>  }
>
> -// Normalize [MIN, MAX] into VARYING and ~[MIN, MAX] into UNDEFINED.
> +// Normalize a range to VARYING or UNDEFINED if possible.
>  //
>  // Avoid using TYPE_{MIN,MAX}_VALUE because -fstrict-enums can
>  // restrict those to a subset of what actually fits in the type.
> @@ -575,24 +574,23 @@ irange::set_zero (tree type)
>  // whereas if we used TYPE_*_VAL, said function would just punt upon
>  // seeing a VARYING.
>
> -inline bool
> -irange::normalize_min_max (tree type, tree min, tree max,
> -                          value_range_kind kind)
> +inline void
> +irange::normalize_min_max ()
>  {
> -  unsigned prec = TYPE_PRECISION (type);
> -  signop sign = TYPE_SIGN (type);
> -  if (wi::eq_p (wi::to_wide (min), wi::min_value (prec, sign))
> -      && wi::eq_p (wi::to_wide (max), wi::max_value (prec, sign)))
> +  gcc_checking_assert (legacy_mode_p ());
> +  gcc_checking_assert (!undefined_p ());
> +  unsigned prec = TYPE_PRECISION (type ());
> +  signop sign = TYPE_SIGN (type ());
> +  if (wi::eq_p (wi::to_wide (min ()), wi::min_value (prec, sign))
> +      && wi::eq_p (wi::to_wide (max ()), wi::max_value (prec, sign)))
>      {
> -      if (kind == VR_RANGE)
> -       set_varying (type);
> -      else if (kind == VR_ANTI_RANGE)
> +      if (m_kind == VR_RANGE)
> +       set_varying (type ());
> +      else if (m_kind == VR_ANTI_RANGE)
>         set_undefined ();
>        else
>         gcc_unreachable ();
> -      return true;
>      }
> -  return false;
>  }
>
>  // Return the maximum value for TYPE.
> --
> 2.26.2
>

Reply via email to