Skip to content

Return branches not correctly merged in size-optimized x86-64 assembly #127376

Open
@dead-claudia

Description

@dead-claudia

Godbolt link (includes this and another buggy example)

I tried this code:

pub fn parse_u32_digit(acc: u32, byte: u8) -> Option<u32> {
    let max = if acc == 429496729 { 5 } else { 9 };
    if acc <= 429496729 {
        let v = (byte as u32).wrapping_sub(b'0' as u32);
        if v <= max {
            return Some(acc.wrapping_mul(10).wrapping_add(v));
        }
    }
    None
}

I expected to see this happen: assembly that looks something like this:

parse_u32_digit:
        xor     eax, eax
        cmp     edi, 429496729
        ja      .LBB1_1
        setne   cl
        movzx   ecx, cl
        lea     r8d, [4*rcx + 5]
        movzx   ecx, sil
        add     ecx, -48
        cmp     ecx, r8d
        ja      .LBB1_4
        lea     eax, [rdi + 4*rdi]
        lea     edx, [rcx + 2*rax]
        mov     eax, 1
.LBB1_1:
.LBB1_4:
        ret

Instead, this happened: the following assembly:

parse_u32_digit:
        xor     eax, eax
        cmp     edi, 429496729
        ja      .LBB1_1
        setne   cl
        movzx   ecx, cl
        lea     r8d, [4*rcx + 5]
        movzx   ecx, sil
        add     ecx, -48
        cmp     ecx, r8d
        ja      .LBB1_4
        lea     eax, [rdi + 4*rdi]
        lea     edx, [rcx + 2*rax]
        mov     eax, 1
.LBB1_4:
        ret
.LBB1_1:
        ret

Meta

rustc --version --verbose:

rustc 1.79.0 (129f3b996 2024-06-10)
binary: rustc
commit-hash: 129f3b9964af4d4a709d1383930ade12dfe7c081
commit-date: 2024-06-10
host: x86_64-unknown-linux-gnu
release: 1.79.0
LLVM version: 18.1.7
Compiler returned: 0

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-codegenArea: Code generationC-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-heavyIssue: Problems and improvements with respect to binary size 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