-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Many Arm microcontoller target feature flags are missing #130988
Comments
I find this example code useful in Godbolt for checking what the flags do and don't do: #![no_std]
#[no_mangle]
pub fn f32_add(x: [f32; 4], y: [f32; 4]) -> [f32; 4] {
[
(x[0] * 2.0) + y[0],
(x[1] * 2.0) + y[1],
(x[2] * 2.0) + y[2],
(x[3] * 2.0) + y[3],
]
}
#[no_mangle]
pub fn f64_add(x: [f64; 4], y: [f64; 4]) -> [f64; 4] {
[
(x[0] * 2.0) + y[0],
(x[1] * 2.0) + y[1],
(x[2] * 2.0) + y[2],
(x[3] * 2.0) + y[3],
]
}
#[no_mangle]
pub fn i32_add(x: [i32; 4], y: [i32; 4]) -> [i32; 4] {
[
(x[0] * 2) + y[0],
(x[1] * 2) + y[1],
(x[2] * 2) + y[2],
(x[3] * 2) + y[3],
]
} At opt-level=3 it will auto-vectorise on CPUs with MVE support. |
Cc @rust-lang/compiler None of these features are currently listed as known ARM features in rustc, so they all cause a warning. And yet our docs recommend people to use them. So that's clearly not great.
|
Nominating for T-compiler triage meeting next week. cc https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/stabilizing.20compiler.20flags.20for.20Rust-for-Linux. T-compiler probably wants to have a dedicated design meeting for target-features, target-cpu, target specs and how they are tracked in a dep graph. |
The avx512 mess would also fall in that general category (but is off-topic here). EDIT: and #131058, as well. |
I wrote up a blog looking into what some of these flags do - https://www.thejpster.org.uk/blog/blog-2024-09-29/. |
T-compiler visited this during the triage meeting, will probably need a design meeting (about the recent discussions around target-feature and ABI). @rustbot label -I-compiler-nominated |
I learned about do-while-loop-with-tail-predication and was so impressed I wrote up a second blog post: https://thejpster.org.uk/blog/blog-2024-10-03/ You really want compiler-builtin's memcpy and memset compiled with MVE, if you possibly can. |
This is not really a tracking issue since there's no unstable implementation being tracked here. Currently, these flags are just wholly unsupported by Rust, and we show a corresponding warning. So I updated the docs and labels accordingly. Adding support for @thejpster does any of the other flags affect ABI, i.e. can toggling it on or off change which registers are being used to pass function arguments? |
Not to my knowledge, but you should ask the Embedded Devices Cortex-M group too. |
How does one contact that group? |
Maybe https://github.com/rust-embedded/wg? |
I've asked via the Rust Embedded Matrix room. I don't think have a ping group for just that sub-group but they probably should. |
I believe the only relevant variation to the standard Arm ABI for these platforms is around VFP/SIMD register arguments, but I'm not completely confident on which flags cause LLVM to use it. It seems like only If Rust had support for RWPI that also changes the ABI, but it (and LLVM) currently doesn't. |
I don't think turning on MVE changes the ABI, in the same way that turning on the FPU doesn't change the ABI. I'm pretty sure the ABI (i.e. use of VFP registers in the calling convention) is controlled by a separate flag. But someone could do some tests in Godbolt to show this. |
…s, r=workingjubilee forbid toggling x87 and fpregs on hard-float targets Part of rust-lang#116344, follow-up to rust-lang#129884: The `x87` target feature on x86 and the `fpregs` target feature on ARM must not be disabled on a hardfloat target, as that would change the float ABI. However, *enabling* `fpregs` on ARM is [explicitly requested](rust-lang#130988) as it seems to be useful. Therefore, we need to refine the distinction of "forbidden" target features and "allowed" target features: all (un)stable target features can determine on a per-target basis whether they should be allowed to be toggled or not. `fpregs` then checks whether the current target has the `soft-float` feature, and if yes, `fpregs` is permitted -- otherwise, it is not. (Same for `x87` on x86). Also fixes rust-lang#132351. Since `fpregs` and `x87` can be enabled on some builds and disabled on others, it would make sense that one can query it via `cfg`. Therefore, I made them behave in `cfg` like any other unstable target feature. The first commit prepares the infrastructure, but does not change behavior. The second commit then wires up `fpregs` and `x87` with that new infrastructure. r? `@workingjubilee`
…ingjubilee forbid toggling x87 and fpregs on hard-float targets Part of rust-lang/rust#116344, follow-up to rust-lang/rust#129884: The `x87` target feature on x86 and the `fpregs` target feature on ARM must not be disabled on a hardfloat target, as that would change the float ABI. However, *enabling* `fpregs` on ARM is [explicitly requested](rust-lang/rust#130988) as it seems to be useful. Therefore, we need to refine the distinction of "forbidden" target features and "allowed" target features: all (un)stable target features can determine on a per-target basis whether they should be allowed to be toggled or not. `fpregs` then checks whether the current target has the `soft-float` feature, and if yes, `fpregs` is permitted -- otherwise, it is not. (Same for `x87` on x86). Also fixes rust-lang/rust#132351. Since `fpregs` and `x87` can be enabled on some builds and disabled on others, it would make sense that one can query it via `cfg`. Therefore, I made them behave in `cfg` like any other unstable target feature. The first commit prepares the infrastructure, but does not change behavior. The second commit then wires up `fpregs` and `x87` with that new infrastructure. r? `@workingjubilee`
@RalfJung asked me to open an issue listing all the useful Arm microcontroller feature flags that are currently entirely unsupported by Rust, not even unstably.
These are all listed at https://doc.rust-lang.org/nightly/rustc/platform-support/arm-none-eabi.html and the sub-pages, as modified by #130987.
Selecting a CPU with
-C target-cpu=xxx
causes LLVM to enable all the optional features of that type of CPU. However, sometimes CPUs are sold without certain features (e.g. you can get a Cortex-M4 either with or without an FPU). So, we use these-C target-feature=...
flags to disable some of the things that LLVM over-enthusiastically enabled for us when we selected a target-cpu. If you don't select a target-cpu, you don't need these flags because by default, only the architecture's baseline features are enabled and you never want to turn those off.-fpregs
- don't emit FPU instructions-fp64
- don't emit double precision FPU instructions-mve
- don't emit Float or Integer M-Profile Vector Extension instructions-mve.fp
- don't emit Float M-Profile Vector Extension instructions-dsp
- don't emit DSP instructions+mve
- do emit Integer M-Profile Vector Extension instructions (used with-fpregs
because MVE uses registers shared with the FPU and those registers are present if you have Integer MVE but no FPU)These are alongside the following target CPUs (
-C target-cpu=...
):cortex-m0
cortex-m0plus
cortex-m3
cortex-m4
cortex-m7
cortex-m33
cortex-m35p
cortex-m55
cortex-m85
If you don't want to use
-C target-cpu...
then the following additional flags can enable certain features. However, these aren't currently mentioned in the documentation (except+mve
because it's listed above).+mve
- M-Profile Vector Extensions (integer)+mve.fp
- M-Profile Vector Extensions (floating point)+dsp
- DSP extensions+fp-armv8d16sp
- single precision FPU for Armv8-M+fp-armv8d16
- double precision FPU for Armv8-M+vfp4d16sp
- single precision FPU for Armv7E-M+vfp4d16
- double precision FPU for Armv7E-MThe text was updated successfully, but these errors were encountered: