https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126130
--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #7)
> (In reply to Richard Biener from comment #5)
> [...]
> > diff --git a/gcc/pta-andersen.cc b/gcc/pta-andersen.cc
> > index bba34b3c9a0..7adf4f53579 100644
> > --- a/gcc/pta-andersen.cc
> > +++ b/gcc/pta-andersen.cc
> > @@ -394,7 +394,8 @@ solution_set_expand (bitmap set, bitmap *expanded)
> > {
> > varinfo_t v = get_varinfo (j);
> > if (v->is_artificial_var
> > - || v->is_full_var)
> > + || v->is_full_var
> > + || v->is_fn_info)
> > continue;
> > if (v->head != prev_head)
> > {
>
> causes
>
[...]
> +FAIL: gcc.dg/torture/pr43879_1.c -O1 execution test
> +FAIL: gcc.dg/torture/pr43879_1.c -O2 execution test
> +FAIL: gcc.dg/torture/pr43879_1.c -O3 -g execution test
> +FAIL: gcc.dg/torture/pr43879_1.c -Os execution test
shows that in pr43879_2.c which has
static int foo(int *i)
{
bar(*i);
baz(i);
bar(*i);
return *i;
}
struct TBL tbl = { foo };
-ESCAPED = { ESCAPED NONLOCAL foo foo.clobber foo.use foo.result foo.arg0 }
+ESCAPED = { foo }
...
-foo.result = { ESCAPED NONLOCAL }
-foo.arg0 = { ESCAPED NONLOCAL }
+foo.result = { }
+foo.arg0 = { }
so when a function pointer escapes we rely on the
ESCAPED = *ESCAPED
ESCAPED = ESCAPED + UNKNOWN
*ESCAPED = NONLOCAL
constraints to populate the arguments (and static chain) with NONLOCAL.
+FAIL: gcc.dg/torture/pr94947-1.c -O1 execution test
+FAIL: gcc.dg/torture/pr94947-1.c -O2 execution test
+FAIL: gcc.dg/torture/pr94947-1.c -O3 -g execution test
+FAIL: gcc.dg/torture/pr94947-1.c -Os execution test
is the more interesting case where we have
static int *p;
static void foo ()
{
if (*p != 1)
abort ();
}
int main()
{
int x = 1;
p = &x;
baz_call = foo;
baz ();
and baz () in another TU calling foo (). With the patch we elide 'x = 1'
because the baz () call only uses escaped/global vars. 'x' does not
escape the unit, but with expanding to USE/CLOBBER we get 'x' escaped
via the escape of 'foo' and thus escaping what foo uses.
Removing use/clobber from the expansion makes this no longer work,
but I have not yet made up my mind whether this is the correct way
to deal with this -- I'd have expected this to only have an effect on
the baz () uses/clobbers, but there we have patched/unpatched
# USE = nonlocal unit-escaped
# CLB = nonlocal unit-escaped
bazD.2966 ();
we treat 'baz' "classical" (it's extern, no body available), but still
use unit-escaped here (we do not compute the classical function escaped
in IPA PTA).
Steensgard-wise we'd "unify" USE/CLB of classical function calls and
all escaped function USE/CLB.