On Monday, 20 May 2024 at 18:14:50 UTC, kinke wrote:
> I think the problem here is that you don't get the expected optimization to a memcpy (with -O3) when using the @restrict
UDA, with the variant taking a D slice. So no correctness issue.
This boils down to the expected memcpy, apparently needing unpacking of D slices:
void cpr2(size_t srcLength, ubyte* src, @restrict ubyte* dst)
{
foreach (i; 0 .. srcLength)
dst[i] = src[i];
}
I don't view that missed optimization as much of a problem, although I will note that gdc decided to issue a call to memmove for the @restrict slice code under -O3. The LDC cpr2 call out to memcpy for the lowered/non-slice variant seems entirely justified given @restrict.
What seems like a problem is emitting SIMD code for the vanilla (no attributes) cp() variant that doesn't produce the same result as a simple scalar loop would. Consider:
values at location x: 0, 1, 2, 3, 4, ...
src at location x
dst at location x + 1
Shouldn't the vanilla scalar copy loop for the above just result in a bunch of zeros? This is what I'd expect if a dead simple loop body were generated. If, on the other hand, you emit SIMD code for the loads and stores, as LDC is want to do, you get something different.
What am I missing?