-
Notifications
You must be signed in to change notification settings - Fork 299
Description
Some C compilers (clang
and gcc
at least) define unaligned vector types. Vectors are often read from unaligned locations, and then using and dereferencing a pointer to the normal vector types would be UB. Hence these types:
// emmintrin.h
typedef double __m128d_u __attribute__((__vector_size__(16), __aligned__(1)));
typedef long long __m128i_u __attribute__((__vector_size__(16), __aligned__(1)));
// xmmintrin.h
typedef float __m128_u __attribute__((__vector_size__(16), __aligned__(1)));
// avxintrin.h
typedef float __m256_u __attribute__ ((__vector_size__ (32), __aligned__(1)));
typedef double __m256d_u __attribute__((__vector_size__(32), __aligned__(1)));
typedef long long __m256i_u __attribute__((__vector_size__(32), __aligned__(1)));
// avx512intrin.h
typedef float __m512_u __attribute__((__vector_size__(64), __aligned__(1)));
typedef double __m512d_u __attribute__((__vector_size__(64), __aligned__(1)));
typedef long long __m512i_u __attribute__((__vector_size__(64), __aligned__(1)));
They have the size of the standard vector types, but an alignment of 1. These types are useful for translating C to rust. e.g. immunant/c2rust#1132.
Proposal
Define these types as one of these
#[repr(C)]
struct([u8; 16]);
#[repr(C)]
struct __m128d_u(u8, u8, u8, ..., u8);
#[repr(C, packed(1))]
struct __m128d_u(f64, f64);
I think the first option runs into arrays technically not being FFI-safe. Option 2 is kind of cumbersome, so I'd like to explore option 3 using packed
. The packed
option can be a little weird, but I don't think that matters here. The whole purpose of this type is just to load the value, and then it'll likely just get transmuted to a proper vector type.
I can open this as an ACP if that is the proper route.