Skip to content

Inefficient implementation of PartialEq for nested (fieldless) enums #132628

Open
@zaneduffield

Description

@zaneduffield

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

A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-codegenArea: Code generationA-enumArea: Enums (discriminated unions, or more generally ADTs (algebraic data types))C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchE-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.I-heavyIssue: Problems and improvements with respect to binary size of generated code.I-slowIssue: 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.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions