Consider the following "intrinsic" signature.
__m256i _mm256_loadu_si256 (const(__m256i)* mem_addr) pure @trusted; // (A)
The intel intrinsics signature have the problem that you must pass an implictely aligned __m256i (aka long4), however the pointer doesn't need to be aligned for an unaligned load. So, this is a bit playing with the type system. Inside the "intrinsic" implementation, nothing should use that non-existent alignment. Though in a way that hasn't blown up yet.
It is tempting to fix that and just take a long* or void* instead.
__m256i _mm256_loadu_si256 (const(void)* mem_addr) pure @system; // (B)
However, in that case, the function is not @trusted anymore, but becomes @system.
Indeed, it is safe to dereference a pointer, but not index from it.
What about float[4] then? We can get back @trusted.
__m256i _mm256_loadu_si256 (const(float[4])* mem_addr) pure @trusted; // (C)
Then, we loose compatibility ith intrinsics code originally written in C++. Casting to const(float[4])* is even more annoying to type than casting to const(__m256i)*.
What do you think is the better signature?
I'd prefer to go A > B > C, but figured I might be missing something.
Permalink
Reply