I _think_ I understand C strict aliasing - it's based on the type of expressions. In the testcase below, the type of expressions is the same, which is why I think it's a compiler bug.
The bug is reproducible with gcc 4.1.0 on multiple platforms. I've tried i386 (i686) and alpha myself and am able to reproduce the problem on both. The original reporter of the problem with my program (the real one, not the testcase) was able to reproduce the problem on other architectures. The problem does not occur with gcc 2.95.3 and 3.4.5. Basically, in the program below, gcc 4.1.0 would pre-load BF_current.P[0] and BF_current.P[17] into registers or stack locations - however the loop modifies P[0] via ptr. #include <stdio.h> #include <string.h> #define BF_N 16 typedef unsigned int BF_word; typedef BF_word BF_key[BF_N + 2]; static struct { BF_word S[4][0x100]; BF_key P; } BF_current; #define BF_ROUND(L, R, N) \ tmp1 = L & 0xFF; \ tmp2 = L >> 8; \ tmp2 &= 0xFF; \ tmp3 = L >> 16; \ tmp3 &= 0xFF; \ tmp4 = L >> 24; \ tmp1 = BF_current.S[3][tmp1]; \ tmp2 = BF_current.S[2][tmp2]; \ tmp3 = BF_current.S[1][tmp3]; \ tmp3 += BF_current.S[0][tmp4]; \ tmp3 ^= tmp2; \ R ^= BF_current.P[N + 1]; \ tmp3 += tmp1; \ R ^= tmp3; #define BF_ENCRYPT \ L ^= BF_current.P[0]; \ { \ int i; \ for (i = 0; i < BF_N; i += 2) { \ BF_ROUND(L, R, i); \ BF_ROUND(R, L, i+1); \ } \ } \ tmp4 = R; \ R = L; \ L = tmp4 ^ BF_current.P[BF_N + 1]; int main(void) { BF_word L, R; BF_word tmp1, tmp2, tmp3, tmp4, *ptr; BF_word i, j; for (i = 0; i < 4; i++) for (j = 0; j < 0x100; j++) BF_current.S[i][j] = (i + 0x12345678) * j; for (i = 0; i < BF_N + 2; i++) BF_current.P[i] = i * 0x98765432; L = R = 0; ptr = BF_current.P; do { #ifndef WORKAROUND ptr += 2; BF_ENCRYPT; *(ptr - 2) = L; *(ptr - 1) = R; #else BF_ENCRYPT; *ptr = L; *(ptr + 1) = R; ptr += 2; #endif } while (ptr < &BF_current.P[BF_N + 2]); printf("%08x %08x\n", L, R); return 0; } host!user:~$ gcc gcc-4.1.0-aliasing-bug.c -o gcc-4.1.0-aliasing-bug -Wall -O2 -fno-strict-aliasing host!user:~$ ./gcc-4.1.0-aliasing-bug 8261e2e6 f1f1bc33 host!user:~$ gcc gcc-4.1.0-aliasing-bug.c -o gcc-4.1.0-aliasing-bug -Wall -O2 host!user:~$ ./gcc-4.1.0-aliasing-bug 46be060b df072f90 host!user:~$ gcc gcc-4.1.0-aliasing-bug.c -o gcc-4.1.0-aliasing-bug -Wall -O2 -DWORKAROUND host!user:~$ ./gcc-4.1.0-aliasing-bug 8261e2e6 f1f1bc33 host!user:~$ uname -mrs Linux 2.4.32-ow1 alpha host!user:~$ gcc -v Using built-in specs. Target: alphaev56-unknown-linux-gnu Configured with: ./configure --prefix=/home/user/gcc-4.1.0 Thread model: posix gcc version 4.1.0 (i386 gives the same results) -- Summary: strict aliasing incorrectly pre-loads an array element Product: gcc Version: 4.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: solar at openwall dot com GCC build triplet: i686-pc-linux-gnu GCC host triplet: i686-pc-linux-gnu GCC target triplet: i686-pc-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26587