-
-
Notifications
You must be signed in to change notification settings - Fork 14.7k
Pattern matching on enum creates unecessary jump table #115742
Copy link
Copy link
Closed
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-bugCategory: This is a bug.Category: This is a bug.I-slowIssue: Problems and improvements with respect to performance of generated code.Issue: Problems and improvements with respect to performance of generated code.llvm-fixed-upstreamIssue expected to be fixed by the next major LLVM upgrade, or backported fixesIssue expected to be fixed by the next major LLVM upgrade, or backported fixes
Description
I tried this code:
Say we define an AST type for expressions, each carrying a span to give its position in the original source code:
pub type ByteSpan = (u32, u32);
pub enum Expr<'core> {
Error(ByteSpan),
Int(ByteSpan, u64),
Array(ByteSpan, &'core [Self]),
Call(ByteSpan, &'core Self, &'core [Self]),
}
pub fn span(expr: &Expr) -> ByteSpan {
match expr {
Expr::Error(span, ..)
| Expr::Int(span, ..)
| Expr::Array(span, ..)
| Expr::Call(span, ..) => *span,
}
}I expected to see this happen:
The ByteSpan is placed at the same offset for every variant of the enum, so the final assembly for span should be:
example::span:
mov eax, dword ptr [rdi + 4]
mov edx, dword ptr [rdi + 8]
ret
Instead, this happened:
A jump table is generated, even though every entry in the jump table is identical (godbolt):
example::span:
mov eax, dword ptr [rdi]
lea rcx, [rip + .LJTI0_0]
movsxd rax, dword ptr [rcx + 4*rax]
add rax, rcx
jmp rax
.LBB0_1:
lea rcx, [rdi + 4]
mov eax, dword ptr [rdi + 4]
mov edx, dword ptr [rcx + 4]
ret
.LJTI0_0:
.long .LBB0_1-.LJTI0_0
.long .LBB0_1-.LJTI0_0
.long .LBB0_1-.LJTI0_0
.long .LBB0_1-.LJTI0_0
If the last 2 variants are removed, the optimal code is produced. If only the last variant is removed, the code is better, but still suboptimal:
example::span:
mov eax, dword ptr [rdi]
test rax, rax
je .LBB0_2
cmp eax, 1
.LBB0_2:
lea rcx, [rdi + 4]
mov eax, dword ptr [rdi + 4]
mov edx, dword ptr [rcx + 4]
ret
Meta
rustc --version --verbose:
rustc 1.74.0-nightly (1e746d774 2023-09-07)
binary: rustc
commit-hash: 1e746d7741d44551e9378daf13b8797322aa0b74
commit-date: 2023-09-07
host: x86_64-unknown-linux-gnu
release: 1.74.0-nightly
LLVM version: 17.0.0
Compiler returned: 0
Reactions are currently unavailable
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-bugCategory: This is a bug.Category: This is a bug.I-slowIssue: Problems and improvements with respect to performance of generated code.Issue: Problems and improvements with respect to performance of generated code.llvm-fixed-upstreamIssue expected to be fixed by the next major LLVM upgrade, or backported fixesIssue expected to be fixed by the next major LLVM upgrade, or backported fixes
Type
Fields
Give feedbackNo fields configured for issues without a type.