This is the mail archive of the gcc-bugs@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]

2.95.1 alias analysis bug


Guys and Gals,
              I'ld be suprised if everyone did not already know this one,
but I thought I should send it anyway (did not see it in the "list of well-
known bugs" which suprised me). I also offer a decent workaround solution 
that I hope GNU-C picks up.

The "strict aliasing" new in gcc-2.9 is in conflict with one of gcc's long 
standing extensions, namely allowing a cast as an l-value.  The example I 
first ran into was in Cygnus' own printf library function, but is easily 
shown with a test program:


float
fred (float * p)
{
  *(int *)p = 0x01230000;

  return 5.0f * *p;
}


With strict aliasing the assignment to *p, and the fetch of *p cannot alias
since they refer to different types, so the compiler is free to rearrange
the order of the load and store, even though in reality they do point to
the same address and the load and store cannot really be rearranged.

compiled with -O1 using gcc-2.95.1 for SPARC gives OK code:

        sethi   %hi(19070976), %g2
        st      %g2, [%o0]		<-- the store 
        ld      [%o0], %f2		<-- and load are in correct order
        sethi   %hi(.LLC0), %g2
        ld      [%g2+%lo(.LLC0)], %f0
        retl
        fmuls   %f2, %f0, %f0

compiled with -O2 (includes strict alias analysis) for SPARC gives:

        ld      [%o0], %f2
        sethi   %hi(.LLC0), %g3
        sethi   %hi(19070976), %g2
        ld      [%g3+%lo(.LLC0)], %f0
        fmuls   %f2, %f0, %f0
        retl
        st      %g2, [%o0]	<-- here the store comes a little late !!!



Since the contents of the pointers for the load and the store are totally
un-ambiguously the same it is incorrect that the strict-type analysis is 
being given precedence here, especially when the source level program is 
"correct" in the spirit of the GNU-C extension that it uses.

When strict aliasing is turned on this case should be detected and a
warning issued and correct code generated rather than silently generating 
incorrect code.

	-------------------------------------------------------------

In the compiler I am working on a source level work-around is available:

float
wilma (float * p)
{
  *p = (float)(void)0x01230000;

  return 5.0f * *p;
}

The language has been enhanced to allow casting to VOID if and only if
the result is immediately cast to another non-void type of the same size
as the original type. The result is transfering bits _without_ converting,
something that everyone wants but that ANSI-C is incapable of doing cleanly.

The compiler change to support this is trivial, and it gets used a lot here.
It also eliminates union-tricks which are ugly and often hard to optimize.
I highly recommend that GNU-C incorporate it. I can provide diffs if anyone
wants them.


-Pete Lawrence,    peter.lawrence@eng.sun.com,   408-774-8661.


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