extern void abort (void); struct S { unsigned char a, b, c, d[16]; };
void __attribute__ ((noinline)) foo (struct S *x, struct S *y) { int a, b; unsigned char c, *d, *e; b = x->b; d = x->d; e = y->d; a = 0; while (b) { if (b >= 8) { c = 0xff; b -= 8; } else { c = 0xff << (8 - b); b = 0; } e[a] = d[a] & c; a++; } } int main (void) { struct S x = { 0, 25, 0, { 0xaa, 0xbb, 0xcc, 0xdd }}; struct S y = { 0, 0, 0, { 0 }}; foo (&x, &y); if (x.d[0] != y.d[0] || x.d[1] != y.d[1] || x.d[2] != y.d[2] || (x.d[3] & 0x80) != y.d[3]) abort (); return 0; } On i686-linux with -O2 -m32 the loop is miscompiled, it copies over just first 24 bits and not the 25th bit. From quick skimming of the tree dumps, this looks messed up by ivopts pass. Seems to be a recent regression, at least 20060304 GCC 4.1.x worked fine, while 20060420 does not. -- Summary: [4.1 regression] ivopts postgresql miscompilation Product: gcc Version: 4.1.1 Status: UNCONFIRMED Severity: critical Priority: P3 Component: tree-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: jakub at gcc dot gnu dot org GCC target triplet: i686-linux http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27285