https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61196
Bug ID: 61196 Summary: Optimizer does not handle memory accesses with two pointers to same location correctly Product: gcc Version: 4.5.3 Status: UNCONFIRMED Severity: major Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: bjoern.m.haase at web dot de Created attachment 32800 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=32800&action=edit testcase program The following test case program boils down an issue with gcc.4.5.3 on the cygwin platform. The bug is not present in the mingw version 4.7.2 that I also have on my system. It, thus, might be fixed, but adding the test case might be worth the effort to check for regressions. When compiling with -O0 -O1 it outputs the expected result, when compiling with -O2 or -O3, it produces an error. The code is somewhat strange but I stumbled over this segment in production code of the libsodium crypto library. Since it's a wrong code bug on an important platform (X86), I did classify it as "major" bug. Output of "gcc testcase.c -O0 -o test.exe && test.exe" : bbccddee 66778899 22334455 ff001122 Output of "gcc testcase.c -O3 -o test.exe && test.exe" : 0 28d41c 28ac88 49435341 We had an error. Output of "gcc testcase.c -O2 -o test.exe && test.exe" : bbccddee 28d41c 28ac68 2d465455 We had an error. Declaring the tp pointer in the testcase as volatile fixes the problem. For this reason, I doubt that it's rather the middle end than the X86 backend. //////////////////////////////////////////////////////////////////// /// /// File testcase.c /// //////////////////////////////////////////////////////////////////// #include <stdio.h> typedef unsigned long int uint32; typedef struct { unsigned long long a; unsigned long long b; } int128; int128 x = {0x1234567,0x1234567}; void copy2(int128 *r, const int128 *x) { r->a = x->a; r->b = x->b; } void shufd(int128 *r, const int128 *x, const unsigned int c) { int128 t; uint32 *tp = (uint32 *)&t; const uint32 *xp = (const uint32 *)x; tp[0] = xp[c&3]; tp[1] = xp[(c>>2)&3]; tp[2] = xp[(c>>4)&3]; tp[3] = xp[(c>>6)&3]; copy2(r,&t); } int main (void) { int didErrorOccur = 0; x.a = 0x112233445566778899ll; x.b = 0xaabbccddeeff001122ll; shufd (&x,&x,0x93); printf ("%x \n", x.a); printf ("%x \n", (x.a >> 32)); printf ("%x \n", x.b); printf ("%x \n", (x.b >> 32)); if (x.a != 0x66778899bbccddeell) { didErrorOccur = 1; } if (x.b != 0xff00112222334455ll) { didErrorOccur = 1; } if (didErrorOccur) { printf ("We had an error.\n"); } }