Skip to content

Commit 5fb43ca

Browse files
Merge pull request rust-lang#437 from AndrewScull/ctpop
Add count_ones() and count_zeros()
2 parents e967f5e + 27e2832 commit 5fb43ca

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

Diff for: crates/core_simd/src/simd/num/int.rs

+16
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,12 @@ pub trait SimdInt: Copy + Sealed {
219219
/// The least significant bit becomes the most significant bit, second least-significant bit becomes second most-significant bit, etc.
220220
fn reverse_bits(self) -> Self;
221221

222+
/// Returns the number of ones in the binary representation of each element.
223+
fn count_ones(self) -> Self::Unsigned;
224+
225+
/// Returns the number of zeros in the binary representation of each element.
226+
fn count_zeros(self) -> Self::Unsigned;
227+
222228
/// Returns the number of leading zeros in the binary representation of each element.
223229
fn leading_zeros(self) -> Self::Unsigned;
224230

@@ -367,6 +373,16 @@ macro_rules! impl_trait {
367373
unsafe { core::intrinsics::simd::simd_bitreverse(self) }
368374
}
369375

376+
#[inline]
377+
fn count_ones(self) -> Self::Unsigned {
378+
self.cast::<$unsigned>().count_ones()
379+
}
380+
381+
#[inline]
382+
fn count_zeros(self) -> Self::Unsigned {
383+
self.cast::<$unsigned>().count_zeros()
384+
}
385+
370386
#[inline]
371387
fn leading_zeros(self) -> Self::Unsigned {
372388
self.cast::<$unsigned>().leading_zeros()

Diff for: crates/core_simd/src/simd/num/uint.rs

+17
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ pub trait SimdUint: Copy + Sealed {
101101
/// The least significant bit becomes the most significant bit, second least-significant bit becomes second most-significant bit, etc.
102102
fn reverse_bits(self) -> Self;
103103

104+
/// Returns the number of ones in the binary representation of each element.
105+
fn count_ones(self) -> Self;
106+
107+
/// Returns the number of zeros in the binary representation of each element.
108+
fn count_zeros(self) -> Self;
109+
104110
/// Returns the number of leading zeros in the binary representation of each element.
105111
fn leading_zeros(self) -> Self;
106112

@@ -215,6 +221,17 @@ macro_rules! impl_trait {
215221
unsafe { core::intrinsics::simd::simd_bitreverse(self) }
216222
}
217223

224+
#[inline]
225+
fn count_ones(self) -> Self {
226+
// Safety: `self` is an integer vector
227+
unsafe { core::intrinsics::simd::simd_ctpop(self) }
228+
}
229+
230+
#[inline]
231+
fn count_zeros(self) -> Self {
232+
(!self).count_ones()
233+
}
234+
218235
#[inline]
219236
fn leading_zeros(self) -> Self {
220237
// Safety: `self` is an integer vector

Diff for: crates/core_simd/tests/ops_macros.rs

+16
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,22 @@ macro_rules! impl_common_integer_tests {
216216
)
217217
}
218218

219+
fn count_ones<const LANES: usize>() {
220+
test_helpers::test_unary_elementwise(
221+
&$vector::<LANES>::count_ones,
222+
&|x| x.count_ones() as _,
223+
&|_| true,
224+
)
225+
}
226+
227+
fn count_zeros<const LANES: usize>() {
228+
test_helpers::test_unary_elementwise(
229+
&$vector::<LANES>::count_zeros,
230+
&|x| x.count_zeros() as _,
231+
&|_| true,
232+
)
233+
}
234+
219235
fn leading_zeros<const LANES: usize>() {
220236
test_helpers::test_unary_elementwise(
221237
&$vector::<LANES>::leading_zeros,

0 commit comments

Comments
 (0)