https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92698
Thomas Koenig <tkoenig at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2019-12-01 Ever confirmed|0 |1 Severity|normal |enhancement --- Comment #3 from Thomas Koenig <tkoenig at gcc dot gnu.org> --- So, here's a C test case, also functionally equivalent to a memmove. #include <stdlib.h> void foo (double *a, int n, int len, int offset) { int i; double *p; p = malloc(sizeof(*p) * len); for (i=0; i<len; i++) p[i] = a[n+i]; for (i=0; i<len; i++) a[n+offset+i] = p[i]; free(p); } So, this is something the middle end could possibly catch, it doesn't do so at the moment. Regarding loop versioning wrt unity / non-unity strides: We've had that discussion for a more general case, I cannot find the PR at the moment, it may have been closed as WONTFIX. One problem that we saw was that the time overhead and growth of code size could be too high, especially with short arrays. With the CONTIGOUS attribute and the IS_CONTIGUOUS function, the user now can control what needs to happen. Older code, by the way, usually has real a(n) style arguments, and these are always contiguous (and may need to be converted on entry / exit). So, what's left? We could indeed translate a(n:n+len-1) = a(n+offset:n+offset+len-1) into pseudo-code if (is_contiguous(a)) then i = n + offset + len - 1 - (n + offset) + 1 if (bounds_checking) then if (n + len - 1 /=i) stop "out of bounds error" end if if (i>0) then call memcpy (c_loc(a(n)), c_loc(a(n+offset), i*c_sizeof(a(1)) end if else a(n:n+len-1) = a(n+offset:n+offset+len-1) (this is pseudo-code because we cannot use the real c_loc because a is usually not a target). So, confirmed as an enhancement request.