Skip to content

Compiler fails to remove jumps using jump table if every label in it is same #110797

Closed
@AngelicosPhosphoros

Description

I tried this code:

pub enum K{
    A(Box<[i32]>),
    B(Box<[u8]>),
    C(Box<[String]>),
    D(Box<[u16]>),
}

pub fn get_len(arg: &K)->usize{
    match arg {
        K::A(ref lst)=>lst.len(),
        K::B(ref lst)=>lst.len(),
        K::C(ref lst)=>lst.len(),
        K::D(ref lst)=>lst.len(),
    }
}

I expected to see this happen:

Since layout of each enum variant is same, I expected to get machine code without any jumps, e.g.

example::get_len:
        mov     rax, qword ptr [rdi + 16]
        ret

Instead, this happened:
Compiler generates jump table, every branch of it points to the same code, and code jumps using it despite being it redundant.

example::get_len:
        mov     rax, qword ptr [rdi]
        lea     rcx, [rip + .LJTI0_0]
        movsxd  rax, dword ptr [rcx + 4*rax]
        add     rax, rcx
        jmp     rax
.LBB0_1:
        mov     rax, qword ptr [rdi + 16]
        ret
.LJTI0_0:                                     ; Note that each of it jumps to same label at the end.
        .long   .LBB0_1-.LJTI0_0
        .long   .LBB0_1-.LJTI0_0
        .long   .LBB0_1-.LJTI0_0
        .long   .LBB0_1-.LJTI0_0

Meta

rustc --version --verbose:

rustc 1.68.0 (2c8cc3432 2023-03-06)
binary: rustc
commit-hash: 2c8cc343237b8f7d5a3c3703e3a87f2eb2c54a74
commit-date: 2023-03-06
host: x86_64-unknown-linux-gnu
release: 1.68.0
LLVM version: 15.0.6
Compiler returned: 0

Also, godbolt link.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.C-bugCategory: This is a bug.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.I-slowIssue: Problems and improvements with respect to performance of generated code.P-mediumMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions