6
6
#![ allow( incomplete_features) ]
7
7
#![ feature( adt_const_params) ]
8
8
9
+ use std:: marker:: ConstParamTy ;
10
+
9
11
extern "rust-intrinsic" {
10
12
fn simd_shuffle < T , I , U > ( a : T , b : T , i : I ) -> U ;
11
13
}
12
14
13
- #[ derive( Copy , Clone ) ]
15
+ #[ derive( Copy , Clone , ConstParamTy , PartialEq , Eq ) ]
14
16
#[ repr( simd) ]
15
17
struct Simd < T , const N : usize > ( [ T ; N ] ) ;
16
18
17
- pub unsafe fn __shuffle_vector16 < const IDX : [ u32 ; 16 ] , T , U > ( x : T , y : T ) -> U {
19
+ unsafe fn __shuffle_vector16 < const IDX : [ u32 ; 16 ] , T , U > ( x : T , y : T ) -> U {
20
+ simd_shuffle ( x, y, IDX )
21
+ }
22
+ unsafe fn __shuffle_vector16_v2 < const IDX : Simd < u32 , 16 > , T , U > ( x : T , y : T ) -> U {
18
23
simd_shuffle ( x, y, IDX )
19
24
}
20
25
@@ -30,6 +35,17 @@ fn main() {
30
35
let y: Simd < u8 , 2 > = simd_shuffle ( a, b, I2 ) ;
31
36
assert_eq ! ( y. 0 , [ 1 , 5 ] ) ;
32
37
}
38
+ // Test that we can also use a SIMD vector instead of a normal array for the shuffle.
39
+ const I1_SIMD : Simd < u32 , 4 > = Simd ( [ 0 , 2 , 4 , 6 ] ) ;
40
+ const I2_SIMD : Simd < u32 , 2 > = Simd ( [ 1 , 5 ] ) ;
41
+ unsafe {
42
+ let x: Simd < u8 , 4 > = simd_shuffle ( a, b, I1_SIMD ) ;
43
+ assert_eq ! ( x. 0 , [ 0 , 2 , 4 , 6 ] ) ;
44
+
45
+ let y: Simd < u8 , 2 > = simd_shuffle ( a, b, I2_SIMD ) ;
46
+ assert_eq ! ( y. 0 , [ 1 , 5 ] ) ;
47
+ }
48
+
33
49
// Test that an indirection (via an unnamed constant)
34
50
// through a const generic parameter also works.
35
51
// See https://github.com/rust-lang/rust/issues/113500 for details.
@@ -42,4 +58,11 @@ fn main() {
42
58
Simd < u8 , 16 > ,
43
59
> ( a, b) ;
44
60
}
61
+ unsafe {
62
+ __shuffle_vector16_v2 :: <
63
+ { Simd ( [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 ] ) } ,
64
+ Simd < u8 , 16 > ,
65
+ Simd < u8 , 16 > ,
66
+ > ( a, b) ;
67
+ }
45
68
}
0 commit comments