sse2, avx: use void* for destinations of loadu functions
The vector types have alignment requirements, but these functions are
specifically for storing *unaligned* data. Some compilers (such as
clang 11) have started to generate bad code for the old versions, but
switching over to void* fixes that.
This also moves the _mm_loadu_epi{8,16,32,64} functions from AVX-512
over to SSE2 (for 128-bit) and AVX (for 256-bit), effectively replacing
the simde_x_mm*_loadu_* functions which are now simply aliases for the
AVX-512 functions.
The only real issue here is that our loadu_si* function take a void*
instead of a __m128i* or __m256i*, making them more permissive. Code
written against SIMDe will allow you to pass, for example, int8_t* data
to these functions without warning, whereas the _loadu_si* functions
will likely trigger a diagnostic.
The solution for this is for code using SIMDe to call functions like
_mm_loadu_epi8 instead of _mm_loadu_si128, even if they don't want to
use AVX-512. On SSE2, this will simply become a cast and call to
_mm_loadu_si128 and all is good. On other architectures we avoid
undefined behavior becous void* has no alignment requirements.
That means the only *real* problem is code which ifdefs SIMDe usage.
In C I would suggest casting to void* instead of __m128i* or __m256i*
when calling _mm_loadu_si128 or _mm_loadu_si256; everything will work
as expected. In C++, though, that will still generate a warning…
probably the best (well, least bad at least) solution there would be
to define a macro to use instead of _mm_loadu_si128/_mm256_loadu_si256
and use an ifdef to define it differently depending on whether you're
using SIMDe or not.
Showing
Please register or sign in to comment