//@ run-pass #![feature(repr_simd, intrinsics)] #![allow(non_camel_case_types)] #[repr(simd, packed)] struct Simd([T; N]); #[repr(simd)] struct FullSimd([T; N]); fn check_size_align() { use std::mem; assert_eq!(mem::size_of::>(), mem::size_of::<[T; N]>()); assert_eq!(mem::size_of::>() % mem::align_of::>(), 0); } fn check_ty() { check_size_align::(); check_size_align::(); check_size_align::(); check_size_align::(); check_size_align::(); check_size_align::(); check_size_align::(); } extern "rust-intrinsic" { fn simd_add(a: T, b: T) -> T; } fn main() { check_ty::(); check_ty::(); check_ty::(); check_ty::(); check_ty::(); check_ty::(); check_ty::(); unsafe { // powers-of-two have no padding and work as usual let x: Simd = simd_add(Simd::([0., 1., 2., 3.]), Simd::([2., 2., 2., 2.])); assert_eq!(std::mem::transmute::<_, [f64; 4]>(x), [2., 3., 4., 5.]); // non-powers-of-two have padding and need to be expanded to full vectors fn load(v: Simd) -> FullSimd { unsafe { let mut tmp = core::mem::MaybeUninit::>::uninit(); std::ptr::copy_nonoverlapping(&v as *const _, tmp.as_mut_ptr().cast(), 1); tmp.assume_init() } } let x: FullSimd = simd_add(load(Simd::([0., 1., 2.])), load(Simd::([2., 2., 2.]))); assert_eq!(x.0, [2., 3., 4.]); } }