This is the mail archive of the gcc-prs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

middle-end/9725: Invalid dependency determination


>Number:         9725
>Category:       middle-end
>Synopsis:       Invalid dependency determination
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Mon Feb 17 15:36:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     Jan Beulich
>Release:        gcc-3.2.2
>Organization:
>Environment:
Cygwin host, various targets.
>Description:
The code below, compiled with -O2 (or -O1 -fstrict-aliasing)
causes the compiler to omit (or, in a non-contrived
environment) incorrectly schedule the second store. This
appears to be related to the incorrect assumption in
alias.c (three places) that different alias sets provide for
non-conflicting memory accesses; this isn't true if I
understand the concept of alias sets (as explained close to
the top of that file) correctly; instead, only the inverse
conclusion would guarantee correct code - if two accesses
are in the same alias set, then there potentially is a
conflict. However, the simple change to invert the tests
(and return values) in the three affected functions yields
various cases where scheduling non-conflicting stores ahead
of other operations is suppressed, so appearantly a better
than this trivial fix is needed.
An interesting (and worrying, at least to me) additional
note is that when the type of the second structure field
is 'unsigned char' the problem is not present.
>How-To-Repeat:
struct s {
	unsigned int h;
	unsigned short q;
};

void test(unsigned long long*pf, unsigned int h, unsigned short q) {
	unsigned long long f;

	((struct s*)&f)->h = h;
	((struct s*)&f)->q = q;
	*pf = f;
}
>Fix:
The simple (to at least guarantee correct code) but
inefficient fix is to invert (and move down as far as
possible the three instances of 
  if (DIFFERENT_ALIAS_SETS_P (x, mem))
    return 0;
to
  if (!DIFFERENT_ALIAS_SETS_P (x, mem))
    return 1;
in alias.c.
>Release-Note:
>Audit-Trail:
>Unformatted:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]