Skip to content

Commit

Permalink
Rollup merge of #87716 - calebzulawski:master, r=workingjubilee
Browse files Browse the repository at this point in the history
Allow generic SIMD array element type

Fixes the following:
```rust
#[repr(simd)]
struct V<T>([T; 4]);
```

cc ``@workingjubilee``
  • Loading branch information
JohnTitor committed Aug 3, 2021
2 parents b70c9dd + b23de51 commit 331e78d
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 15 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_typeck/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,7 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
match e.kind() {
ty::Param(_) => (), // pass struct<T>(T, T, T, T) through, let monomorphization catch errors
ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_) => (), // struct(u8, u8, u8, u8) is ok
ty::Array(t, _) if matches!(t.kind(), ty::Param(_)) => (), // pass struct<T>([T; N]) through, let monomorphization catch errors
ty::Array(t, _clen)
if matches!(
t.kind(),
Expand Down
58 changes: 43 additions & 15 deletions src/test/ui/simd/simd-generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,15 @@ struct f32x4(f32, f32, f32, f32);

#[repr(simd)]
#[derive(Copy, Clone)]
struct S<const N: usize>([f32; N]);
struct A<const N: usize>([f32; N]);

#[repr(simd)]
#[derive(Copy, Clone)]
struct B<T>([T; 4]);

#[repr(simd)]
#[derive(Copy, Clone)]
struct C<T, const N: usize>([T; N]);


extern "platform-intrinsic" {
Expand All @@ -29,7 +37,23 @@ impl ops::Add for f32x4 {
}
}

impl ops::Add for S<4> {
impl ops::Add for A<4> {
type Output = Self;

fn add(self, rhs: Self) -> Self {
unsafe { simd_add(self, rhs) }
}
}

impl ops::Add for B<f32> {
type Output = Self;

fn add(self, rhs: Self) -> Self {
unsafe { simd_add(self, rhs) }
}
}

impl ops::Add for C<f32, 4> {
type Output = Self;

fn add(self, rhs: Self) -> Self {
Expand All @@ -39,19 +63,23 @@ impl ops::Add for S<4> {


pub fn main() {
let lr = f32x4(1.0f32, 2.0f32, 3.0f32, 4.0f32);
let x = [1.0f32, 2.0f32, 3.0f32, 4.0f32];
let y = [2.0f32, 4.0f32, 6.0f32, 8.0f32];

// lame-o
let f32x4(x, y, z, w) = add(lr, lr);
assert_eq!(x, 2.0f32);
assert_eq!(y, 4.0f32);
assert_eq!(z, 6.0f32);
assert_eq!(w, 8.0f32);

let lr2 = S::<4>([1.0f32, 2.0f32, 3.0f32, 4.0f32]);
let [x, y, z, w] = add(lr2, lr2).0;
assert_eq!(x, 2.0f32);
assert_eq!(y, 4.0f32);
assert_eq!(z, 6.0f32);
assert_eq!(w, 8.0f32);
let a = f32x4(1.0f32, 2.0f32, 3.0f32, 4.0f32);
let f32x4(a0, a1, a2, a3) = add(a, a);
assert_eq!(a0, 2.0f32);
assert_eq!(a1, 4.0f32);
assert_eq!(a2, 6.0f32);
assert_eq!(a3, 8.0f32);

let a = A(x);
assert_eq!(add(a, a).0, y);

let b = B(x);
assert_eq!(add(b, b).0, y);

let c = C(x);
assert_eq!(add(c, c).0, y);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// build-fail

#![feature(repr_simd)]

struct E;

// error-pattern:monomorphising SIMD type `S<E>` with a non-primitive-scalar (integer/float/pointer) element type `E`

#[repr(simd)]
struct S<T>([T; 4]);

fn main() {
let _v: Option<S<E>> = None;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
error: monomorphising SIMD type `S<E>` with a non-primitive-scalar (integer/float/pointer) element type `E`

error: aborting due to previous error

0 comments on commit 331e78d

Please sign in to comment.