safety and auto vectorization

Steven Schveighoffer schveiguy at gmail.com
Mon Aug 3 18:55:36 UTC 2020


On 8/2/20 1:31 PM, 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.

First, I think this is a bug. A regression in fact. As of 2.077 this 
works, and before it did not. There is nothing in the spec that says the 
behavior is defined for this case.

Second, it's more than just that. This also runs currently:

void main()
{
     auto a = [1, 2, 3];
     auto b = [4, 5, 6];
     int[] dst = new int[4]; // note the extra element
     dst[] = a[] + b[];
     writeln(dst[3]);
}

Prior to 2.077, this fails with array length problems.

After that it prints (at the moment): 402653184

If I up the size to 5, it fails with a range violation. I strongly 
suspect some off-by-one errors, but this looks unsafe.

-Steve


More information about the Digitalmars-d-learn mailing list