c++simdintrinsicsreinterpret-castc++23

How to use std::simd as input of SIMD intrinsics functions?


For now, the functions provided by std::datapar::simd and std::experimental::simd are somewhat limited, especially when it comes to element shuffling or non-trivial load patterns. Let's say, I have the following:

std::array<unsigned long long int, 16> a = {
    0, 100, 200, 300, 400, 500, 600, 700,
    800, 900, 1000, 1100, 1200, 1300, 1400, 1500
};
std::array<int, 4> vindex_data = {3, 7, 11, 15};
unsigned long long int* base_addr = a.data();
std::experimental::fixed_size_simd<int, 4> vindex(
    vindex_data.data(), 
    std::experimental::element_aligned
);
int scale = sizeof(unsigned long long int);
std::experimental::fixed_size_simd<unsigned long long int, 4> v;
/* And then I would like to load v using _mm256_i32gather_epi64*/
v = _mm256_i32gather_epi64(base_addr, vindex, scale); // This will not compile

Is there any non-standard way that would work on GCC and CLANG to call intrinsics SIMD functions on std::datapar::simd and std::experimental::simd (maybe through reinterpret_cast)?


Solution

  • The spec says

    Recommended practice: Implementations should support implicit conversions between specializations of basic_simd and appropriate implementation-defined types.

    [Note 1: Appropriate types are non-standard vector types which are available in the implementation. — end note]

    On a high-quality implementation, that last line should just work (after you fixed everything else that's wrong with the code before it). If not, complain to your vendor.