From 6e88e96ccf1ca7621e6177d729a69625838db1c8 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Sat, 13 Jul 2019 17:16:57 +0200 Subject: Support repr(simd) on ADTs containing a single array field This PR allows using `#[repr(simd)]` on ADTs containing a single array field: ```rust #[repr(simd)] struct S0([f32; 4]); #[repr(simd)] struct S1([f32; N]); #[repr(simd)] struct S2([T; N]); ``` This should allow experimenting with portable packed SIMD abstractions on nightly that make use of const generics. --- .../simd-intrinsic-generic-extract-insert.rs | 47 ++++++++++++++++++++++ .../simd-intrinsic-transmute-array.rs | 44 ++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 src/test/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs create mode 100644 src/test/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs (limited to 'src/test/codegen') diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs new file mode 100644 index 00000000000..3dba044d376 --- /dev/null +++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs @@ -0,0 +1,47 @@ +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] + +#![feature(repr_simd, platform_intrinsics, const_generics)] +#![allow(non_camel_case_types, incomplete_features)] + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct M(pub f32, pub f32, pub f32, pub f32); + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct S([f32; N]); + +extern "platform-intrinsic" { + fn simd_extract(x: T, idx: u32) -> U; + fn simd_insert(x: T, idx: u32, b: U) -> T; +} + +// CHECK-LABEL: @extract_m +#[no_mangle] +pub unsafe fn extract_m(v: M, i: u32) -> f32 { + // CHECK: extractelement <4 x float> %0, i32 %i + simd_extract(v, i) +} + +// CHECK-LABEL: @extract_s +#[no_mangle] +pub unsafe fn extract_s(v: S<4>, i: u32) -> f32 { + // CHECK: extractelement <4 x float> %0, i32 %i + simd_extract(v, i) +} + +// CHECK-LABEL: @insert_m +#[no_mangle] +pub unsafe fn insert_m(v: M, i: u32, j: f32) -> M { + // CHECK: insertelement <4 x float> %1, float %j, i32 %i + simd_insert(v, i, j) +} + +// CHECK-LABEL: @insert_s +#[no_mangle] +pub unsafe fn insert_s(v: S<4>, i: u32, j: f32) -> S<4> { + // CHECK: insertelement <4 x float> %1, float %j, i32 %i + simd_insert(v, i, j) +} diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs new file mode 100644 index 00000000000..23098e7f649 --- /dev/null +++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs @@ -0,0 +1,44 @@ +// ignore-tidy-linelength +// compile-flags: -C no-prepopulate-passes +// min-llvm-version 8.0 + +#![crate_type = "lib"] + +#![allow(non_camel_case_types, incomplete_features)] +#![feature(repr_simd, platform_intrinsics, const_generics)] + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct S([f32; N]); + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct T([f32; 4]); + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct U(f32, f32, f32, f32); + +// CHECK-LABEL: @build_array_s +#[no_mangle] +pub fn build_array_s(x: [f32; 4]) -> S<4> { + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}} %{{[0-9]+}}, i8* {{.*}} %3, i64 16, i1 false) + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}} %{{[0-9]+}}, i8* {{.*}} %6, i64 16, i1 false) + S::<4>(x) +} + +// CHECK-LABEL: @build_array_t +#[no_mangle] +pub fn build_array_t(x: [f32; 4]) -> T { + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}} %{{[0-9]+}}, i8* {{.*}} %3, i64 16, i1 false) + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}} %{{[0-9]+}}, i8* {{.*}} %6, i64 16, i1 false) + T(x) +} + +// CHECK-LABEL: @build_array_u +#[no_mangle] +pub fn build_array_u(x: [f32; 4]) -> U { + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}} %{{[0-9]+}}, i8* {{.*}} %3, i64 16, i1 false) + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}} %{{[0-9]+}}, i8* {{.*}} %6, i64 16, i1 false) + unsafe { std::mem::transmute(x) } +} -- cgit 1.4.1-3-g733a5