Skip to content

Instructions missing from naked_asm blocks. #139407

Closed
@ZiCog

Description

@ZiCog

Instructions are getting omitted from naked_asm blocks after fixing a compilation error and then rebuilding with cargo run. A cargo clean and cargo run is then required to get a correct executable.

As a minimal demonstration of this problem this code contains a deliberate error and fails to build:

#![feature(naked_functions)]
#![no_main]

use core::arch::naked_asm;

#[unsafe(no_mangle)]
#[naked]
extern "C" fn add_u64(x: u64, y: u64) -> u64 {
    unsafe { naked_asm!("add x0, x0, w1", "ret") }
}

#[unsafe(no_mangle)]
pub extern "C" fn main(_argc: isize, _argv: *const *const u8) -> isize {
    println!("{}", add_u64(3u64, 7u64));
    0
}
cargo run
   Compiling rust_asm v0.1.0 (/Users/me/rust_asm)
error: too few operands for instruction
  |
note: instantiated into assembly here
 --> <inline asm>:5:1
  |
5 | add x0, x0, w1
  | ^^^^^^^^^^^^^^

We fix the source by changing w1 into x1. Which now builds without error but produces the wrong result:

#![feature(naked_functions)]
#![no_main]

use core::arch::naked_asm;

#[unsafe(no_mangle)]
#[naked]
extern "C" fn add_u64(x: u64, y: u64) -> u64 {
    unsafe { naked_asm!("add x0, x0, x1", "ret") }
}

#[unsafe(no_mangle)]
pub extern "C" fn main(_argc: isize, _argv: *const *const u8) -> isize {
    println!("{}", add_u64(3u64, 7u64));
    0
}
cargo run
   Compiling rust_asm v0.1.0 (/Users/me/rust_asm)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.14s
     Running `target/debug/rust_asm`
3

Looking at the disassembled executable with objdump -d target/debug/rust_asm | less we find the add instruction is missing from the add_u64() function:

00000001000018d0 <_add_u64>:
1000018d0: d65f03c0     ret

Rebuilding with cargo clean and cargo run then produces the correct result:

cargo clean
     Removed 41 files, 1.0MiB total
cargo run
   Compiling rust_asm v0.1.0 (/Users/me/rust_asm)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.36s
     Running `target/debug/rust_asm`
10

And of course the add instruction is now in the executable where we expect it to be:

00000001000018cc <_add_u64>:
1000018cc: 8b010000     add     x0, x0, x1
1000018d0: d65f03c0     ret

Meta

rustc --version --verbose
rustc 1.87.0-nightly (249cb8431 2025-03-12)
binary: rustc
commit-hash: 249cb84316401daf040832cdbb8a45e0f5ab6af8
commit-date: 2025-03-12
host: aarch64-apple-darwin
release: 1.87.0-nightly
LLVM version: 20.1.0

Metadata

Metadata

Labels

A-incr-compArea: Incremental compilationC-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-nightlyPerformance or correctness regression from stable to nightly.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions