Skip to content

Conversation

@quaternic
Copy link
Contributor

@quaternic quaternic commented Dec 2, 2025

Feature gate: #![feature(uint_gather_scatter_bits)]
Tracking issue: #149069
Accepted ACP: rust-lang/libs-team#695 (comment)

Adds an additional runtime test for uN::gather_bits and uN::scatter_bits in coretests. They are each other's inverses in a sense, so a shared test can test both with relative ease.

I plan to follow up with optimized implementations for these functions.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Dec 2, 2025
@rustbot
Copy link
Collaborator

rustbot commented Dec 2, 2025

r? @Mark-Simulacrum

rustbot has assigned @Mark-Simulacrum.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

assert_eq!(&xs, &[0xff, 0x00, 0x0f, 0xf0, 0x33, 0xcc, 0x55, 0xaa]);
}

// `256 * BITS` masks
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the below loop, the total count of calls to one of the tested functions comes up to about 512 * BITS * BITS. As the current implementation is itself a 0..BITS-loop (in the worst case when the mask has most bits set), the u128 test would be doing on the order of 10^9 operations, and completes in ~2s locally, which might be excessive for a single test. Any ideas on what to trim?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the for k in 0..BITS scatter loop, t will be zeroed out before the loop is complete so some iterations could be shaved.
It won't have the same coverage, but you could combine the for k in 0..BITS and for k in 0..count loops together since their iteration count would both be the number of mask bits.

let mut t = sparse; for k in 0..count { let lowest_one = t.isolate_lowest_one(); let gathered_bits = lowest_one.gather_bits(sparse); let shifted_bit = ((1 as $T) << k); let scattered_bits = shifted_bit.scatter_bits(sparse); assert_eq!(gathered_bits, shifted_bit); assert_eq!(scattered_bits, lowest_one); t ^= lowest_one; } assert_eq!(t, 0);

Then, outside of the sparse_masks loop, we can explicitly check the property.

// If t.trailing_zeros() >= the mask's bit width, the result is 0 let mut t = !(0 as $T); for _ in 0..$T::BITS { assert_eq!(0, t.scatter_bits(!t)); t <<= 1; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue.

4 participants