• Evan Nemerson's avatar
    sse2, avx: use void* for destinations of loadu functions · e4e2a2fa
    Evan Nemerson authored
    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.
    e4e2a2fa
sse2.h 239 KB