Bug 38826 - points-to result wrong for reads from call-clobbered vars
Summary: points-to result wrong for reads from call-clobbered vars
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.4.0
: P3 normal
Target Milestone: 4.4.0
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks: 38477
  Show dependency treegraph
 
Reported: 2009-01-13 12:14 UTC by Richard Biener
Modified: 2009-01-14 16:45 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Biener 2009-01-13 12:14:15 UTC
The following testcase emits a strict-aliasing warning because the points-to
result for p is wrong.  It should be pt_anything, but instead the read from
s.q is considered a non-pointer variable (we do not have constraints for all
implicitly taken addresses by passing &s to the function call).

struct S { int *p; int *q; };

void foo (struct S *);

int bar (int b)
{
  struct S s;
  int *p;
  float f;
  foo (&s);
  if (b)
    p = s.q;
  else
    p = (int *)&f;
  return *p;
}

Inspecting the points-to results on

struct S { int *p; int *q; };

void foo (struct S *);

int *bar (int b)
{
  struct S s;
  foo (&s);
  return s.q;
}

exposes the failure as

ESCAPED = { ESCAPED NONLOCAL s s.64+64 }
...
s = { ESCAPED NONLOCAL }
s.64+64 = { ESCAPED NONLOCAL }
D.1598_1 = { }


D.1598_1 should have the same solution as s.64+64.
Comment 1 Richard Biener 2009-01-13 12:34:54 UTC
It is interesting to see how taking the address of &s.q makes it a pointer
variable.  The fundamental issue seems to be that eliminating non-pointers
and their edges conflicts with field-sensitive analysis.

Consider

struct S { int *p; int *q; };

void foo (struct S **);

int *bar (int b)
{
  struct S s;
  struct S *p = &s;
  foo (&p);
  return s.q;
}

to see that just generating extra ADDRESSOF constraints for call arguments
will not fix the issue.

Not only we will need to avoid eliminating non-pointers / edges if any of a
variables sub-field has got a proper pointer label, unifying them (they
still have pointer label 0) is also wrong.

Danny, any idea where/how to fix this?
Comment 2 Richard Biener 2009-01-13 14:37:43 UTC
In fact, field-sensitive points-to analysis is probably not improving things
anyway - a testcase where it does is certainly welcome! - simply due to the
fact that the points-to analysis would need to be more clever than
load (partial-)redundancy elimination.  Where it could help is for IPA mode
though.  And likely it will rot very quickly if we disable it, but ... disabling
it would be my prefered choice here.
Comment 3 Daniel Berlin 2009-01-13 18:42:59 UTC
Subject: Re:  points-to result wrong for reads 
	from call-clobbered vars

Interesting.
I have emailed some others for their thoughts.

One way to eliminate this bug would be to mark the entire structure as
indirect nodes due to &s when we initialize the offline problem.
You would also have to do the same if you see &s.p.

The problem of course, is that i think our C++ implementation still
plays games with subtracting offsets, so for C++, you'd have to mark
the entire structure full of variables indirect when you see address
taking of any member :(

Anyway, give me a short time to wait for responses and see if there is
a good way out of this.

On Tue, Jan 13, 2009 at 7:34 AM, rguenth at gcc dot gnu dot org
<gcc-bugzilla@gcc.gnu.org> wrote:
>
>
> ------- Comment #1 from rguenth at gcc dot gnu dot org  2009-01-13 12:34 -------
> It is interesting to see how taking the address of &s.q makes it a pointer
> variable.  The fundamental issue seems to be that eliminating non-pointers
> and their edges conflicts with field-sensitive analysis.
>
> Consider
>
> struct S { int *p; int *q; };
>
> void foo (struct S **);
>
> int *bar (int b)
> {
>  struct S s;
>  struct S *p = &s;
>  foo (&p);
>  return s.q;
> }
>
> to see that just generating extra ADDRESSOF constraints for call arguments
> will not fix the issue.
>
> Not only we will need to avoid eliminating non-pointers / edges if any of a
> variables sub-field has got a proper pointer label, unifying them (they
> still have pointer label 0) is also wrong.
>
> Danny, any idea where/how to fix this?
>
>
> --
>
> rguenth at gcc dot gnu dot org changed:
>
>           What    |Removed                     |Added
> ----------------------------------------------------------------------------
>                 CC|                            |dberlin at gcc dot gnu dot
>                   |                            |org
>
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38826
>
> ------- You are receiving this mail because: -------
> You are on the CC list for the bug, or are watching someone who is.
>
Comment 4 Richard Biener 2009-01-14 16:45:45 UTC
Subject: Bug 38826

Author: rguenth
Date: Wed Jan 14 16:45:22 2009
New Revision: 143374

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=143374
Log:
2009-01-14  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/38826
	PR middle-end/38477
	* tree-ssa-structalias.c (emit_alias_warning): Emit the pointer
	initialization notes only if we actually emitted a warning.
	(intra_create_variable_infos): Add constraints for a result decl
	that is passed by hidden reference.
	(build_pred_graph): Mark all related variables non-direct on
	address-taking.

	* gcc.dg/Wstrict-aliasing-bogus-pta-1.c: New testcase.

Added:
    trunk/gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-pta-1.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-ssa-structalias.c

Comment 5 Richard Biener 2009-01-14 16:45:52 UTC
Fixed.