[Bug fortran/92698] Unnecessary copy in overlapping array assignment
tkoenig at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Sun Dec 1 00:46:00 GMT 2019
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.
More information about the Gcc-bugs
mailing list