I was studying the x86_64 assembly for the following function:
/// Returns the greatest power of two less than or equal to `self`, or 0 otherwise.
pub const fn prev_power_of_two(n: u64) -> u64 {
// n = 0 gives highest_bit_set_idx = 0.
let highest_bit_set_idx = 63 - (n|1).leading_zeros();
// Binary AND of highest bit with n is a no-op, except zero gets wiped.
(1 << highest_bit_set_idx) & n
}
When compiling with -C opt=level=3
we get the following assembly on nightly and 1.50.0:
example::prev_power_of_two:
mov rax, rdi
or rax, 1
bsr rcx, rax
xor ecx, 63
xor cl, 63
mov eax, 1
shl rax, cl
and rax, rdi
ret
Everything seems good, except I can't explain these two instructions:
xor ecx, 63
xor cl, 63
As far as I can see, these are a no-op. Why are they generated?
This problem has been fixed. Rust nightly no longer generates these xor
instructions.
See Godbolt
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With