Thread overview
Advice needed: Fixing intrinsics signatures for those that unduely take aligned vectors ?
Jan 01, 2021
Guillaume Piolat
Jan 01, 2021
Guillaume Piolat
Jan 01, 2021
Guillaume Piolat
Jan 01, 2021
Guillaume Piolat
January 01, 2021
Some x86 intrinsics have no alignment requirement, but nonetheless take parameters that are aligned vector types.

- `__m128 _mm_loadh_pi (__m128 a, const(__m64)* mem_addr) `
- `__m128 _mm_loadl_pi (__m128 a, const(__m64)* mem_addr)`
- `__m128i _mm_loadu_si128 (const(__m128i)* mem_addr)`
- `__m128i _mm_loadl_epi64 (const(__m128i)* mem_addr)`
- `void _mm_storel_epi64 (__m128i* mem_addr, __m128i a)`
- `void _mm_storeu_si128 (__m128i* mem_addr, __m128i a)`

I guess the reasoning was that the intrinsics are modelled upon the instructions.

The implementation may look like this:

    /// Load 64-bit integer from memory into the first element of result.
    /// Zero out the other.
    __m128i _mm_loadl_epi64 (const(__m128i)* mem_addr) pure
    {
        auto pLong = cast(const(long)*)mem_addr;
        long2 r = [0, 0];
        r.ptr[0] = *pLong;
        return cast(__m128i)(r);
    }

No alignment problem within the function, but this signature often make the caller cast their input to a `(__m128i)`, but the memory isn't necessarily aligned.
(I've seen this happen with C++ compiler too).

eg: __m128i depthSamplesP0 = _mm_loadl_epi64( cast(const(__m128i)*)(depth) );


=== The Question ===

Should we change the signature to:

    __m128i _mm_loadl_epi64 (const(void)* mem_addr) pure   // instead of const(__m128i)*

instead to avoid an eventual error (and stay compatible with the original signatures)?

January 01, 2021
My other question is about @safe:



    I was told in D "memory safety" doesn't include null-safety. And indeed:


    float readOne(float* adr) @safe
    {
        return *adr; // this is safe
    }


Q: Does D's definition of @safety prevents memory alignment bugs?
   (such as a crash because of a MOVDQA on a non-aligned pointer for example).
January 01, 2021
On Friday, 1 January 2021 at 20:40:45 UTC, Guillaume Piolat wrote:
>
> Q: Does D's definition of @safety prevents memory alignment bugs?
>    (such as a crash because of a MOVDQA on a non-aligned pointer for example).

Doesn't D accept all traps as "safe"? Only overwriting data would be unsafe?

January 01, 2021
On 1/1/21 3:55 PM, Ola Fosheim Grøstad wrote:
> On Friday, 1 January 2021 at 20:40:45 UTC, Guillaume Piolat wrote:
>>
>> Q: Does D's definition of @safety prevents memory alignment bugs?
>>    (such as a crash because of a MOVDQA on a non-aligned pointer for example).
> 
> Doesn't D accept all traps as "safe"? Only overwriting data would be unsafe?
> 

Yes, something that terminates the program immediately is still safe in D's eyes. @safe is not looking to fix all bugs, just memory safety problems.

-Steve
January 01, 2021
On Friday, 1 January 2021 at 21:07:10 UTC, Steven Schveighoffer wrote:
> Yes, something that terminates the program immediately is still safe in D's eyes. @safe is not looking to fix all bugs, just memory safety problems.

But shouldn't reading out of bounds be safe too, or?

January 01, 2021
On Friday, 1 January 2021 at 21:11:09 UTC, Ola Fosheim Grøstad wrote:
> On Friday, 1 January 2021 at 21:07:10 UTC, Steven Schveighoffer wrote:
>> Yes, something that terminates the program immediately is still safe in D's eyes. @safe is not looking to fix all bugs, just memory safety problems.
>
> But shouldn't reading out of bounds be safe too, or?

Well, it obviously isn't. What I meant is that maybe it would be better to relax the requirements for reads in final builds since you have many reads and writes are more destructive. Just a thought.

January 01, 2021
On Friday, 1 January 2021 at 21:11:09 UTC, Ola Fosheim Grøstad wrote:
> On Friday, 1 January 2021 at 21:07:10 UTC, Steven Schveighoffer wrote:
>> Yes, something that terminates the program immediately is still safe in D's eyes. @safe is not looking to fix all bugs, just memory safety problems.
>
> But shouldn't reading out of bounds be safe too, or?

I guess the reasoning is that that doesn't necessarily lead to a program shutdown, for example your allocator may return more bytes. Hence, @safe must have bounds checking.
January 01, 2021
On Friday, 1 January 2021 at 21:07:10 UTC, Steven Schveighoffer wrote:
>
> Yes, something that terminates the program immediately is still safe in D's eyes. @safe is not looking to fix all bugs, just memory safety problems.
>
> -Steve

Thanks for answering. Makes sense.
January 01, 2021
On Friday, 1 January 2021 at 22:06:39 UTC, Guillaume Piolat wrote:
> I guess the reasoning is that that doesn't necessarily lead to a program shutdown, for example your allocator may return more bytes. Hence, @safe must have bounds checking.

I guess it depends on the nature of the array elements too. Read out of bounds from an array of arrays could lead to overwrites as it would get a bogus array, but not an array of floats which would only obtain a senseless floating point value.

January 01, 2021
On 1/1/21 4:22 PM, Ola Fosheim Grøstad wrote:
> On Friday, 1 January 2021 at 21:11:09 UTC, Ola Fosheim Grøstad wrote:
>> On Friday, 1 January 2021 at 21:07:10 UTC, Steven Schveighoffer wrote:
>>> Yes, something that terminates the program immediately is still safe in D's eyes. @safe is not looking to fix all bugs, just memory safety problems.
>>
>> But shouldn't reading out of bounds be safe too, or?
> 
> Well, it obviously isn't. What I meant is that maybe it would be better to relax the requirements for reads in final builds since you have many reads and writes are more destructive. Just a thought.
> 

foo(int*[] somearr)
{
  auto badptr = somearr[somearr.length]; // read happens here, what could go wrong?
  *badptr = 5; // oops
}

-Steve