@@ -18,17 +18,28 @@ macro_rules! simd_ty {
1818 #[ inline( always) ]
1919 pub ( crate ) const fn splat( value: $ety) -> Self {
2020 $id( $( {
21+ // We want this to be repeated for each element.
22+ // So we need to use `elem_name` in a `$(...)`.
23+ // But we don't actually need that name for anything so we use a dummy struct.
2124 #[ allow( non_camel_case_types, dead_code) ]
2225 struct $elem_name;
2326 value
2427 } ) ,* )
2528 }
2629
30+ /// Extract the element at position `index`.
31+ /// `index` is not a constant so this is not efficient!
32+ /// Use for testing only.
2733 // FIXME: Workaround rust@60637
2834 #[ inline( always) ]
2935 pub ( crate ) fn extract( self , index: usize ) -> $ety {
36+ // Here we assume that there is no padding.
37+ let len = crate :: mem:: size_of:: <Self >( ) / crate :: mem:: size_of:: <$ety>( ) ;
38+ assert!( index < len) ;
39+ // Now that we know this is in-bounds, use pointer arithmetic to access the right element.
40+ let self_ptr = & self as * const Self as * const $ety;
3041 unsafe {
31- crate :: core_arch :: simd_llvm :: simd_extract ( self , index as u32 )
42+ self_ptr . add ( index) . read ( )
3243 }
3344 }
3445 }
@@ -62,15 +73,6 @@ macro_rules! simd_m_ty {
6273 Self :: bool_to_internal( value)
6374 } ) ,* )
6475 }
65-
66- // FIXME: Workaround rust@60637
67- #[ inline( always) ]
68- pub ( crate ) fn extract( self , index: usize ) -> bool {
69- let r: $ety = unsafe {
70- crate :: core_arch:: simd_llvm:: simd_extract( self , index as u32 )
71- } ;
72- r != 0
73- }
7476 }
7577 }
7678}
0 commit comments