This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: __builtin_memcpy and alignment assumptions
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: sellcey at imgtec 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: Mon, 11 Jan 2016 09:53:20 +0100
- 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> <1452278171 dot 29343 dot 62 dot camel at ubuntu-sellcey>
On Fri, Jan 8, 2016 at 7:36 PM, Steve Ellcey <sellcey@imgtec.com> wrote:
> 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.
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.