Skip to content

Poorly optimized assembly generation around Ipv4Addr, Ipv6Addr #77583

Closed

Description

I tried this code:

pub fn ipv4_bitand_mask(ipv4: Ipv4Addr, mask: u32) -> Ipv4Addr {
    let ipv4_u32 = u32::from_ne_bytes(ipv4.octets());
    Ipv4Addr::from((ipv4_u32 & mask).to_ne_bytes())
}

I expected to see this happen: assembly generated should be equivalent to:

pub fn ipv4_bitand_mask_unsafe(ipv4: Ipv4Addr, mask: u32) -> Ipv4Addr {
    let ipv4_u32: u32 = unsafe { std::mem::transmute(ipv4) };
    unsafe { std::mem::transmute(ipv4_u32 & mask) }
}

Instead, this happened: the generated assembly retains calls to Ipv4::octets and Ipv4::from, leaving the assembly poorly optimized

I've played with different ways of implementing the safe version, but cannot find anyway get it to optimize further.

Good assembly:

example::ipv4_bitand_mask_unsafe:
        mov     eax, edi
        and     eax, esi
        ret

Bad assembly:

example::ipv4_bitand_mask:
        push    rbx
        sub     rsp, 16
        mov     ebx, esi
        mov     dword ptr [rsp + 8], edi
        lea     rdi, [rsp + 8]
        call    qword ptr [rip + std::net::ip::Ipv4Addr::octets@GOTPCREL]
        and     eax, ebx
        mov     edi, eax
        call    qword ptr [rip + <std::net::ip::Ipv4Addr as core::convert::From<[u8; 4]>>::from@GOTPCREL]
        add     rsp, 16
        pop     rbx
        ret

Playground and GodBolt (both include an IPv6 example as well)

Adding '-Z mir-opt-level=2' (or higher) does optimize away the call to octets, but not the call to from.

I get the same optimization behavior when building a binary, at least on my own platfom (x86-64 Windows MSVC)

Meta

rustc --version --verbose:

rustc 1.49.0-nightly (beb5ae474 2020-10-04)
binary: rustc
commit-hash: beb5ae474d2835962ebdf7416bd1c9ad864fe101
commit-date: 2020-10-04
host: x86_64-pc-windows-msvc
release: 1.49.0-nightly
LLVM version: 11.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.I-slowIssue: Problems and improvements with respect to performance of generated code.T-libsRelevant to the library 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