-
Notifications
You must be signed in to change notification settings - Fork 14k
Closed
Labels
A-target-featureArea: Enabling/disabling target features like AVX, Neon, etc.Area: Enabling/disabling target features like AVX, Neon, etc.C-bugCategory: This is a bug.Category: This is a bug.O-AArch64Armv8-A or later processors in AArch64 modeArmv8-A or later processors in AArch64 modeT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
Compiled with RUSTFLAGS=-Ctarget_feature=-neon (for aarch64-unknown-linux-gnu):
#![feature(simd_ffi)]
use std::arch::aarch64::*;
fn main() {
// The target_feature unsafety contract requires us to test this first.
if std::arch::is_aarch64_feature_detected!("neon") {
unsafe { test(); }
}
}
#[target_feature(enable = "neon")]
unsafe fn test() {
const A: [u32; 4] = [40, 30, 16, 9];
const B: [u32; 4] = [2, 12, 26, 33];
let a: uint32x4_t = vld1q_u32(A.as_ptr());
let b: uint32x4_t = vld1q_u32(B.as_ptr());
let r = trampoline(a, b);
println!("{a:?} + {b:?} -> {r:?}");
}
fn trampoline(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
unsafe { add(a, b) }
}
extern "C" {
// The C implementation is a simple pass-through to `vaddq_u32(a, b)`.
fn add(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t;
}Ideally, trampoline would fail to compile, because it does not have Neon and shouldn't be able to represent the vector types.
- The call to
trampoline(a, b)passes the arguments in memory (using the Rust ABI). - The subsequent call to
add(a, b)tries to pass each argument in fourwregisters (each holding au32), as if they are tuples(u32, u32, u32, u32). - The C implementation expects arguments in Neon registers (
v0andv1), so the result is unpredictable.
If test() — which has "neon" enabled — calls add(a, b) directly, it uses v0 and v1, as per AAPCS64.
This is the AArch64 counterpart to #116344 and #114479, with the twist that on AArch64, it's preferable for Neon-specific types to fail to compile without the proper features. These aren't general-purpose types. At least some C compilers refuse to compile code that uses Neon types when -mcpu=+nosimd+nofp is specified.
Meta
This came out of a Zulip discussion.
rustc --version --verbose:
rustc 1.76.0-nightly (a1a37735c 2023-11-23)
binary: rustc
commit-hash: a1a37735cbc3db359d0b24ba9085c9fcbe1bc274
commit-date: 2023-11-23
host: x86_64-unknown-linux-gnu
release: 1.76.0-nightly
LLVM version: 17.0.5
Metadata
Metadata
Assignees
Labels
A-target-featureArea: Enabling/disabling target features like AVX, Neon, etc.Area: Enabling/disabling target features like AVX, Neon, etc.C-bugCategory: This is a bug.Category: This is a bug.O-AArch64Armv8-A or later processors in AArch64 modeArmv8-A or later processors in AArch64 modeT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.