This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: __builtin_memcpy and alignment assumptions
- From: Steve Ellcey <sellcey at imgtec dot com>
- To: Richard Biener <richard dot guenther at gmail dot com>
- Cc: Eric Botcazou <ebotcazou at libertysurf dot fr>, Jakub Jelinek <jakub at redhat dot com>, GCC Development <gcc at gcc dot gnu dot org>
- Date: Fri, 8 Jan 2016 10:36:11 -0800
- Subject: Re: __builtin_memcpy and alignment assumptions
- Authentication-results: sourceware.org; auth=none
- References: <5e991791-a201-4b8d-89fd-78db873368c7 at BAMAIL02 dot ba dot imgtec dot org> <1482639 dot JCa9WsCs7z at polaris> <20160108113220 dot GT18720 at tucnak dot redhat dot com> <2160140 dot tpolP5XCIt at polaris> <CAFiYyc2LEB8WKF7JqSpqd6n=p0W0tec+H_OciyHxzqZsdjyvrg at mail dot gmail dot com>
- Reply-to: <sellcey at imgtec dot com>
On Fri, 2016-01-08 at 12:56 +0100, Richard Biener wrote:
> On Fri, Jan 8, 2016 at 12:40 PM, Eric Botcazou <ebotcazou@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
sellcey@imgtec.com