On Sunday, 2 August 2020 at 17:31:45 UTC, Bruce Carneal wrote:
import std;
void f0(int[] a, int[] b, int[] dst) @safe {
dst[] = a[] + b[];
}
void f1(int[] a, int[] b, int[] dst) @trusted {
const minLen = min(a.length, b.length, dst.length);
dst[0..minLen] = a[0..minLen] + b[0..minLen];
assert(dst.length == minLen);
}
I was surprised that f0 ran just fine with a.length and
b.length geq dst.length. Is that a bug or a feature?
Assuming it's a feature, are f0 and f1 morally equivalent? I
ask because f1 auto-vectorizes in ldc while f0 does not. Not
sure why. As a guess I'd say that the front end doesn't hoist
bounds checks in f0 or at least doesn't convey the info to the
back end in a comprehensible fashion. Non-guesses welcome.
I don't know what's going on auto-vectorization-wise, but to
address the behavioral issues, the next thing I would do if I
were in your shoes is something like this:
import std.stdio;
int[100] a, b, dst;
a[] = 2;
b[] = 3;
dst[] = 42;
f0(a[0..$], b[0..$], dst[0..50]); // Notice: dst is a smaller
slice.
writefln("dst[49] == %d", dst[49]); // Should be 5.
writefln("dst[50] == %d", dst[50]); // 42 or 5?
On my machine (Linux 64-bit DMD v2.093.0) it prints this:
dst[49] == 5
dst[50] == 42
Which suggests that it is doing the minimum-length calculation,
as the dst[] values outside of the lesser-sized slice were
untouched.
This was DMD, so it's going to be worth trying on your compiler
to see what you get.