-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Neon types generate bad code if the "neon" target feature is disabled. #118249
Comments
IMO the declaration of Having a type disappear based on a target feature does not make a ton of sense from a Rust perspective. |
It's the counterpart to the second. The first issue is about the ABI of |
Ok, so perhaps the real problem here is that we can't add
Is there more material I can read to get a better understanding of the reasoning behind that? From our perspective, trying to expose specific hardware features to low-level Rust code, it makes a lot of sense: Notably, having feature-specific types would go some way towards allowing traits implementations to have implied target features. For example, we can't implement |
Agreed, such attributes at declarations are needed. The original design didn't think they were needed since there is no codegen for declarations and target features seemingly only affect codegen, but alas, the situations is more messy than that.
Availability of Rust standard library types is determined by And even for C, how do you handle per-function enabling of target features? I could build a file without neon support but then declare one function in there to support neon. How do you make the type only available to that one function? That would require special compiler magic, the preprocessor does not suffice. |
It appears that the types are actually available to the language, but if you try to use them with the hardware features disabled, you get a compiler error. That probably qualifies as special compiler magic! With Neon and FP on AArch64 specifically, there are many caveats and corner-cases because most tools (reasonably) assume they're present. I experimented a bit with SVE, since it's genuinely optional. The following compiles fine without "+sve", using both Clang (build from source #include <arm_sve.h>
__attribute__((target("arch=armv8-a+sve")))
svuint32_t add_sve(svuint32_t a, svuint32_t b) {
return svadd_x(svptrue_b32(), a, b);
} In both cases, arguments are passed in SVE-specific I'd be happy if we could do that in Rust too, rather than falling back onto a different ABI. If someone is using these types, they're saying "I'm using SVE" (or Neon), so anything else is a surprising behaviour, I think. There's another significant difference in C: it usually compiles and then links several compilation units, and it is easy to compile one or more modules with "+sve", and perhaps call it only after run-time feature checks. To do a similar thing in Rust, I think you'd have to put all the hardware-specific bits into a separate crate with |
I had in mind something like this: #[target_feature(require = "sve")]
#[repr(...)]
pub struct svuint32_t { ... } ... then the compiler can check, when the type is used, that the context provides the required target features. We can fix it for |
Compiled with
RUSTFLAGS=-Ctarget_feature=-neon
(foraarch64-unknown-linux-gnu
):Ideally,
trampoline
would fail to compile, because it does not have Neon and shouldn't be able to represent the vector types.trampoline(a, b)
passes the arguments in memory (using the Rust ABI).add(a, b)
tries to pass each argument in fourw
registers (each holding au32
), as if they are tuples(u32, u32, u32, u32)
.v0
andv1
), so the result is unpredictable.If
test()
— which has "neon" enabled — callsadd(a, b)
directly, it usesv0
andv1
, 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
:The text was updated successfully, but these errors were encountered: