Merge pull request #437 from AndrewScull/ctpop

Add count_ones() and count_zeros()
This commit is contained in:
Caleb Zulawski 2024-09-11 19:00:19 -04:00 committed by GitHub
commit 5fb43ca86f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 49 additions and 0 deletions

View file

@ -219,6 +219,12 @@ pub trait SimdInt: Copy + Sealed {
/// The least significant bit becomes the most significant bit, second least-significant bit becomes second most-significant bit, etc.
fn reverse_bits(self) -> Self;
/// Returns the number of ones in the binary representation of each element.
fn count_ones(self) -> Self::Unsigned;
/// Returns the number of zeros in the binary representation of each element.
fn count_zeros(self) -> Self::Unsigned;
/// Returns the number of leading zeros in the binary representation of each element.
fn leading_zeros(self) -> Self::Unsigned;
@ -367,6 +373,16 @@ macro_rules! impl_trait {
unsafe { core::intrinsics::simd::simd_bitreverse(self) }
}
#[inline]
fn count_ones(self) -> Self::Unsigned {
self.cast::<$unsigned>().count_ones()
}
#[inline]
fn count_zeros(self) -> Self::Unsigned {
self.cast::<$unsigned>().count_zeros()
}
#[inline]
fn leading_zeros(self) -> Self::Unsigned {
self.cast::<$unsigned>().leading_zeros()

View file

@ -101,6 +101,12 @@ pub trait SimdUint: Copy + Sealed {
/// The least significant bit becomes the most significant bit, second least-significant bit becomes second most-significant bit, etc.
fn reverse_bits(self) -> Self;
/// Returns the number of ones in the binary representation of each element.
fn count_ones(self) -> Self;
/// Returns the number of zeros in the binary representation of each element.
fn count_zeros(self) -> Self;
/// Returns the number of leading zeros in the binary representation of each element.
fn leading_zeros(self) -> Self;
@ -215,6 +221,17 @@ macro_rules! impl_trait {
unsafe { core::intrinsics::simd::simd_bitreverse(self) }
}
#[inline]
fn count_ones(self) -> Self {
// Safety: `self` is an integer vector
unsafe { core::intrinsics::simd::simd_ctpop(self) }
}
#[inline]
fn count_zeros(self) -> Self {
(!self).count_ones()
}
#[inline]
fn leading_zeros(self) -> Self {
// Safety: `self` is an integer vector

View file

@ -216,6 +216,22 @@ macro_rules! impl_common_integer_tests {
)
}
fn count_ones<const LANES: usize>() {
test_helpers::test_unary_elementwise(
&$vector::<LANES>::count_ones,
&|x| x.count_ones() as _,
&|_| true,
)
}
fn count_zeros<const LANES: usize>() {
test_helpers::test_unary_elementwise(
&$vector::<LANES>::count_zeros,
&|x| x.count_zeros() as _,
&|_| true,
)
}
fn leading_zeros<const LANES: usize>() {
test_helpers::test_unary_elementwise(
&$vector::<LANES>::leading_zeros,