http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57359

            Bug ID: 57359
           Summary: wrong code for union access at -O3 on x86_64-linux
           Product: gcc
           Version: 4.9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: dhazeghi at yahoo dot com

The following code is miscompiled with current gcc 4.8 branch and trunk at -O3
on x86_64-linux.  The last write to the union appears to be getting removed (*k
= 0), so that the program outputs '1' instead of '0'.  This behavior does not
occur on 4.7.

$ gcc-trunk -v
gcc version 4.9.0 20130521 (experimental) [trunk revision 199148] (GCC) 
$ gcc-trunk -O2 wrong.c 
$ ./a.out 
0
$ gcc-4.7 -O3 wrong.c 
$ ./a.out 
0
$ gcc-trunk -O3 wrong.c 
$ ./a.out 
1
$
-------------------------------
int printf(const char *, ...);

union
{
    int i;
    long long ll;
} u;

unsigned int i;

int a;
int *pa = &a;
int **ppa = &pa;
int ia[1][1];

long long *la[][1][1] = { {}, {}, {}, {}, 0, &u.ll };
long long **ppll = &la[4][1][0];
long long ll = 1;

void
foo ()
{
    for (; i <= 1; i++)
    {
        int *j;
        int *k = &u.i;
        **ppll = ll;
        *k = 0;
        j = *ppa;
        ia[0][0] = *j;
    }
}

int
main ()
{
    foo ();
    printf ("%d\n", u.i);
    return 0;
}

Reply via email to