Le 26/10/2023 à 11:29, Richard Biener a écrit :
On Wed, Oct 25, 2023 at 5:51 AM Andrew Pinski <pins...@gmail.com> wrote:
diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 40767736389..2a2a90230f5 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -15047,15 +15047,33 @@ tree_single_nonnegative_warnv_p (tree t, bool 
*strict_overflow_p, int depth)
        return RECURSE (TREE_OPERAND (t, 1)) && RECURSE (TREE_OPERAND (t, 2));

      case SSA_NAME:
-      /* Limit the depth of recursion to avoid quadratic behavior.
-        This is expected to catch almost all occurrences in practice.
-        If this code misses important cases that unbounded recursion
-        would not, passes that need this information could be revised
-        to provide it through dataflow propagation.  */
-      return (!name_registered_for_update_p (t)
-             && depth < param_max_ssa_name_query_depth
-             && gimple_stmt_nonnegative_warnv_p (SSA_NAME_DEF_STMT (t),
-                                                 strict_overflow_p, depth));
+      {
+       /* For integral types, querry the global range if possible. */

query

+       if (INTEGRAL_TYPE_P (TREE_TYPE (t)))
+         {
+           value_range vr;
+           if (get_global_range_query ()->range_of_expr (vr, t)
+               && !vr.varying_p () && !vr.undefined_p ())
+             {
+               /* If the range is nonnegative, return true. */
+               if (vr.nonnegative_p ())
+                 return true;
+
+               /* If the range is non-positive, then return false. */
+               if (vr.nonpositive_p ())
+                 return false;

That's testing for <= 0, nonnegative for >= 0.  This means when
vr.nonpositive_p () the value could still be zero (and nonnegative),
possibly be figured out by the recursion below.

Since we don't have negative_p () do we want to test
nonpositive_p () && nonzero_p () instead?


Maybe !contains_zero_p () instead of nonzero_p () ?

nonzero_p seems to check that the range is exactly the "all but zero" range as visible in the implementation:

  inline bool
  irange::nonzero_p () const
  {
    if (undefined_p ())
      return false;

    wide_int zero = wi::zero (TYPE_PRECISION (type ()));
    return *this == int_range<2> (type (), zero, zero, VR_ANTI_RANGE);
  }

Reply via email to