leading_zeros() can return at most the number of bits of the underlying data type. The compiler does not seem to consider this during optimization.
Code
#![feature(core_intrinsics)]
const LOOKUP: [usize; 65] = [15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 12, 12, 12, 11, 11, 10, 10, 9, 8, 7, 6, 5, 4, 3, 0, 0];
pub fn min_selector(i: u64) -> usize {
let l_z = i.leading_zeros() as usize;
// unsafe {core::intrinsics::assume(l_z < 65);}
return LOOKUP[l_z];
}
Tested on rustc 1.51.0 (2fd73fabe 2021-03-23), nightly in the Compiler Explorer with -C opt-level=3.
I expect the unsafe block to have no effect, since u64::leading_zeros() shouldn't return a number greater than 64. Instead, the disassembly shows that there is a bounds check which disappears when the unsafe block is uncommented.
leading_zeros()can return at most the number of bits of the underlying data type. The compiler does not seem to consider this during optimization.Code
Tested on
rustc 1.51.0 (2fd73fabe 2021-03-23),nightlyin the Compiler Explorer with-C opt-level=3.I expect the unsafe block to have no effect, since
u64::leading_zeros()shouldn't return a number greater than 64. Instead, the disassembly shows that there is a bounds check which disappears when theunsafeblock is uncommented.