Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missed optimization: converting "equivalent" enums #116272

Open
ojeda opened this issue Sep 29, 2023 · 1 comment
Open

Missed optimization: converting "equivalent" enums #116272

ojeda opened this issue Sep 29, 2023 · 1 comment
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. I-slow Issue: Problems and improvements with respect to performance of generated code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@ojeda
Copy link
Contributor

ojeda commented Sep 29, 2023

With Rust 1.72.0:

#[repr(u32)]
pub enum E1 {
    A = 0,
    B = 1,
    C = 255,
}

pub enum E2 {
    A = 0,
    B = 1,
    C = 255,
}

pub fn f(e: E1) -> E2 {
    match e {
        E1::A => E2::A,
        E1::B => E2::B,
        E1::C => E2::C,
    }
}

pub fn g(e: E2) -> E1 {
    match e {
        E2::A => E1::A,
        E2::B => E1::B,
        E2::C => E1::C,
    }
}

compiles to branches (f) and a table-based approach (g):

example::f:
        test    edi, edi
        je      .LBB0_1
        cmp     edi, 1
        jne     .LBB0_4
        mov     al, 1
        ret
.LBB0_1:
        xor     eax, eax
        ret
.LBB0_4:
        mov     al, -1
        ret

example::g:
        inc     dil
        movsx   rax, dil
        lea     rcx, [rip + .Lswitch.table.example::g]
        mov     eax, dword ptr [rcx + 4*rax]
        ret

.Lswitch.table.example::g:
        .long   255
        .long   0
        .long   1

However, they could simply be:

example::f:
        mov     eax, edi
        ret

example::g:
        movzx   eax, dil
        ret

https://godbolt.org/z/Ko5cKKojh

The compiler figures it out correctly if the values are contiguous (e.g. changing 255 above to 2), or if the sizes / repr is the same.

This sort of code may happen when one is safely wrapping an automatically generated Rust enum from (e.g. from C code) into a better enum (e.g. with a smaller layout, better docs or more idiomatic variant names).

@Rageking8
Copy link
Contributor

@rustbot label +A-LLVM +T-compiler +I-slow

@rustbot rustbot added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. I-slow Issue: Problems and improvements with respect to performance of generated code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 29, 2023
@saethlin saethlin removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Sep 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. I-slow Issue: Problems and improvements with respect to performance of generated code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants