Rather than returning an array of features from to_llvm_features, return a structure that contains
the dependencies. This also contains metadata on how the features depend on each other to allow for
the correct enabling and disabling.
Some features that are tied together only make sense to be folded
together when enabling the feature. For example on AArch64 sve and
neon are tied together, however it doesn't make sense to disable neon
when disabling sve.
In #91608 the fp-armv8 feature was removed as it's tied to the neon
feature. However disabling neon didn't actually disable the use of
floating point registers and instructions, for this `-fp-armv8` is
required.
Remove misleading target feature aliases
Fixes#100752. This is a follow up to #103750. These aliases could not be completely removed until rust-lang/stdarch#1355 landed.
cc `@Amanieu`
Print all features with --print target-features
This fixes `rustc --print target-features` with respect to aliases and tied features.
Before this change, the print command assumed that each LLVM feature corresponds exactly to one rustc feature. In the case of aliases and tied features, this assumption failed and some features (such as aarch64's "pacg") were missing. With this change, every target feature is listed.
After https://github.com/llvm/llvm-project/commit/8689f5e landed, LLVM takes the intersection of v8a and v8r as default.
This commit brings back v8a support by explicitly specifying v8a in the feature list.
This should solve #97724.
Add support for MIPS VZ ISA extension
[Link to relevant LLVM line where virt extension is specified](83fab8cee9/llvm/lib/Target/Mips/Mips.td (L172-L173))
This has been tested on mips-unknown-linux-musl with a target-cpu that is >= MIPS32 5 and `target-features=+virt`. The example was checked in a disassembler to ensure the correct assembly sequence was being generated using the virtualization instructions.
Needed additional work:
* MIPS is missing from [the Rust reference CPU feature lists](https://doc.rust-lang.org/reference/attributes/codegen.html#available-features)
Example docs for later:
```md
#### `mips` or `mips64`
This platform requires that `#[target_feature]` is only applied to [`unsafe`
functions][unsafe function]. This target's feature support is currently unstable
and must be enabled by `#![feature(mips_target_feature)]` ([Issue #44839])
[Issue #44839]: https://github.com/rust-lang/rust/issues/44839
Further documentation on these features can be found in the [MIPS Instruction Set
Reference Manual], or elsewhere on [mips.com].
[MIPS Instruction Set Reference Manual]: https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00086-2B-MIPS32BIS-AFP-6.06.pdf
[developer.arm.com]: https://www.mips.com/products/architectures/ase/
Feature | Implicitly Enables | Description
---------------|--------------------|-------------------
`fp64` | | 64-bit Floating Point
`msa` | | "MIPS SIMD Architecture"
`virt` | | Virtualization instructions (VZ ASE)
```
If the above is good I can also submit a PR for that if there's interest in documenting it while it's still unstable. Otherwise that can be dropped, I just wrote it before realizing it was possibly not a good idea.
Relevant to #44839
https://reviews.llvm.org/D120026 changed atomics on thumbv6m to
use libatomic, to ensure that atomic load/store are compatible with
atomic RMW/CAS. However, Rust wants to expose only load/store
without libcalls.
https://reviews.llvm.org/D130480 added support for this behind
the +atomics-32 target feature, so enable that feature.
Inline assembly uses the target features to determine which registers
are available on the current target. However it needs to be able to
access unstable target features for this.
Fixes#99071
Arm's FEAT_FP and Feat_AdvSIMD describe the same thing on AArch64:
The Neon unit, which handles both floating point and SIMD instructions.
Moreover, a configuration for AArch64 must include both or neither.
Arm says "entirely proprietary" toolchains may omit floating point:
https://developer.arm.com/documentation/102374/0101/Data-processing---floating-point
In the Programmer's Guide for Armv8-A, Arm says AArch64 can have
both FP and Neon or neither in custom implementations:
https://developer.arm.com/documentation/den0024/a/AArch64-Floating-point-and-NEON
In "Bare metal boot code for Armv8-A", enabling Neon and FP
is just disabling the same trap flag:
https://developer.arm.com/documentation/dai0527/a
In an unlikely future where "Neon and FP" become unrelated,
we can add "[+-]fp" as its own feature flag.
Until then, we can simplify programming with Rust on AArch64 by
folding both into "[+-]neon", which is valid as it supersets both.
"[+-]neon" is retained for niche uses such as firmware, kernels,
"I just hate floats", and so on.
Direct users towards using Rust target feature names in CLI
This PR consists of a couple of changes on how we handle target features.
In particular there is a bug-fix wherein we avoid passing through features that aren't prefixed by `+` or `-` to LLVM. These appear to be causing LLVM to assert, which is pretty poor a behaviour (and also makes it pretty clear we expect feature names to be prefixed).
The other commit, I anticipate to be somewhat more controversial is outputting a warning when users specify a LLVM-specific, or otherwise unknown, feature name on the CLI. In those situations we request users to either replace it with a known Rust feature name (e.g. `bmi` -> `bmi1`) or file a feature request. I've a couple motivations for this: first of all, if users are specifying these features on the command line, I'm pretty confident there is also a need for these features to be usable via `#[cfg(target_feature)]` machinery. And second, we're growing a fair number of backends recently and having ability to provide some sort of unified-ish interface in this place seems pretty useful to me.
Sponsored by: standard.ai
If they are trying to use features rustc doesn't yet know about,
request a feature request.
Additionally, also warn against using feature names without leading `+`
or `-` signs.
LLVM really dislikes this and will assert, saying something along the
lines of:
```
rustc: llvm/lib/MC/MCSubtargetInfo.cpp:60: void ApplyFeatureFlag(
llvm::FeatureBitset&, llvm::StringRef, llvm::ArrayRef<llvm::SubtargetFeatureKV>
): Assertion
`SubtargetFeatures::hasFlag(Feature) && "Feature flags should start with '+' or '-'"`
failed.
```
The "CI" environment var isn't universal (for example, I think Azure
uses TF_BUILD). However, we are mostly concerned with rust-lang/rust's
own CI which currently is GitHub Actions which does set "CI". And I
think most other providers use "CI" as well.