On such platforms: gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5) gcc version 3.3.3 (SuSE Linux)
Source Code: void func(unsigned char *buf) { unsigned short *p, a, b, c, d; unsigned int *q, m, n; unsigned int i1 = 0x1111; unsigned int i2 = 0x2222; unsigned int i3 = 0x3333; unsigned int i4 = 0x4444; unsigned int mod1 = 0x5555; unsigned int mod2 = 0x6666; unsigned int mod3 = 0x7777; unsigned int mod4 = 0x8888; p = (unsigned short *)buf; a = *p; b = *(p + 2); c = *(p + 4); d = *(p + 6); c = d^0x1234; b = c^0x2345; a = b^0x3456; *p = a; *(p + 2) = b; *(p + 4) = c; q = (unsigned int *)buf; m = *q; *q = ((*q * i1) % mod1) ^ 0xabcd; q++; n = *q; *q = ((*q * i2) % mod2) ^ 0xbcde ^ (m & 0xffff); q++; m = *q; *q = ((*q * i3) % mod3) ^ 0xcdef ^ (n & 0xffff); q++; *q = ((*q * i4) % mod4) ^ 0xdef1 ^ (m & 0xffff); return; } when compiled with O2 or O3 options, such as "gcc -O2 a.c", the problem is: when "m" was assigned first, buf[0] & buf[1] was NOT updated by "a". the asm code like this: ... xor 0x3456, eax; <- a mov [ebx], esi; <- m was assigned value of OLD buf[0 ~ 3] mov ax, [ebx]; <- buf[0] & buf[1] was updated by a imul 0x1111, esi; ... as a constrast, when compiled with O1 or none options, such like "gcc -O1 a.c" or "gcc a.c", the asm code like this: ... xor 0x3456, eax; mov ax, [ebx]; mov [ebx], esi; imul 0x1111, esi; ... when change the order of "*p = a; *(p + 2) = b; *(p + 4) =c" to "*(p + 4) = c; *(p + 2) = b; *p = a", compiled with O2 or O3 option, the result was correct too. -- Summary: program was compiled wrong when use GCC O2 or O3 option Product: gcc Version: 3.3.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: lucifer_ww at yahoo dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30208