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.