On Fri, Jan 8, 2016 at 7:36 PM, Steve Ellcey <[email protected]> wrote: > On Fri, 2016-01-08 at 12:56 +0100, Richard Biener wrote: >> On Fri, Jan 8, 2016 at 12:40 PM, Eric Botcazou <[email protected]> >> wrote: >> >> I think we only assume it if the pointer is actually dereferenced, >> >> otherwise >> >> it just breaks too much code in the wild. And while memcpy dereferences, >> >> it dereferences it through a char * cast, and thus only the minimum >> >> alignment is assumed. >> > >> > Yet the compiler was generating the expected code for Steve's testcase on >> > strict-alignment architectures until very recently (GCC 4.5 IIUC) and this >> > worked perfectly. > > Yes, I just checked and I did get the better code in GCC 4.5 and I get > the current slower code in GCC 4.6. > >> Consider >> >> int a[256]; >> int >> main() >> { >> void *p = (char *)a + 1; >> void *q = (char *)a + 5; >> __builtin_memcpy (p, q, 4); >> return 0; >> } >> >> where the ME would be entitled to "drop" the char */void * conversions >> and use &a typed temps. > > I am not sure how this works but I tweaked get_pointer_alignment_1 so > that if there was no align info or if get_ptr_info_alignment returned > false then the routine would return type based alignment information > instead of default 'void *' alignment. In that case and using your > example, GCC still accessed p & q as pointers to unaligned data. > > In fact if I used int pointers: > > int a[256]; > int main() > { > int *p = (int *)((char *)a + 1); > int *q = (int *)((char *)a + 5); > __builtin_memcpy (p, q, 4); > return 0; > } > > GCC did unaligned accesses when optimizing, but when unoptimized (and > with my change) GCC did aligned accesses, which would not work on a > strict alignment machine like MIPS This seems to match what happens > with: > > int a[256]; > int main() > { > int *p = (int *)((char *)a + 1); > int *q = (int *)((char *)a + 5); > *p = *q; > return 0; > } > > When I optimize it, GCC does unaligned accesses and when unoptimized > GCC does aligned accesses which will not work on MIPS.
Of course reading the fine-print in the C standard makes these testcases undefined (you use a int * type for not properly aligned pointers, -Wcast-align should warn about this). Btw, your change to get_pointer_alignment would basically boil down to doing get_object_alignment. Richard.
