On Fri, 2016-01-08 at 12:56 +0100, Richard Biener wrote:
> On Fri, Jan 8, 2016 at 12:40 PM, Eric Botcazou <ebotca...@libertysurf.fr> 
> 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
sell...@imgtec.com




Reply via email to