Skip to content

global_asm! errors are inconsistent with target features #113221

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

Open
eigenform opened this issue Jul 1, 2023 · 3 comments
Open

global_asm! errors are inconsistent with target features #113221

eigenform opened this issue Jul 1, 2023 · 3 comments
Labels
A-inline-assembly Area: Inline assembly (`asm!(…)`) A-target-feature Area: Enabling/disabling target features like AVX, Neon, etc. C-bug Category: This is a bug.

Comments

@eigenform
Copy link

eigenform commented Jul 1, 2023

$ rustc --version --verbose
rustc 1.71.0-nightly (2f2c438dc 2023-05-08)
binary: rustc
commit-hash: 2f2c438dce75d8cc532c3baa849eeddc0901802c
commit-date: 2023-05-08
host: x86_64-unknown-linux-gnu
release: 1.71.0-nightly
LLVM version: 16.0.2

global_asm! prints errors about missing target features even when they are enabled. I think this is the same behavior as
#50477.

In this case, rustc emits errors but doesn't abort and produces the correct, expected output file.

/// foo.rs
core::arch::global_asm!("
.section .text
.global my_func
my_func:
    sb
    ret
");

#[no_mangle]
#[inline(never)]
fn main() {
    //unsafe { core::arch::asm!("sb"); }
}
$ rustc foo.rs --target aarch64-unknown-linux-gnu --crate-type lib -C target-feature=+sb
error: instruction requires: sb
    sb
    ^
error: instruction requires: sb
    sb
    ^
$ aarch64-linux-gnu-objdump -C -d libfoo.rlib 
In archive libfoo.rlib:

lib.rmeta:     file format elf64-littleaarch64


foo.foo.bbcbb88c88589229-cgu.0.rcgu.o:     file format elf64-littleaarch64


Disassembly of section .text:

0000000000000000 <my_func>:
   0:	d50330ff 	sb
   4:	d65f03c0 	ret

Disassembly of section .text.main:

0000000000000000 <main>:
   0:	d65f03c0 	ret

For comparison, here's the same situation with asm! instead:

  • When the feature isn't enabled, rustc prints errors about the missing feature and aborts (generating no output file)
  • When the feature is enabled, there are no errors and rustc produces the correct, expected output file
/// foo.rs
//core::arch::global_asm!("
//.section .text
//.global my_func
//my_func:
//    sb
//    ret
//");

#[no_mangle]
#[inline(never)]
fn main() {
    unsafe { core::arch::asm!("sb"); }
}
$ rustc foo.rs --target aarch64-unknown-linux-gnu --crate-type lib 
error: instruction requires: sb
  --> foo.rs:34:27
   |
34 |         core::arch::asm!("sb");
   |                           ^
   |
note: instantiated into assembly here
  --> <inline asm>:1:2
   |
1  |     sb
   |     ^

error: aborting due to previous error

$ rustc foo.rs --target aarch64-unknown-linux-gnu --crate-type lib -C target-feature=+sb
$ aarch64-linux-gnu-objdump -C -d libfoo.rlib 
In archive libfoo.rlib:

lib.rmeta:     file format elf64-littleaarch64


foo.foo.bbcbb88c88589229-cgu.0.rcgu.o:     file format elf64-littleaarch64


Disassembly of section .text.main:

0000000000000000 <main>:
   0:	d50330ff 	sb
   4:	d65f03c0 	ret
@Jules-Bertholet
Copy link
Contributor

@rustbot label C-bug A-inline-assembly

@rustbot rustbot added A-inline-assembly Area: Inline assembly (`asm!(…)`) C-bug Category: This is a bug. labels Jul 1, 2023
@workingjubilee workingjubilee added the A-target-feature Area: Enabling/disabling target features like AVX, Neon, etc. label Jul 17, 2023
@folkertdev
Copy link
Contributor

This is not a solution in general, but in this specific case, you can use .arch_extension sb to enable the sb target feature in the global asm:

https://godbolt.org/z/GPdcM4x8f

core::arch::global_asm!("
.arch_extension sb
.section .text
.global my_func
my_func:
    sb
    ret
.arch_extension nosb
");

By the way, C runs into the same problem, so the issue appears to be that LLVM does not really have a good way of attaching target features to global assembly (or at least, it doesn't do it).

The .arch_extension directive is arm specific, so this "fix" only works on arm.

@eigenform
Copy link
Author

eigenform commented Jan 16, 2025

Explicitly including -C embed-bitcode=no appears to make this error disappear, but disabling LTO with -C lto=off doesn't work here.

It seems like this has been around for a while, LLVM just doesn't propagate features to assembly correctly, see:

Presumably something like llvm/llvm-project#97685 will fix this whole class of issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-inline-assembly Area: Inline assembly (`asm!(…)`) A-target-feature Area: Enabling/disabling target features like AVX, Neon, etc. C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

5 participants