public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Biener <richard.guenther@gmail.com>
To: Alexandre Oliva <oliva@adacore.com>
Cc: GCC Patches <gcc-patches@gcc.gnu.org>,
	Bin Cheng <bin.cheng@linux.alibaba.com>
Subject: Re: [PATCH] [PR105665] ivopts: check defs of names in base for undefs
Date: Wed, 1 Jun 2022 11:42:25 +0200	[thread overview]
Message-ID: <CAFiYyc2nVx4n7XOPA-ZwB+k07n84j2z6Es08neGr+BRCsxsvTg@mail.gmail.com> (raw)
In-Reply-To: <orh755de8m.fsf@lxoliva.fsfla.org>

On Tue, May 31, 2022 at 3:27 PM Alexandre Oliva <oliva@adacore.com> wrote:
>
> On May 30, 2022, Richard Biener <richard.guenther@gmail.com> wrote:
>
> > I don't think you can rely on TREE_VISITED not set at the start of the
> > pass (and you don't clear it either).
>
> I don't clear it, but I loop over all SSA names and set TREE_VISITED to
> either true or false, so that's covered.
>
> I even had a test patch that checked that TREE_VISITED remains unchanged
> and still matched the expected value, with a recursive verification.
>
> I could switch to an sbitmap if that's preferred, though.
>
> > I also wonder how you decide that tracking PHIs with (one) uninit arg
> > is "enough"?
>
> It's a conservative assumption, granted.  One could imagine cases in
> which an uninit def is never actually used, say because of conditionals
> forced by external circumstances the compiler cannot possibly know
> about.  But then, just as this sort of bug shows, sometimes even when an
> uninit is not actually used, the fact that it is uninit and thus
> undefined may end up percolating onto stuff that is actually used, so I
> figured we'd be better off leaving alone whatever is potentially derived
> from an uninit value.
>
> > Is it important which edge of the PHI the undef appears in?
>
> At some point, I added recursion to find_ssa_undef, at PHI nodes and
> assignments, and pondered whether to recurse at PHI nodes only for defs
> that were "earlier" ones, rather than coming from back edges.  I ended
> up reasoning that back edges would affect step and rule out an IV
> candidate even sooner.  But the forward propagation of maybe-undef
> obviated that reasoning.  Now, almost tautologically, if circumstances
> are such that the compiler could only tell that an ssa name is defined
> with external knowledge, then, since such external knowledge is not
> available to the compiler, it has to assume that the ssa name may be
> undefined.
>
> > I presume the testcase might have it on the loop entry edge?
>
> The original testcase did.  The modified one (the added increment) shows
> it can be an earlier edge that has the maybe-undef name.
>
> > I presume only PHIs in loop headers are to be considered?
>
> As in the modified testcase, earlier PHIs that are entirely outside the
> loop can still trigger the bug.  Adding more increments of g guarded by
> conditionals involving other global variables pushes the undef ssa name
> further and further away from the inner loop, while still rendering g an
> unsuitable IV.

So for example

void foo (int flag, int init, int n, int *p)
{
   int i;
   if (flag)
     i = init;
   for (; i < n; ++i)
     *(p++) = 1;
}

will now not consider 'i - i-on-entry' as an IV to express *(p++) = 1.
But

void foo (int flag, int init, int n, int *p)
{
   int i;
   if (flag)
     i = init;
   i++;
   for (; i < n; ++i)
     *(p++) = 1;
}

still would (the propagation stops at i++).  That said - I wonder if we
want to compute a conservative set of 'must-initialized' here or to
say, do we understand the failure mode good enough to say that
a must-def (even if from an SSA name without a definition) is good
enough to avoid the issues we are seeing?

One would argue that my example above invokes undefined behavior
if (!flag), but IIRC the cases in the PRs we talk about are not but
IVOPTs with its IV choice exposes undefined behavior - orignially
by relying on undef - undef being zero.

That said, the contains-undef thing tries to avoid rewriting expressions
with terms that possibly contain undefs which means if we want to
strenthen it then we look for must-defined (currently it's must-undefined)?

Richard.

> >> +int a, b, c[1], d[2], *e = c;
> >> +int main() {
> >> +  int f = 0;
> >> +  for (; b < 2; b++) {
> >> +    int g;
> >> +    if (f)
> >> +      g++, b = 40;
> >> +    a = d[b * b];
> >> +    for (f = 0; f < 3; f++) {
> >> +      if (e)
> >> +        break;
> >> +      g--;
> >> +      if (a)
> >> +        a = g;
> >> +    }
> >> +  }
> >> +  return 0;
> >> +}
>
> --
> Alexandre Oliva, happy hacker                https://FSFLA.org/blogs/lxo/
>    Free Software Activist                       GNU Toolchain Engineer
> Disinformation flourishes because many people care deeply about injustice
> but very few check the facts.  Ask me about <https://stallmansupport.org>

  reply	other threads:[~2022-06-01  9:42 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-28  5:51 Alexandre Oliva
2022-05-30 12:21 ` Richard Biener
2022-05-31 13:27   ` Alexandre Oliva
2022-06-01  9:42     ` Richard Biener [this message]
2022-06-01 19:56       ` Alexandre Oliva
2022-06-02  7:10         ` Alexandre Oliva
2022-06-02  9:23           ` Richard Biener
2022-06-03  7:01             ` Alexandre Oliva

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=CAFiYyc2nVx4n7XOPA-ZwB+k07n84j2z6Es08neGr+BRCsxsvTg@mail.gmail.com \
    --to=richard.guenther@gmail.com \
    --cc=bin.cheng@linux.alibaba.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=oliva@adacore.com \
    /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).