public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Biener <rguenther@suse.de>
To: Aldy Hernandez <aldyh@redhat.com>
Cc: gcc-patches@gcc.gnu.org, Andrew MacLeod <amacleod@redhat.com>
Subject: Re: [PATCH] Fixup possible VR_ANTI_RANGE value_range issues
Date: Tue, 28 Feb 2023 09:41:12 +0000 (UTC)	[thread overview]
Message-ID: <nycvar.YFH.7.77.849.2302280907000.27913@jbgna.fhfr.qr> (raw)
In-Reply-To: <98102d74-cb30-0190-af66-86800e0721e4@redhat.com>

On Mon, 27 Feb 2023, Aldy Hernandez wrote:

> 
> 
> On 2/27/23 14:58, Richard Biener wrote:
> > After fixing PR107561 the following avoids looking at VR_ANTI_RANGE
> > ranges where it doesn't seem obvious the code does the correct
> > thing here (lower_bound and upper_bound do not work as expected).
> 
> I do realize there's some confusion here, and some of it is my fault. This has
> become obvious in my upcoming work removing all of legacy.
> 
> What's going on is that ultimately min/max are broken with (non-legacy)
> iranges.  Or at the very least inconsistent between legacy and non-legacy.
> These are left over from the legacy world, and have been marked DEPRECATED for
> a few releases, but the middle end warnings continued to use them and even
> added new uses after they were obsoleted.
> 
> min/max have different meanings depending on kind(), which is also deprecated,
> btw.  They are the underlying min/max fields from the legacy implementation,
> and thus somewhat leak the implementation details. Unfortunately, they are
> being called from non-legacy code which is ignoring the kind() field.
> 
> In retrospect I should've converted everything away from min/max/kind years
> ago, or at the very least converted min/max to work with non-legacy more
> consistently.
> 
> For the record:
> 
>   enum value_range_kind kind () const;		// DEPRECATED
>   tree min () const;				// DEPRECATED
>   tree max () const;				// DEPRECATED
>   bool symbolic_p () const;			// DEPRECATED
>   bool constant_p () const;			// DEPRECATED
>   void normalize_symbolics ();			// DEPRECATED
>   void normalize_addresses ();			// DEPRECATED
>   bool may_contain_p (tree) const;		// DEPRECATED
>   bool legacy_verbose_union_ (const class irange *);	// DEPRECATED
>   bool legacy_verbose_intersect (const irange *);	// DEPRECATED
> 
> In my local branch I tried converting all the middle-end legacy API uses to
> the new API, but a bunch of tests started failing, and lots more false
> positives started showing up in correct code.  I suspect that's part of the
> reason legacy continued to be used in these passes :-/.  As you point out in
> the PR, the tests seem designed to test the current (at times broken)
> implementation.
> 
> That being said, the 5 fixes in your patch are not wrong to begin with,
> because all uses guard lower_bound() and upper_bound() which work correctly.
> They return the lowest and uppermost possible bound for the range (ignoring
> the underlying implementation).  So, the lower bound of a signed non-zero is
> -INF because ~[0,0] is really [-INF,-1][1,+INF]. In the min/max legacy code,
> min() of signed non-zero (~[0,0]) is 0.  The new implementation has no concept
> of anti-ranges, and we don't leak any of that out.
> 
> Any uses of min/max without looking at kind() are definitely broken. OTOH uses
> of lower/upper_bound are fine and should work with both legacy and non-legacy.
> 
> Unrelated, but one place where I haven't been able to convince myself that the
> use is correct is bounds_of_var_in_loop:
> 
> > /* 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)
> >         || (dir == EV_DIR_GROWS
> >      && compare_values (maxvr.max (), initvr.max ()) != 1))
> 
> Ughh...this is all slated to go away, and I have patches removing all of
> legacy and the old API.
> 
> Does this help?  Do you still think lower and upper bound are not working as
> expected?

lower_bound/upper_bound work as expected, 
tree_lower_bound/tree_upper_bound do not.  I've checked and all uses
I "fixed" use lower_bound/upper_boud.

tree_lower_bound & friends are 'protected', but in the above light the
comment

  // potential promotion to public?

looks dangerous (I was considering using them ...).

I'm dropping the patch, it's probably time to work on getting rid of
'value_range' uses (aka legacy_mode_p ()) and/or replace raw accesses
to the min/max for that mode with m_base accesses?  At least
that there's tree_{upper,lower}_bound for pair != 0 suggests this
function is used with differing semantics internally which is a
source of confusion (to me at least).  tree_{lower,upper}_bound
should be able to assert it's not a legacy mode range and
min/max should be able to assert that it is.

Btw, legacy_upper_bound looks wrong:

  if (m_kind == VR_ANTI_RANGE)
    {
      tree typ = type (), t;
      if (pair == 1 || vrp_val_is_min (min ()))
        t = vrp_val_max (typ);
      else
        t = wide_int_to_tree (typ, wi::to_wide (min ()) - 1);

not sure what the pair == 1 case is about, but the upper bound
of an anti-range is only special when max() is vrp_val_is_max,
aka ~[low, +INF] where it then is low - 1, but the above checks
for ~[-INF, high] and returns +INF in that case.  That's correct
unless high == +INF at least, but the else case is wrong for
all high != +INF?

I think it should be

      if (pair == 1 || !vrp_val_is_max (max ()))
        t = vrp_val_max (typ);
      else
        t = wide_int_to_tree (typ, wi::to_wide (min ()) - 1);

no?

The pair == 1 case is a mystery to me - I suppose we consider the
non-existing range to be empty?

Richard.


> Aldy
> 
> > 
> > Bootstrapped and tested on x86_64-unknown-linux-gnu.
> > 
> > OK?
> > 
> > Thanks,
> > Richard.
> > 
> >  * gimple-ssa-sprintf.cc (get_int_range): Avoid VR_ANTI_RANGE
> >  by using range_int_cst_p.
> >  (format_integer): Likewise.
> >  (handle_printf_call): Guard against VR_ANTI_RANGE.
> >  * graphite-sese-to-poly.cc (add_param_constraints): Likewise.
> >  * tree-ssa-strlen.cc (set_strlen_range): Likewise.
> > ---
> >   gcc/gimple-ssa-sprintf.cc    | 6 +++---
> >   gcc/graphite-sese-to-poly.cc | 2 +-
> >   gcc/tree-ssa-strlen.cc       | 2 +-
> >   3 files changed, 5 insertions(+), 5 deletions(-)
> > 
> > diff --git a/gcc/gimple-ssa-sprintf.cc b/gcc/gimple-ssa-sprintf.cc
> > index 18975708d2c..61974072f62 100644
> > --- a/gcc/gimple-ssa-sprintf.cc
> > +++ b/gcc/gimple-ssa-sprintf.cc
> > @@ -1082,7 +1082,7 @@ get_int_range (tree arg, gimple *stmt,
> >      value_range vr;
> >      query->range_of_expr (vr, arg, stmt);
> >   -	  if (!vr.undefined_p () && !vr.varying_p ())
> > +	  if (range_int_cst_p (&vr))
> >        {
> >          HOST_WIDE_INT type_min
> >   		= (TYPE_UNSIGNED (argtype)
> > @@ -1391,7 +1391,7 @@ format_integer (const directive &dir, tree arg,
> > pointer_query &ptr_qry)
> >         value_range vr;
> >         ptr_qry.rvals->range_of_expr (vr, arg, dir.info->callstmt);
> >   -      if (!vr.varying_p () && !vr.undefined_p ())
> > +      if (range_int_cst_p (&vr))
> >    {
> >      argmin = wide_int_to_tree (TREE_TYPE (arg), vr.lower_bound ());
> >      argmax = wide_int_to_tree (TREE_TYPE (arg), vr.upper_bound ());
> > @@ -4623,7 +4623,7 @@ handle_printf_call (gimple_stmt_iterator *gsi,
> > pointer_query &ptr_qry)
> >      value_range vr;
> >      ptr_qry.rvals->range_of_expr (vr, size, info.callstmt);
> >   -	  if (!vr.undefined_p ())
> > +	  if (!vr.undefined_p () && vr.kind () != VR_ANTI_RANGE)
> >        {
> >          tree type = TREE_TYPE (size);
> >          tree tmin = wide_int_to_tree (type, vr.lower_bound ());
> > diff --git a/gcc/graphite-sese-to-poly.cc b/gcc/graphite-sese-to-poly.cc
> > index fbe7667380a..b89262640ac 100644
> > --- a/gcc/graphite-sese-to-poly.cc
> > +++ b/gcc/graphite-sese-to-poly.cc
> > @@ -426,7 +426,7 @@ add_param_constraints (scop_p scop, graphite_dim_t p,
> > tree parameter)
> >   
> >     if (INTEGRAL_TYPE_P (type)
> >         && get_range_query (cfun)->range_of_expr (r, parameter)
> > -      && !r.undefined_p ())
> > +      && range_int_cst_p (&r))
> >       {
> >         min = r.lower_bound ();
> >         max = r.upper_bound ();
> > diff --git a/gcc/tree-ssa-strlen.cc b/gcc/tree-ssa-strlen.cc
> > index 7508c1768a5..e1230522564 100644
> > --- a/gcc/tree-ssa-strlen.cc
> > +++ b/gcc/tree-ssa-strlen.cc
> > @@ -1936,7 +1936,7 @@ set_strlen_range (tree lhs, wide_int min, wide_int
> > max,
> >    {
> >      value_range r;
> >      get_range_query (cfun)->range_of_expr (r, bound);
> > -	  if (!r.undefined_p ())
> > +	  if (range_int_cst_p (&r))
> >        {
> >          /* For a bound in a known range, adjust the range determined
> >      above as necessary.  For a bound in some anti-range or
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg,
Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman;
HRB 36809 (AG Nuernberg)

  reply	other threads:[~2023-02-28  9:41 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <09219.123022708581201997@us-mta-652.us.mimecast.lan>
2023-02-27 16:08 ` Aldy Hernandez
2023-02-28  9:41   ` Richard Biener [this message]
2023-03-01 10:01     ` Aldy Hernandez
2023-03-01 10:12       ` Richard Biener
2023-03-01 10:28         ` Aldy Hernandez
     [not found] <20230227135827.802E8385840A@sourceware.org>
2023-03-11 16:16 ` Jeff Law
2023-02-27 13:58 Richard Biener

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=nycvar.YFH.7.77.849.2302280907000.27913@jbgna.fhfr.qr \
    --to=rguenther@suse.de \
    --cc=aldyh@redhat.com \
    --cc=amacleod@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).