---------- Forwarded message ---------
From: Aldy Hernandez <al...@redhat.com>
Date: Tue, Aug 4, 2020, 13:34
Subject: [PATCH] Adjust tree-ssa-strlen.c for irange API.
To: <gcc-patches@gcc.gnu.org>
Cc: <l...@redhat.com>, <mse...@redhat.com>, Aldy Hernandez <al...@redhat.com>


This patch adapts the strlen pass to use the irange API.

I wasn't able to remove the one annoying use of VR_ANTI_RANGE, because
I'm not sure what to do.  Perhaps Martin can shed some light.  The
current code has:

  else if (rng == VR_ANTI_RANGE)
        {
          wide_int maxobjsize = wi::to_wide (TYPE_MAX_VALUE
(ptrdiff_type_node));
          if (wi::ltu_p (cntrange[1], maxobjsize))
            {
              cntrange[0] = cntrange[1] + 1;
              cntrange[1] = maxobjsize;

Suppose we have ~[10,20], won't the above set cntrange[] to [21,MAX]?  Won't
this ignore the 0..9 that is part of the range?  What should we do here?

Anyways, I've left the anti-range in place, but the rest of the patch still
stands.

OK?

gcc/ChangeLog:

        * tree-ssa-strlen.c (get_range): Adjust for irange API.
        (compare_nonzero_chars): Same.
        (dump_strlen_info): Same.
        (get_range_strlen_dynamic): Same.
        (set_strlen_range): Same.
        (maybe_diag_stxncpy_trunc): Same.
        (get_len_or_size): Same.
        (count_nonzero_bytes_addr): Same.
        (handle_integral_assign): Same.
---
 gcc/tree-ssa-strlen.c | 122 ++++++++++++++++++++----------------------
 1 file changed, 57 insertions(+), 65 deletions(-)

diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index fbaee745f7d..e6009874ee5 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -220,21 +220,25 @@ get_range (tree val, wide_int minmax[2], const
vr_values *rvals /* = NULL */)
         GCC 11).  */
       const value_range *vr
        = (CONST_CAST (class vr_values *, rvals)->get_value_range (val));
-      value_range_kind rng = vr->kind ();
-      if (rng != VR_RANGE || !range_int_cst_p (vr))
+      if (vr->undefined_p () || vr->varying_p ())
        return NULL_TREE;

-      minmax[0] = wi::to_wide (vr->min ());
-      minmax[1] = wi::to_wide (vr->max ());
+      minmax[0] = vr->lower_bound ();
+      minmax[1] = vr->upper_bound ();
       return val;
     }

-  value_range_kind rng = get_range_info (val, minmax, minmax + 1);
-  if (rng == VR_RANGE)
-    return val;
+  value_range vr;
+  get_range_info (val, vr);
+  if (!vr.undefined_p () && !vr.varying_p ())
+    {
+      minmax[0] = vr.lower_bound ();
+      minmax[1] = vr.upper_bound ();
+      return val;
+    }

-  /* Do not handle anti-ranges and instead make use of the on-demand
-     VRP if/when it becomes available (hopefully in GCC 11).  */
+  /* We should adjust for the on-demand VRP if/when it becomes
+     available (hopefully in GCC 11).  */
   return NULL_TREE;
 }

@@ -278,16 +282,18 @@ compare_nonzero_chars (strinfo *si, unsigned
HOST_WIDE_INT off,
     = (CONST_CAST (class vr_values *, rvals)
        ->get_value_range (si->nonzero_chars));

-  value_range_kind rng = vr->kind ();
-  if (rng != VR_RANGE || !range_int_cst_p (vr))
+  if (vr->undefined_p () || vr->varying_p ())
     return -1;

   /* If the offset is less than the minimum length or if the bounds
      of the length range are equal return the result of the comparison
      same as in the constant case.  Otherwise return a conservative
      result.  */
-  int cmpmin = compare_tree_int (vr->min (), off);
-  if (cmpmin > 0 || tree_int_cst_equal (vr->min (), vr->max ()))
+  tree type = TREE_TYPE (si->nonzero_chars);
+  tree tmin = wide_int_to_tree (type, vr->lower_bound ());
+  tree tmax = wide_int_to_tree (type, vr->upper_bound ());
+  int cmpmin = compare_tree_int (tmin, off);
+  if (cmpmin > 0 || tree_int_cst_equal (tmin, tmax))
     return cmpmin;

   return -1;
@@ -905,32 +911,14 @@ dump_strlen_info (FILE *fp, gimple *stmt, const
vr_values *rvals)
                  print_generic_expr (fp, si->nonzero_chars);
                  if (TREE_CODE (si->nonzero_chars) == SSA_NAME)
                    {
-                     value_range_kind rng = VR_UNDEFINED;
-                     wide_int min, max;
+                     value_range vr;
                      if (rvals)
-                       {
-                         const value_range *vr
-                           = CONST_CAST (class vr_values *, rvals)
-                           ->get_value_range (si->nonzero_chars);
-                         rng = vr->kind ();
-                         if (range_int_cst_p (vr))
-                           {
-                             min = wi::to_wide (vr->min ());
-                             max = wi::to_wide (vr->max ());
-                           }
-                         else
-                           rng = VR_UNDEFINED;
-                       }
+                       vr = *(CONST_CAST (class vr_values *, rvals)
+                              ->get_value_range (si->nonzero_chars));
                      else
-                       rng = get_range_info (si->nonzero_chars, &min,
&max);
-
-                     if (rng == VR_RANGE || rng == VR_ANTI_RANGE)
-                       {
-                         fprintf (fp, " %s[%llu, %llu]",
-                                  rng == VR_RANGE ? "" : "~",
-                                  (long long) min.to_uhwi (),
-                                  (long long) max.to_uhwi ());
-                       }
+                       get_range_info (si->nonzero_chars, vr);
+                     vr.normalize_symbolics ();
+                     vr.dump (fp);
                    }
                }

@@ -1113,11 +1101,13 @@ get_range_strlen_dynamic (tree src, c_strlen_data
*pdata, bitmap *visited,
              const value_range_equiv *vr
                = CONST_CAST (class vr_values *, rvals)
                ->get_value_range (si->nonzero_chars);
-             if (vr->kind () == VR_RANGE
-                 && range_int_cst_p (vr))
+             if (!vr->undefined_p () && !vr->varying_p ())
                {
-                 pdata->minlen = vr->min ();
-                 pdata->maxlen = vr->max ();
+                 tree type = TREE_TYPE (si->nonzero_chars);
+                 tree tmin = wide_int_to_tree (type, vr->lower_bound ());
+                 tree tmax = wide_int_to_tree (type, vr->upper_bound ());
+                 pdata->minlen = tmin;
+                 pdata->maxlen = tmax;
                }
              else
                pdata->minlen = build_zero_cst (size_type_node);
@@ -1159,11 +1149,11 @@ get_range_strlen_dynamic (tree src, c_strlen_data
*pdata, bitmap *visited,
          const value_range_equiv *vr
            = CONST_CAST (class vr_values *, rvals)
            ->get_value_range (si->nonzero_chars);
-         if (vr->kind () == VR_RANGE
-             && range_int_cst_p (vr))
+         if (!vr->undefined_p () && !vr->varying_p ())
            {
-             pdata->minlen = vr->min ();
-             pdata->maxlen = vr->max ();
+             tree type = TREE_TYPE (si->nonzero_chars);
+             pdata->minlen = wide_int_to_tree (type, vr->lower_bound ());
+             pdata->maxlen = wide_int_to_tree (type, vr->upper_bound ());
              pdata->maxbound = pdata->maxlen;
            }
          else
@@ -1803,12 +1793,14 @@ set_strlen_range (tree lhs, wide_int min, wide_int
max,
       else if (TREE_CODE (bound) == SSA_NAME)
        {
          wide_int minbound, maxbound;
-         value_range_kind rng = get_range_info (bound, &minbound,
&maxbound);
-         if (rng == VR_RANGE)
+         value_range vr;
+         get_range_info (bound, vr);
+         if (!vr.undefined_p () && !vr.varying_p ())
            {
+             wide_int minbound = vr.lower_bound ();
+             wide_int maxbound = vr.upper_bound ();
              /* For a bound in a known range, adjust the range determined
-                above as necessary.  For a bound in some anti-range or
-                in an unknown range, use the range determined by callers.
*/
+                above as necessary.  */
              if (wi::ltu_p (minbound, min))
                min = minbound;
              if (wi::ltu_p (maxbound, max))
@@ -3045,6 +3037,8 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi,
tree src, tree cnt)

          if (wi::ltu_p (cntrange[1], maxobjsize))
            {
+             /* FIXME: Imagine ~[10,20].  The code here will set
+                cntrange[] to [21,MAX].  Why are we ignoring [0,9] ??  */
              cntrange[0] = cntrange[1] + 1;
              cntrange[1] = maxobjsize;
            }
@@ -4139,10 +4133,12 @@ get_len_or_size (tree arg, int idx, unsigned
HOST_WIDE_INT lenrng[2],
        }
       else if (TREE_CODE (si->nonzero_chars) == SSA_NAME)
        {
-         wide_int min, max;
-         value_range_kind rng = get_range_info (si->nonzero_chars, &min,
&max);
-         if (rng == VR_RANGE)
+         value_range vr;
+         get_range_info (si->nonzero_chars, vr);
+         if (!vr.undefined_p () && !vr.varying_p ())
            {
+             wide_int min = vr.lower_bound ();
+             wide_int max = vr.upper_bound ();
              lenrng[0] = min.to_uhwi ();
              lenrng[1] = max.to_uhwi ();
              *nulterm = si->full_string_p;
@@ -4847,11 +4843,11 @@ count_nonzero_bytes_addr (tree exp, unsigned
HOST_WIDE_INT offset,
        {
          vr_values *v = CONST_CAST (vr_values *, rvals);
          const value_range_equiv *vr = v->get_value_range
(si->nonzero_chars);
-         if (vr->kind () != VR_RANGE || !range_int_cst_p (vr))
+         if (vr->undefined_p () || vr->varying_p ())
            return false;
-
-         minlen = tree_to_uhwi (vr->min ());
-         maxlen = tree_to_uhwi (vr->max ());
+         tree type = TREE_TYPE (si->nonzero_chars);
+         minlen = tree_to_uhwi (wide_int_to_tree (type, vr->lower_bound
()));
+         maxlen = tree_to_uhwi (wide_int_to_tree (type, vr->upper_bound
()));
        }
       else
        return false;
@@ -5554,16 +5550,12 @@ handle_integral_assign (gimple_stmt_iterator *gsi,
bool *cleanup_eh,
                  /* Reading a character before the final '\0'
                     character.  Just set the value range to ~[0, 0]
                     if we don't have anything better.  */
-                 wide_int min, max;
-                 signop sign = TYPE_SIGN (lhs_type);
-                 int prec = TYPE_PRECISION (lhs_type);
-                 value_range_kind vr = get_range_info (lhs, &min, &max);
-                 if (vr == VR_VARYING
-                     || (vr == VR_RANGE
-                         && min == wi::min_value (prec, sign)
-                         && max == wi::max_value (prec, sign)))
+                 value_range vr;
+                 get_range_info (lhs, vr);
+                 if (vr.varying_p ())
                    set_range_info (lhs, VR_ANTI_RANGE,
-                                   wi::zero (prec), wi::zero (prec));
+                                   wi::zero (TYPE_PRECISION (lhs_type)),
+                                   wi::zero (TYPE_PRECISION (lhs_type)));
                }
            }
        }
-- 
2.26.2

Reply via email to