http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48377
--- Comment #14 from Jakub Jelinek <jakub at gcc dot gnu.org> 2011-04-07 08:20:30 UTC --- Sure, but for types with user alignment smaller than their size, loop peeling may often never be able to align it. This regressed with http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=161797 What I mean is that for say unsigned int type with 32-bit alignment loop peeling for valid code should always end up with correct alignment, but for unsigned int with 8-bit alignment it can't. And e.g. i?86 long long is of the same category, it has 64-bit size, but 32-bit alignment, so if you have a pointer to long long array, the whole array might be just 32-bit aligned, but not 64-bit, then any kind of peeling will still result in misalignment. __attribute__((noinline, noclone)) unsigned long long foo (const char *s, int len) { const unsigned long long *p = (const unsigned long long *) s; unsigned long long f = len / sizeof (unsigned long long), hash = len, i; for (i = 0; i < f; ++i) hash += *p++; return hash; } struct S { int i; long long buf[64]; } s; int main (void) { return foo ((const char *) s.buf, 60); } works fine though (with -m32 -O3 -mavx or -m32 -O3 -msse4).