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)
next prev parent 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).