Open
Description
I'm not sure if this is the right place for this (might be LLVM to blame), just a bit of inefficient code that I noticed.
https://godbolt.org/z/K57orYj5h
The only difference between the two functions eq
and matches
is the use of ==
and matches!
for the enum comparison. The generated code for eq
includes two calls to PartialEq
for Outer
, whereas the code for matches
has a much simpler (inline) comparison.
Also, the generated code for PartialEq
seems very inefficient, given the enum is just a two-byte value that can be directly compared.
If you tinker with the enum definitions it's not hard to cause eq
to optimise exactly like matches
.
Example copied here
#[derive(PartialEq)]
pub enum InnerInner {
One,
Two,
}
#[derive(PartialEq)]
pub enum Inner {
One,
Two,
Const(InnerInner),
}
#[derive(PartialEq)]
pub enum Outer {
One(Inner),
Two,
Three,
Four,
Five(Inner),
Six(Inner),
Seven(Inner),
Eight(Inner),
}
#[no_mangle]
pub fn eq(t: Outer, b: &mut bool) {
let token_type = if t == Outer::One(Inner::One) {
Outer::One(Inner::One)
} else {
Outer::Two
};
*b = token_type == Outer::Two;
}
#[no_mangle]
pub fn matches(t: Outer, b: &mut bool) {
let token_type = if matches!(t, Outer::One(Inner::One)) {
Outer::One(Inner::One)
} else {
Outer::Two
};
*b = matches!(token_type, Outer::Two);
}
Metadata
Metadata
Assignees
Labels
Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Code generationArea: Enums (discriminated unions, or more generally ADTs (algebraic data types))Category: An issue highlighting optimization opportunities or PRs implementing suchCall for participation: An issue has been fixed and does not reproduce, but no test has been added.Issue: Problems and improvements with respect to binary size of generated code.Issue: Problems and improvements with respect to performance of generated code.Relevant to the compiler team, which will review and decide on the PR/issue.