leading_zeros.rs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. use rand_xoshiro::rand_core::{RngCore, SeedableRng};
  2. use rand_xoshiro::Xoshiro128StarStar;
  3. use compiler_builtins::int::__clzsi2;
  4. use compiler_builtins::int::leading_zeros::{
  5. usize_leading_zeros_default, usize_leading_zeros_riscv,
  6. };
  7. #[test]
  8. fn __clzsi2_test() {
  9. // Binary fuzzer. We cannot just send a random number directly to `__clzsi2()`, because we need
  10. // large sequences of zeros to test. This XORs, ANDs, and ORs random length strings of 1s to
  11. // `x`. ORs insure sequences of ones, ANDs insures sequences of zeros, and XORs are not often
  12. // destructive but add entropy.
  13. let mut rng = Xoshiro128StarStar::seed_from_u64(0);
  14. let mut x = 0usize;
  15. // creates a mask for indexing the bits of the type
  16. let bit_indexing_mask = usize::MAX.count_ones() - 1;
  17. // 10000 iterations is enough to make sure edge cases like single set bits are tested and to go
  18. // through many paths.
  19. for _ in 0..10_000 {
  20. let r0 = bit_indexing_mask & rng.next_u32();
  21. // random length of ones
  22. let ones: usize = !0 >> r0;
  23. let r1 = bit_indexing_mask & rng.next_u32();
  24. // random circular shift
  25. let mask = ones.rotate_left(r1);
  26. match rng.next_u32() % 4 {
  27. 0 => x |= mask,
  28. 1 => x &= mask,
  29. // both 2 and 3 to make XORs as common as ORs and ANDs combined
  30. _ => x ^= mask,
  31. }
  32. let lz = x.leading_zeros() as usize;
  33. let lz0 = __clzsi2(x);
  34. let lz1 = usize_leading_zeros_default(x);
  35. let lz2 = usize_leading_zeros_riscv(x);
  36. if lz0 != lz {
  37. panic!("__clzsi2({}): expected: {}, found: {}", x, lz, lz0);
  38. }
  39. if lz1 != lz {
  40. panic!(
  41. "usize_leading_zeros_default({}): expected: {}, found: {}",
  42. x, lz, lz1
  43. );
  44. }
  45. if lz2 != lz {
  46. panic!(
  47. "usize_leading_zeros_riscv({}): expected: {}, found: {}",
  48. x, lz, lz2
  49. );
  50. }
  51. }
  52. }