Skip to content

global_asm! errors are inconsistent with target features #113221

Open

Description

@eigenform
$ 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

Activity

  1. Jules-Bertholet commented on Jul 1, 2023

    @Jules-Bertholet
    Contributor

    @rustbot label C-bug A-inline-assembly

  2. folkertdev commented on Jan 16, 2025

    @folkertdev
    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.

  3. eigenform commented on Jan 16, 2025

    @eigenform
    Author

    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-inline-assemblyArea: Inline assembly (`asm!(…)`)A-target-featureArea: Enabling/disabling target features like AVX, Neon, etc.C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions