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.
Steve Ellcey
[email protected]