Skip to content

inline ASM requires target features on some targets #112709

@tarcieri

Description

@tarcieri

I have code that, for whatever reason, will compile on aarch64-apple-darwin but not on aarch64-unknown-linux-gnu. It's asking me to enable target_features on a function that's annotated inline(always) (which, in and of itself, does not seem to make sense).

A minimal reproduction is also elusive in that everything I've tried so far compiles. I'm wondering if this is some kind of bug related to the inliner.

To start with, here are the functions it's complaining about:

/// AES single round encryption.
#[inline(always)]
pub unsafe fn vaeseq_u8(mut data: uint8x16_t, key: uint8x16_t) -> uint8x16_t {
    asm!(
        "AESE {d:v}.16B, {k:v}.16B",
        d = inout(vreg) data,
        k = in(vreg) key,
        options(pure, nomem, nostack, preserves_flags)
    );
    data
}

/// AES inverse mix columns.
#[inline(always)]
pub unsafe fn vaesimcq_u8(mut data: uint8x16_t) -> uint8x16_t {
    asm!(
        "AESIMC {d:v}.16B, {d:v}.16B",
        d = inout(vreg) data,
        options(pure, nomem, nostack, preserves_flags)
    );
    data
}

These compile fine in and of themselves. In fact trying to put together a minimal repro I haven't been able to reproduce the compile error, even with quite a bit of the related code in place: https://godbolt.org/z/P7h8KsaMG

So it seems like some strange interactions in more complicated code, possibly related to inlining.

It's easily reproducible, but unfortunately the only repro I have to offer is the following commit of this PR: RustCrypto/block-ciphers@7818f35

The compile error is as follows (which I've reproduced locally): https://github.com/RustCrypto/block-ciphers/actions/runs/5283017067/jobs/9558698657

error: instruction requires: aes
  --> aes/src/armv8/intrinsics.rs:11:10
   |
11 |         "AESE {d:v}.16B, {k:v}.16B",
   |          ^
   |
note: instantiated into assembly here
  --> <inline asm>:1:2
   |
1  |     AESE v1.16B, v0.16B
   |     ^

error: instruction requires: aes
  --> aes/src/armv8/intrinsics.rs:47:10
   |
47 |         "AESIMC {d:v}.16B, {d:v}.16B",
   |          ^
   |
note: instantiated into assembly here
  --> <inline asm>:1:2
   |
1  |     AESIMC v0.16B, v0.16B
   |     ^

One more odd observation, the compile error can be "solved" by replacing #[inline(always)] with #[target_feature(enable = "aes")], as in here: RustCrypto/block-ciphers@10debe5

However, this solution seemed to cause massive performance degradation with spooky-action-at-a-distance impacts on seemingly unrelated code (although code that was using the same CPU instruction): RustCrypto/block-ciphers#365 (comment)

Meta

This reproduces on all versions of rustc I've tried, including the latest nighty. The code in question is targeting an MSRV of 1.61, where the error also occurs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    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