rust-lang / rust-lang/rust

Inline `asm!` is unnecessarily duplicated

Open
#149,832 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-inline-assembly C-bug needs-triage
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

The following example code:

unsafe extern "system" {
    safe fn finish_ffi_stuff(handle: isize) -> bool;
    safe fn do_ffi_stuff(path: *const u8) -> isize;
    safe fn get_ffi_result() -> u32;
}

//#[inline(never)]
fn get_result() -> u32 {
    let code: u32;
    #[cfg(target_arch = "x86_64")]
    unsafe {
        core::arch::asm!(
            "call {}", // yes, I know. this is just an example.
            sym get_ffi_result,
            out("eax") code,
            options(nostack, preserves_flags, pure, readonly)
        );
    }
    code
}

fn finish_stuff(handle: isize) -> Result<(), u32> {
    match finish_ffi_stuff(handle) {
        false => Err(get_result()),
        true => Ok(())
    }
}

fn do_stuff(path: &str) -> Result<isize, u32> {
    let handle = do_ffi_stuff(path.as_ptr());
    match handle {
        -1 => Err(get_result()),
        _ => Ok(handle)
    }
}

pub fn my_main() -> u32 {
    match do_stuff("meow") {
        Ok(meow) => finish_stuff(meow).err().unwrap_or(0),
        Err(e) => e
    }
}

Produces the following x86_64 assembly:

example[46d8dd5c5912c656]::my_main:
        push    rax
        lea     rdi, [rip + .Lanon.014ce376276f773fc8cbe61d4d1296c1.0]
        call    qword ptr [rip + do_ffi_stuff@GOTPCREL]
        cmp     rax, -1
        je      .LBB0_3
        mov     rdi, rax
        call    qword ptr [rip + finish_ffi_stuff@GOTPCREL]
        test    al, al
        je      .LBB0_4
        xor     eax, eax
        pop     rcx
        ret
.LBB0_3:

        call    get_ffi_result

        pop     rcx
        ret
.LBB0_4:

        call    get_ffi_result

        pop     rcx
        ret

.Lanon.014ce376276f773fc8cbe61d4d1296c1.0:
        .ascii  "meow"

Note that .LBB0_3 and .LBB0_4 are exact duplicates. While the compiler can't see inside asm blocks, I'd assume it at least knows that they are the same in this case.

Meta

rustc --version --verbose:

rustc 1.94.0-nightly (ba86c0460 2025-12-06)
binary: rustc
commit-hash: ba86c0460b0233319e01fd789a42a7276eade805
commit-date: 2025-12-06
host: x86_64-unknown-linux-gnu
release: 1.94.0-nightly
LLVM version: 21.1.5

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the supplied x86_64 example with the noted nightly rustc version and compare its generated assembly. Investigate the compiler and LLVM handling of the repeated asm! paths, using the shown duplicate blocks as the baseline; done means equivalent output no longer contains the unnecessary duplicated blocks.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.