How to correctly use std::arch::_mm_loadu_si128 / _mm_storeu_si128

Viewed 543

Usually one should be wary of transmuting (or casting) pointers to a higher alignment. Yet the interface to the above functions require *const _m128i and *mut _m128i pointers, respectively. Both are SIMD-aligned, which means I'd need to keep my arrays SIMD-aligned, too. On the other hand, the intrinsics are explicitly designed to load/store unaligned data.

Is this safe? Shouldn't we change the interface? Or at least document this fact?

1 Answers

I think this is a cross-language duplicate of Is `reinterpret_cast`ing between hardware vector pointer and the corresponding type an undefined behavior?.

As I explained over there, Intel defined the C/C++ intrinsics API such that loadu / storeu can safely dereference an under-aligned pointer, and that it's safe to create such pointers, even though it's UB in ISO C++ even to create under-aligned pointers. (Thus implementations that provide the intrinsics API must define the behaviour).

The Rust version should work identically. Implementations that provide it must make it safe to create under-aligned __m128i* pointers, as long as you don't dereference them "manually".

The other API-design option would be to have another version of the type that doesn't imply 16-byte alignment, like a __m128i_u or something. GNU C does this with their native vector syntax, but that's way off topic for Rust.

Related