-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Open
Labels
A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchCategory: An issue highlighting optimization opportunities or PRs implementing suchI-slowIssue: Problems and improvements with respect to performance of generated code.Issue: Problems and improvements with respect to performance of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
I tried this code:
#[derive(Clone, Copy)]
#[repr(u8)]
pub enum Len {
Zero = 0,
One,
Two,
Three,
}
#[no_mangle]
pub fn convert_len(len: &Len) -> Option<usize> {
match *len {
// Len::Zero => Some(0), // This produces optimal code.
Len::Zero => None, // This does not: two table lookups, one being identity table.
Len::One => Some(1),
Len::Two => Some(2),
Len::Three => Some(3),
}
}
// Manual optimal code.
#[no_mangle]
pub fn convert_len_optimal(len: &Len) -> Option<usize> {
match *len {
Len::Zero => None,
len => Some(unsafe { std::mem::transmute::<Len, u8>(len) } as usize),
}
}
It gives (Compiler explorer):
convert_len:
movzx eax, byte ptr [rdi]
shl eax, 3
lea rcx, [rip + .Lswitch.table.convert_len]
mov rdx, qword ptr [rax + rcx]
lea rcx, [rip + .Lswitch.table.convert_len.1]
mov rax, qword ptr [rax + rcx]
ret
convert_len_optimal:
movzx edx, byte ptr [rdi]
xor eax, eax
test rdx, rdx
setne al
ret
.Lswitch.table.convert_len:
.zero 8
.quad 1
.quad 2
.quad 3
.Lswitch.table.convert_len.1:
.quad 0
.quad 1
.quad 1
.quad 1
I expect convert_len
to generate code like convert_len_optimal
. No table lookup should be generated, especially not the first identity table. Though I don't expect performance to differ a lot when the cache is hot, but wasting cache on these trivial tables does not worth it.
I'm not sure if LLVM or rustc is to blame here.
Meta
Reproduced on compiler Explorer's 1.84, latest nightly, and local nightly (rustc 1.86.0-nightly (854f22563 2025-01-31)
)
Metadata
Metadata
Assignees
Labels
A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchCategory: An issue highlighting optimization opportunities or PRs implementing suchI-slowIssue: Problems and improvements with respect to performance of generated code.Issue: Problems and improvements with respect to performance of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.