12
12
) ]
13
13
mod mask_impl;
14
14
15
- use crate :: simd:: {
16
- cmp:: SimdPartialEq , intrinsics, LaneCount , Simd , SimdCast , SimdElement , SupportedLaneCount ,
17
- } ;
15
+ use crate :: simd:: { LaneCount , Simd , SimdCast , SimdElement , SupportedLaneCount } ;
18
16
use core:: cmp:: Ordering ;
19
17
use core:: { fmt, mem} ;
20
18
@@ -35,7 +33,7 @@ mod sealed {
35
33
36
34
fn eq ( self , other : Self ) -> bool ;
37
35
38
- fn as_usize ( self ) -> usize ;
36
+ fn to_usize ( self ) -> usize ;
39
37
40
38
type Unsigned : SimdElement ;
41
39
@@ -60,14 +58,23 @@ macro_rules! impl_element {
60
58
where
61
59
LaneCount <N >: SupportedLaneCount ,
62
60
{
63
- ( value. simd_eq( Simd :: splat( 0 as _) ) | value. simd_eq( Simd :: splat( -1 as _) ) ) . all( )
61
+ // We can't use `Simd` directly, because `Simd`'s functions call this function and
62
+ // we will end up with an infinite loop.
63
+ // Safety: `value` is an integer vector
64
+ unsafe {
65
+ use core:: intrinsics:: simd;
66
+ let falses: Simd <Self , N > = simd:: simd_eq( value, Simd :: splat( 0 as _) ) ;
67
+ let trues: Simd <Self , N > = simd:: simd_eq( value, Simd :: splat( -1 as _) ) ;
68
+ let valid: Simd <Self , N > = simd:: simd_or( falses, trues) ;
69
+ simd:: simd_reduce_all( valid)
70
+ }
64
71
}
65
72
66
73
#[ inline]
67
74
fn eq( self , other: Self ) -> bool { self == other }
68
75
69
76
#[ inline]
70
- fn as_usize ( self ) -> usize {
77
+ fn to_usize ( self ) -> usize {
71
78
self as usize
72
79
}
73
80
@@ -141,8 +148,9 @@ where
141
148
// but these are "dependently-sized" types, so copy elision it is!
142
149
unsafe {
143
150
let bytes: [ u8 ; N ] = mem:: transmute_copy ( & array) ;
144
- let bools: Simd < i8 , N > = intrinsics:: simd_ne ( Simd :: from_array ( bytes) , Simd :: splat ( 0u8 ) ) ;
145
- Mask :: from_int_unchecked ( intrinsics:: simd_cast ( bools) )
151
+ let bools: Simd < i8 , N > =
152
+ core:: intrinsics:: simd:: simd_ne ( Simd :: from_array ( bytes) , Simd :: splat ( 0u8 ) ) ;
153
+ Mask :: from_int_unchecked ( core:: intrinsics:: simd:: simd_cast ( bools) )
146
154
}
147
155
}
148
156
@@ -160,7 +168,7 @@ where
160
168
// This would be hypothetically valid as an "in-place" transmute,
161
169
// but these are "dependently-sized" types, so copy elision it is!
162
170
unsafe {
163
- let mut bytes: Simd < i8 , N > = intrinsics:: simd_cast ( self . to_int ( ) ) ;
171
+ let mut bytes: Simd < i8 , N > = core :: intrinsics:: simd :: simd_cast ( self . to_int ( ) ) ;
164
172
bytes &= Simd :: splat ( 1i8 ) ;
165
173
mem:: transmute_copy ( & bytes)
166
174
}
@@ -175,7 +183,10 @@ where
175
183
#[ must_use = "method returns a new mask and does not mutate the original value" ]
176
184
pub unsafe fn from_int_unchecked ( value : Simd < T , N > ) -> Self {
177
185
// Safety: the caller must confirm this invariant
178
- unsafe { Self ( mask_impl:: Mask :: from_int_unchecked ( value) ) }
186
+ unsafe {
187
+ core:: intrinsics:: assume ( <T as Sealed >:: valid ( value) ) ;
188
+ Self ( mask_impl:: Mask :: from_int_unchecked ( value) )
189
+ }
179
190
}
180
191
181
192
/// Converts a vector of integers to a mask, where 0 represents `false` and -1
@@ -374,23 +385,25 @@ where
374
385
) ;
375
386
376
387
// Safety: the input and output are integer vectors
377
- let index: Simd < T , N > = unsafe { intrinsics:: simd_cast ( index) } ;
388
+ let index: Simd < T , N > = unsafe { core :: intrinsics:: simd :: simd_cast ( index) } ;
378
389
379
390
let masked_index = self . select ( index, Self :: splat ( true ) . to_int ( ) ) ;
380
391
381
392
// Safety: the input and output are integer vectors
382
- let masked_index: Simd < T :: Unsigned , N > = unsafe { intrinsics:: simd_cast ( masked_index) } ;
393
+ let masked_index: Simd < T :: Unsigned , N > =
394
+ unsafe { core:: intrinsics:: simd:: simd_cast ( masked_index) } ;
383
395
384
396
// Safety: the input is an integer vector
385
- let min_index: T :: Unsigned = unsafe { intrinsics:: simd_reduce_min ( masked_index) } ;
397
+ let min_index: T :: Unsigned =
398
+ unsafe { core:: intrinsics:: simd:: simd_reduce_min ( masked_index) } ;
386
399
387
400
// Safety: the return value is the unsigned version of T
388
401
let min_index: T = unsafe { core:: mem:: transmute_copy ( & min_index) } ;
389
402
390
403
if min_index. eq ( T :: TRUE ) {
391
404
None
392
405
} else {
393
- Some ( min_index. as_usize ( ) )
406
+ Some ( min_index. to_usize ( ) )
394
407
}
395
408
}
396
409
}
0 commit comments