https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50417

--- Comment #8 from rguenther at suse dot de <rguenther at suse dot de> ---
On Fri, 8 Jul 2016, npl at chello dot at wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50417
> 
> npl at chello dot at changed:
> 
>            What    |Removed                     |Added
> ----------------------------------------------------------------------------
>                  CC|                            |npl at chello dot at
> 
> --- Comment #7 from npl at chello dot at ---
> This seems to affect even the most trivial cases. I ran the following code 
> witn
> arm gcc 4.8.4, 4.9.2 and 5.3.0:
> 
> #include <stdint.h>
> #include <string.h>
> 
> uint32_t foo_noalign(const uint32_t *s) {
>         uint32_t v;
>         memcpy(&v, s, sizeof(v));
>         return v;
> }
> 
> uint32_t foo(const uint32_t *s) {
>         uint32_t v;
>         memcpy(&v, __builtin_assume_aligned(s, 4), sizeof(v));
>         return v;
> }
> 
> Which generates the following code:
> 
> 00000000 <foo_noalign>:
>    0:   e92d4007        push    {r0, r1, r2, lr}
>    4:   e3a02004        mov     r2, #4
>    8:   e1a01000        mov     r1, r0
>    c:   e08d0002        add     r0, sp, r2
>   10:   ebfffffe        bl      0 <memcpy>
>   14:   e59d0004        ldr     r0, [sp, #4]
>   18:   e28dd00c        add     sp, sp, #12
>   1c:   e49de004        pop     {lr}            ; (ldr lr, [sp], #4)
>   20:   e12fff1e        bx      lr
> 
> 00000024 <foo>:
>   24:   e5900000        ldr     r0, [r0]
>   28:   e12fff1e        bx      lr
> 
> Thats really, really bad. clang has no problems generating the optimal code.

But there is no good reasoning that can be applied that it is a valid
transform.  What does clang do when s is void * and you cast that to
uint32_t *?  Note that memcpy prototype takes a void * argument.

Reply via email to