Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instructions missing from naked_asm blocks. #139407

Open
ZiCog opened this issue Apr 5, 2025 · 13 comments · May be fixed by #139453
Open

Instructions missing from naked_asm blocks. #139407

ZiCog opened this issue Apr 5, 2025 · 13 comments · May be fixed by #139453
Assignees
Labels
A-incr-comp Area: Incremental compilation C-bug Category: This is a bug. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness P-high High priority regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@ZiCog
Copy link

ZiCog commented Apr 5, 2025

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
@ZiCog ZiCog added the C-bug Category: This is a bug. label Apr 5, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Apr 5, 2025
@bjorn3
Copy link
Member

bjorn3 commented Apr 5, 2025

cc @folkertdev

@bjorn3 bjorn3 added A-naked Area: `#[naked]`, prologue and epilogue-free, functions, https://git.io/vAzzS F-naked_functions `#![feature(naked_functions)]` labels Apr 5, 2025
@compiler-errors
Copy link
Member

@ZiCog: The code that you shared is identical. I assume you meant to write unsafe { naked_asm!("add x0, x0, w1", "ret") } in the first code snippet.

@compiler-errors
Copy link
Member

I also can't seem to reproduce the bug on either aarch64-apple-darwin or aarch64-unknown-linux-gnu, either on nightly for 2025-03-12 or today's nightly.

@ZiCog
Copy link
Author

ZiCog commented Apr 5, 2025

Sorry, you are right, that should be unsafe { naked_asm!("add x0, x0, w1", "ret") } in the first snippet. I have changed it in the report. I was being so careful...

I just did a rustup update on my MacBook Pro M1 and it won't install anything newer than 2025-03-12 for the lack of rls. Anything I can do about that?

OS = Sequoia 15.3.1

Problem is still here for me.

@compiler-errors
Copy link
Member

@ZiCog: I'm trying to understand anything about what could be different between my attempt to reproduce the bug here and your setup.

Is there anything special about your Cargo.toml?

Is there anything special about your setup? Does it reproduce on a fresh cargo init'ed project with all changes and commands made through the command line (i.e. no IDE running)?

Could you share any other information here?

@ZiCog
Copy link
Author

ZiCog commented Apr 5, 2025

I was using the Zed editor and Warp terminal. I have now repeated the experiment with vim and the regular Mac terminal.

It turns out that starting with a new project cargo init rust_bug and following the steps in my report the problem does not occur.

BUT. Then editing that x1 to w1 again to produce the build error and then changing it back to x1 does indeed show the problem. It builds but produces the wrong result.

In short. On a fresh project there is no problem. On a "stale" project there is.

My Cargo.toml remains as generated:

[package]
name = "rust_bug"
version = "0.1.0"
edition = "2024"

[dependencies]

@compiler-errors
Copy link
Member

Ah, thanks @ZiCog. Repeating x1 -> w1 -> x1 was necessary. I got it to print "3" :)

@ZiCog
Copy link
Author

ZiCog commented Apr 5, 2025

I just tried this on an Nvidia Jetson Nano with 2025-04-04 and the problem did not show:

$ cat /etc/issue
Ubuntu 18.04.6 LTS \n \l

$ uname -a
Linux konalantie-nx 4.9.201-tegra #1 SMP PREEMPT Fri Jul 9 08:56:59 PDT 2021 aarch64 aarch64 aarch64 GNU/Linux

$ rustc --version --verbose
rustc 1.88.0-nightly (17ffbc8 2025-04-04)
binary: rustc
commit-hash: 17ffbc8
commit-date: 2025-04-04
host: aarch64-unknown-linux-gnu
release: 1.88.0-nightly
LLVM version: 20.1.2

@ZiCog
Copy link
Author

ZiCog commented Apr 5, 2025

Is there any way I can get a more recent nightly installed on my Mac Book Pro M1 ?

@zachs18
Copy link
Contributor

zachs18 commented Apr 6, 2025

@ZiCog

Is there any way I can get a more recent nightly installed on my Mac Book Pro M1 ?

You need to remove the rls component (it has been removed and hadn't done anything for a while anyway) so that rustup will update to newer nightlys that no longer have it.

rustup +nightly component remove rls is the magic word IIRC, and then rustup update nightly

@compiler-errors
Copy link
Member

I don't believe this has anything to do with naked_asm, nor does this have anything to do with MacOS really.

My rough explanation for why this occurs is:

Session 1 begins

  • Typeck function
  • We write dep graph for function
  • Spit out object file for function's CGU
  • Finalize session directory

Session 2 begins

  • Copy over previous finalized incremental directory WITH HARD LINKS
  • Typeck function (since it's dirty)
  • Write dep graph for function
  • Try to rebuild CGU, which fails but dirties THE HARD LINK of function's CGU
  • We do NOT finalize session directory

Session 3 begins

  • Look up the previous FINALIZED incremental directory
  • All the nodes are green of course
  • CGU reuse kicks in, but we load the DIRTIED linker artifacts
  • lmao

I can actually reproduce this on linux with -Csave-temps and a similar setup 🤔

@compiler-errors compiler-errors self-assigned this Apr 6, 2025
@ZiCog
Copy link
Author

ZiCog commented Apr 6, 2025

OK. I now have the most recent nightly installed and it also shows the problem on my Mac M1

rustc 1.88.0-nightly (5e17a2a91 2025-04-05)
binary: rustc
commit-hash: 5e17a2a91dd7dbefd8b4a1087c2e42257457deeb
commit-date: 2025-04-05
host: aarch64-apple-darwin
release: 1.88.0-nightly
LLVM version: 20.1.2

How did you get the problem to manifest on Linux ?

@Noratrieb Noratrieb added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-incr-comp Area: Incremental compilation I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness and removed F-naked_functions `#![feature(naked_functions)]` needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Apr 6, 2025
@rustbot rustbot added the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Apr 6, 2025
@compiler-errors compiler-errors removed the A-naked Area: `#[naked]`, prologue and epilogue-free, functions, https://git.io/vAzzS label Apr 6, 2025
@apiraino
Copy link
Contributor

apiraino commented Apr 7, 2025

Assigning priority (discussion on Zulip)

@rustbot label -I-prioritize +P-high +regression-from-stable-to-nightly

@rustbot rustbot added P-high High priority regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Apr 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-incr-comp Area: Incremental compilation C-bug Category: This is a bug. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness P-high High priority regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
7 participants