66#![ allow( incomplete_features) ]
77#![ feature( adt_const_params) ]
88
9+ use std:: marker:: ConstParamTy ;
10+
911extern "rust-intrinsic" {
1012 fn simd_shuffle < T , I , U > ( a : T , b : T , i : I ) -> U ;
1113}
1214
13- #[ derive( Copy , Clone ) ]
15+ #[ derive( Copy , Clone , ConstParamTy , PartialEq , Eq ) ]
1416#[ repr( simd) ]
1517struct Simd < T , const N : usize > ( [ T ; N ] ) ;
1618
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 {
1823 simd_shuffle ( x, y, IDX )
1924}
2025
@@ -30,6 +35,17 @@ fn main() {
3035 let y: Simd < u8 , 2 > = simd_shuffle ( a, b, I2 ) ;
3136 assert_eq ! ( y. 0 , [ 1 , 5 ] ) ;
3237 }
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+
3349 // Test that an indirection (via an unnamed constant)
3450 // through a const generic parameter also works.
3551 // See https://github.com/rust-lang/rust/issues/113500 for details.
@@ -42,4 +58,11 @@ fn main() {
4258 Simd < u8 , 16 > ,
4359 > ( a, b) ;
4460 }
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+ }
4568}
0 commit comments