https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50417
--- Comment #10 from rguenther at suse dot de <rguenther at suse dot de> --- On Fri, 8 Jul 2016, olegendo at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50417 > > --- Comment #9 from Oleg Endo <olegendo at gcc dot gnu.org> --- > (In reply to rguent...@suse.de from comment #8) > > > > 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. > > Does it matter whether there's a void* in between or not? > > If we do a *(int32_T*)(void*)(int32_t*)p on a strict alignment target, it will > result in a 32 bit mem access. No, changing the pointer type doesn't change the access - how the access is implemented depends on memcpy. > GCC knows memcpy and its semantics well enough so propagating the target's > alignment rules into memcpy is most likely going to be a safe and sane thing > to > do. So at least cases like > > void test (const int* a, int* b) > { > std::memcpy (b, a, 4); > } > > should work. Shouldn't it? What makes the parameter type special? Would void test (const int *a, int *b) { std::memcpy ((char *)b, (char *)a, t); } be invalid to optimize to an aligned copy in your eyes? Yes, I know that C standard rule about pointer type casting, 6.3.2.3/7 in C11, but I guess that if we'd start to derive alignment from this undefinedness we are going to break a lot of code. To GCC what matters is actual accesses, not just pointer conversions which are all stripped anyway which makes the following testcase not optimizable (easily) void test (const char *a, char *b) { std::memcpy ((int *)b, (int *)a, 4); }