Description
I compiled the following code (Godbolt):
use std::hint::assert_unchecked;
#[no_mangle]
unsafe fn foo(x: u32) -> bool {
assert_unchecked(x.is_power_of_two());
x == 0
}
With -Copt-level=3 -Cdebuginfo=2
, I got this assembly:
foo:
test edi, edi
sete al
ret
In the above assembly, the compiler doesn't realize that x
being a power of two implies that it is not zero.
However, with -Copt-level=3 -Cdebuginfo=0
, I got this assembly:
foo:
xor eax, eax
ret
That is, the compiler correctly optimizes the code to always returning false.
I expect debuginfo to not impact the amount of optimization, so I'm assuming that this is a bug.
Additional context
This was discovered while checking whether x % y
is optimized when y
is known to be a power of two.
I compiled the following code (Godbolt):
use std::hint::assert_unchecked;
#[no_mangle]
unsafe fn foo(x: u32, y: u32) -> u32 {
assert_unchecked(y.is_power_of_two());
x % y
}
#[no_mangle]
unsafe fn bar(x: u32, y: u32) -> u32 {
assert_unchecked(y != 0 && y.is_power_of_two());
x % y
}
With -Copt-level=3 -Cdebuginfo=2
, I got this assembly:
foo:
test esi, esi
je .LBB0_2
mov eax, edi
xor edx, edx
div esi
mov eax, edx
ret
.LBB0_2:
push rax
lea rdi, [rip + .L__unnamed_1]
call qword ptr [rip + core::panicking::panic_const::panic_const_rem_by_zero::h39e69d103ed030d2@GOTPCREL]
bar:
lea eax, [rsi - 1]
and eax, edi
ret
.L__unnamed_2:
.ascii "/app/example.rs"
.L__unnamed_1:
.quad .L__unnamed_2
.asciz "\017\000\000\000\000\000\000\000\006\000\000\000\005\000\000"
However, with -Copt-level=3 -Cdebuginfo=0
, I got this assembly:
foo:
lea eax, [rsi - 1]
and eax, edi
ret
bar:
lea eax, [rsi - 1]
and eax, edi
ret
This seems to imply that LLVM can make use of the fact that is_power_of_two
returns true to do optimizations. However, for some reason, when debuginfo is on, it can't figure out that is_power_of_two
implies that the number is not zero.
Meta
The issue is reproducible on Godbolt with version info:
rustc 1.87.0-nightly (f280acf4c 2025-02-19)
binary: rustc
commit-hash: f280acf4c743806abbbbcfe65050ac52ec4bdec0
commit-date: 2025-02-19
host: x86_64-unknown-linux-gnu
release: 1.87.0-nightly
LLVM version: 20.1.0
Internal compiler ID: nightly
@rustbot labels +C-optimization +A-debuginfo