https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89617
--- Comment #2 from John Zwinck <jzwinck at gmail dot com> --- Jakub, here is a similar example using structs instead of arrays. It still generates different code, with RESTRICT giving memcpy instead of mov, but no RESTRICT still using memmove which is suboptimal. struct S { int arr[3]; }; inline void Copy(S& __restrict__ dest, const S& __restrict__ src) { std::copy(std::begin(src.arr), std::end(src.arr), dest.arr); } void f2(S& dest, const S& src) { if (&dest != &src) { #ifdef RESTRICT Copy(dest, src); #else std::copy(std::begin(src.arr), std::end(src.arr), dest.arr); #endif } } Demo: https://godbolt.org/z/zmJTLU That being said, Clang thinks that casting a larger array to a smaller one is undefined behavior, so can you give a more specific example of when two arrays might overlap yet not have the same starting address?