Open
Description
The following example shows that rustc
does not optimize boolean computations for the usize
type.
I tried this code: (opt-level=3)
https://www.godbolt.org/z/zY3Kqj8ax
#[no_mangle]
fn even(x: usize) -> bool {
if !(x >= (0 + 2)) {
return false;
} else if x == 2 {
return true;
} else {
return even(x - 2);
}
}
I expected to see this happen:
even:
cmp rdi, 2
jae .LBB0_2
xor eax, eax
ret
.LBB0_2:
mov rax, rdi
add rdi, -2
and rax, -2
cmp rax, 2
jne .LBB0_2
test rdi, rdi
sete al
ret
Instead, this happened:
even:
cmp rdi, 2
jb .LBB0_1
lea rcx, [rdi - 2]
mov eax, ecx
shr eax
inc eax
and eax, 7
je .LBB0_3
add eax, eax
xor edx, edx
.LBB0_5:
add rdx, 2
cmp rax, rdx
jne .LBB0_5
sub rdi, rdx
sete al
cmp rcx, 14
jae .LBB0_8
.LBB0_10:
and al, 1
ret
.LBB0_1:
xor eax, eax
and al, 1
ret
.LBB0_3:
cmp rcx, 14
jb .LBB0_10
.LBB0_8:
add rdi, -16
cmp rdi, 1
ja .LBB0_8
test rdi, rdi
sete al
and al, 1
ret
However, when I change the type from usize
to i32
, the compiler generates the desired assembly code. Additionally, I can also get optimized result by rewriting if !(x >= (0 + 2))
as if x < 2
.
Therefore, I think that something wrong may occur when optimizing boolean computation for usize
type. If addressed in the future, this improvement could enhance rustc
's code generation efficiency for such cases.
Could you please review the situation? Thank you!
Meta
rustc 1.85.0-nightly (d117b7f21 2024-12-31)
binary: rustc
commit-hash: d117b7f211835282b3b177dc64245fff0327c04c
commit-date: 2024-12-31
host: x86_64-unknown-linux-gnu
release: 1.85.0-nightly
LLVM version: 19.1.6
Metadata
Metadata
Assignees
Labels
Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Category: An issue highlighting optimization opportunities or PRs implementing suchIssue: Problems and improvements with respect to performance of generated code.Relevant to the compiler team, which will review and decide on the PR/issue.