Advice needed: Fixing intrinsics signatures for those that unduely take aligned vectors ?

Guillaume Piolat first.name at guess.com
Fri Jan 1 20:31:37 UTC 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)?



More information about the Digitalmars-d mailing list