This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: __builtin_memcpy and alignment assumptions


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]