The initial naming of "Abi" was an awful mistake, conveying wrong ideas
about how psABIs worked and even more about what the enum meant.
It was only meant to represent the way the value would be described to
a codegen backend as it was lowered to that intermediate representation.
It was never meant to mean anything about the actual psABI handling!
The conflation is because LLVM typically will associate a certain form
with a certain ABI, but even that does not hold when the special cases
that actually exist arise, plus the IR annotations that modify the ABI.
Reframe `rustc_abi::Abi` as the `BackendRepr` of the type, and rename
`BackendRepr::Aggregate` as `BackendRepr::Memory`. Unfortunately, due to
the persistent misunderstandings, this too is now incorrect:
- Scattered ABI-relevant code is entangled with BackendRepr
- We do not always pre-compute a correct BackendRepr that reflects how
we "actually" want this value to be handled, so we leave the backend
interface to also inject various special-cases here
- In some cases `BackendRepr::Memory` is a "real" aggregate, but in
others it is in fact using memory, and in some cases it is a scalar!
Our rustc-to-backend lowering code handles this sort of thing right now.
That will eventually be addressed by lifting duplicated lowering code
to either rustc_codegen_ssa or rustc_target as appropriate.
This commit adds a new rustc target feature named `wide-arithmetic` for
WebAssembly targets. This corresponds to the [wide-arithmetic] proposal
for WebAssembly which adds new instructions catered towards accelerating
integer arithmetic larger than 64-bits. This proposal to WebAssembly is
not standard yet so this new feature is flagged as an unstable target
feature. Additionally Rust's LLVM version doesn't support this new
feature yet since support will first be added in LLVM 20, so the
feature filtering logic for LLVM is updated to handle this.
I'll also note that I'm not currently planning to add wasm-specific
intrinsics to `std::arch::wasm32` at this time. The currently proposed
instructions are all accessible through `i128` or `u128`-based
operations which Rust already supports, so intrinsic shouldn't be
necessary to get access to these new instructions.
[wide-arithmetic]: https://github.com/WebAssembly/wide-arithmetic
rustc_target: Add pauth-lr aarch64 target feature
Add the pauth-lr target feature, corresponding to aarch64 FEAT_PAuth_LR. This feature has been added in LLVM 19.
It is currently not supported by the Linux hwcap and so we cannot add runtime feature detection for it at this time.
r? `@Amanieu`
Emit future-incompatibility lint when calling/declaring functions with vectors that require missing target feature
On some architectures, vector types may have a different ABI depending on whether the relevant target features are enabled. (The ABI when the feature is disabled is often not specified, but LLVM implements some de-facto ABI.)
As discussed in https://github.com/rust-lang/lang-team/issues/235, this turns out to very easily lead to unsound code.
This commit makes it a post-monomorphization error to declare or call functions using those vector types in a context in which the corresponding target features are disabled, if using an ABI for which the difference is relevant. This ensures that these functions are always called with a consistent ABI.
See the [nomination comment](https://github.com/rust-lang/rust/pull/127731#issuecomment-2288558187) for more discussion.
r? RalfJung
Part of https://github.com/rust-lang/rust/issues/116558
On some architectures, vector types may have a different ABI when
relevant target features are enabled.
As discussed in https://github.com/rust-lang/lang-team/issues/235, this
turns out to very easily lead to unsound code.
This commit makes it an error to declare or call functions using those
vector types in a context in which the corresponding target features are
disabled, if using an ABI for which the difference is relevant.
Fix `target_vendor` in QNX Neutrino targets
The `x86_64-pc-nto-qnx710` and `i586-pc-nto-qnx700` targets have `pc` in their target triple names, but the vendor was set to the default `"unknown"`.
CC target maintainers `@flba-eb,` `@gh-tr,` `@jonathanpallant` and `@japaric`
Rollup of 9 pull requests
Successful merges:
- #130991 (Vectorized SliceContains)
- #131928 (rustdoc: Document `markdown` module.)
- #131955 (Set `signext` or `zeroext` for integer arguments on RISC-V and LoongArch64)
- #131979 (Minor tweaks to `compare_impl_item.rs`)
- #132036 (Add a test case for #131164)
- #132039 (Specialize `read_exact` and `read_buf_exact` for `VecDeque`)
- #132060 ("innermost", "outermost", "leftmost", and "rightmost" don't need hyphens)
- #132065 (Clarify documentation of `ptr::dangling()` function)
- #132066 (Fix a typo in documentation of `pointer::sub_ptr()`)
r? `@ghost`
`@rustbot` modify labels: rollup
terminology: #[feature] *enables* a feature (instead of "declaring" or "activating" it)
Mostly, we currently call a feature that has a corresponding `#[feature(name)]` attribute in the current crate a "declared" feature. I think that is confusing as it does not align with what "declaring" usually means. Furthermore, we *also* refer to `#[stable]`/`#[unstable]` as *declaring* a feature (e.g. in [these diagnostics](f25e5abea2/compiler/rustc_passes/messages.ftl (L297-L301))), which aligns better with what "declaring" usually means. To make things worse, the functions `tcx.features().active(...)` and `tcx.features().declared(...)` both exist and they are doing almost the same thing (testing whether a corresponding `#[feature(name)]` exists) except that `active` would ICE if the feature is not an unstable lang feature. On top of this, the callback when a feature is activated/declared is called `set_enabled`, and many comments also talk about "enabling" a feature.
So really, our terminology is just a mess.
I would suggest we use "declaring a feature" for saying that something is/was guarded by a feature (e.g. `#[stable]`/`#[unstable]`), and "enabling a feature" for `#[feature(name)]`. This PR implements that.
Always specify `llvm_abiname` for RISC-V targets
For RISC-V targets, when `llvm_abiname` is not specified LLVM will infer the ABI from the target features, causing #116344 to occur. This PR adds the correct `llvm_abiname` to all RISC-V targets where it is missing (which are all soft-float targets), and adds a test to prevent future RISC-V targets from accidentally omitting `llvm_abiname`. The only affect of this PR is that `-Ctarget-feature=+f` (or similar) will no longer affect the ABI on the modified targets.
<!-- homu-ignore:start -->
r? `@RalfJung`
<!--- homu-ignore:end -->
rust_for_linux: -Zregparm=<N> commandline flag for X86 (#116972)
Command line flag `-Zregparm=<N>` for X86 (32-bit) for rust-for-linux: https://github.com/rust-lang/rust/issues/116972
Implemented in the similar way as fastcall/vectorcall support (args are marked InReg if fit).
Migrate `llvm::set_comdat` and `llvm::SetUniqueComdat` to LLVM-C FFI.
Note, now we can call `llvm::set_comdat` only when the target actually
supports adding comdat. As this has no convenient LLVM-C API, we
implement this as `TargetOptions::supports_comdat`.
Co-authored-by: Stuart Cook <Zalathar@users.noreply.github.com>
Setting up indirect access to external data for loongarch64-linux-{musl,ohos}
In issue #118053, the `loongarch64-unknown-linux-gnu` target needs indirection to access external data, and so do the `loongarch64-unknown-linux-musl` and `loongarch64-unknown-linux-ohos` targets.
Add the pauth-lr target feature, corresponding to aarch64 FEAT_PAuth_LR.
This feature has been added in LLVM 19.
It is currently not supported by the Linux hwcap and so we cannot add
runtime feature detection for it at this time.
LLVM has added 3 new address spaces to support special Windows use
cases. These shouldn't trouble us for now, but LLVM requires matching
data layouts.
See llvm/llvm-project#111879 for details
Fix clobber_abi and disallow SVE-related registers in Arm64EC inline assembly
Currently `clobber_abi` in Arm64EC inline assembly is implemented using `InlineAsmClobberAbi::AArch64NoX18`, but broken since it attempts to clobber registers that cannot be used in Arm64EC: https://godbolt.org/z/r3PTrGz5r
```
error: cannot use register `x13`: x13, x14, x23, x24, x28, v16-v31 cannot be used for Arm64EC
--> <source>:6:14
|
6 | asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags));
| ^^^^^^^^^^^^^^^^
error: cannot use register `x14`: x13, x14, x23, x24, x28, v16-v31 cannot be used for Arm64EC
--> <source>:6:14
|
6 | asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags));
| ^^^^^^^^^^^^^^^^
<omitted the same errors for v16-v31>
```
Additionally, this disallows SVE-related registers per https://github.com/rust-lang/rust/pull/131332#issuecomment-2401189142.
cc ``@dpaoliello``
r? ``@Amanieu``
``@rustbot`` label O-windows O-AArch64 +A-inline-assembly
compiler: `{TyAnd,}Layout` comes home
The `Layout` and `TyAndLayout` types are heavily abstract and have no particular target-specific qualities, though we do use them to answer questions particular to targets. We can keep it that way if we simply move them out of `rustc_target` and into `rustc_abi`. They bring a small entourage of connected types with them, but that's fine.
This will allow us to strengthen a few abstraction barriers over time and thus make the notoriously gnarly layout code easier to refactor. For now, we don't need to worry about that and deliberately use reexports to minimize this particular diff.
In issue #118053, the `loongarch64-unknown-linux-gnu` target needs indirection
to access external data, and so do the `loongarch64-unknown-linux-musl` and
`loongarch64-unknown-linux-ohos` targets.
Support clobber_abi in MSP430 inline assembly
This supports `clobber_abi` which is one of the requirements of stabilization mentioned in #93335.
Refs: Section 3.2 "Register Conventions" in [MSP430 Embedded Application Binary Interface](https://www.ti.com/lit/an/slaa534a/slaa534a.pdf)
cc ``@cr1901``
r? ``@Amanieu``
``@rustbot`` label +O-msp430
ABI: Pass aggregates by value on AIX
On AIX we pass aggregates byval. Adds new ABI for AIX for powerpc64.
313ad85dfa/clang/lib/CodeGen/Targets/PPC.cpp (L216)
Fixes the following 2 testcases on AIX:
```
tests/ui/abi/extern/extern-pass-TwoU16s.rs
tests/ui/abi/extern/extern-pass-TwoU8s.rs
```
LLVM 20 split out what used to be called b16b16 and correspond to aarch64
FEAT_SVE_B16B16 into sve-b16b16 and sme-b16b16.
Add sme-b16b16 as an explicit feature and update the codegen accordingly.
Fix `target_vendor` in non-IDF Xtensa ESP32 targets
`rustc`'s Xtensa ESP32 targets are the following:
- `xtensa-esp32-none-elf`
- `xtensa-esp32-espidf`
- `xtensa-esp32s2-none-elf`
- `xtensa-esp32s2-espidf`
- `xtensa-esp32s3-none-elf`
- `xtensa-esp32s3-espidf`
The ESP-IDF targets already set `target_vendor="espressif"`, however, the ESP32 is, from my understanding, produced by Espressif regardless of whether using the IDF or not, so we should set the target vendor there as well?
Fix `target_abi` in `sparc-unknown-none-elf`
This was previously set to `target_abi = "elf"`, but `elf` is not used elsewhere as a target ABI (even though there's many targets that have it in their name), so I've removed it.
CC target maintainer ``@jonathanpallant,`` what do you think about this?
``@rustbot`` label O-SPARC
Fix `target_env` in `avr-unknown-gnu-atmega328`
The target name itself contains GNU, we should probably reflect that as `target_env = "gnu"` as well? Or from my reading of https://github.com/rust-lang/rust/pull/74941#issuecomment-712219034, perhaps not, but then that should probably be documented somewhere?
There's no listed target maintainer, but the target was introduced in https://github.com/rust-lang/rust/pull/74941, so I'll ping the author of that: `@dylanmckay`
Relatedly, I wonder _why_ the recommendation is to [create separate target triples for each AVR](https://github.com/Rahix/avr-hal/tree/main/avr-specs), when `-Ctarget-cpu=...` would suffice, perhaps you could also elaborate on that? Was it just because `-Ctarget-cpu=...` didn't exist back then? If so, now that it does, should we now change the target back to e.g. `avr-unknown-none-gnu`, and require the user to set `-Ctarget-cpu=...` instead?
Add x86_64-unknown-trusty as tier 3 target
This PR adds a third target for the Trusty platform, `x86_64-unknown-trusty`.
Please let me know if an MCP is required. https://github.com/rust-lang/compiler-team/issues/582 was made when adding the first two targets, I can make another one for the new target as well if needed.
# Target Tier Policy Acknowledgements
> A tier 3 target must have a designated developer or developers (the "target maintainers") on record to be CCed when issues arise regarding the target. (The mechanism to track and CC such developers may evolve over time.)
- Nicole LeGare (```@randomPoison)```
- Andrei Homescu (```@ahomescu)```
- Chris Wailes (chriswailes@google.com)
- As a fallback trusty-dev-team@google.com can be contacted
Note that this does not reflect the maintainers currently listed in [`trusty.md`](c52c23b6f4/src/doc/rustc/src/platform-support/trusty.md). #130452 is currently open to update the list of maintainers in the documentation.
> Targets must use naming consistent with any existing targets; for instance, a target for the same CPU or OS as an existing Rust target should use the same name for that CPU or OS. Targets should normally use the same names and naming conventions as used elsewhere in the broader ecosystem beyond Rust (such as in other toolchains), unless they have a very good reason to diverge. Changing the name of a target can be highly disruptive, especially once the target reaches a higher tier, so getting the name right is important even for a tier 3 target.
The new target `x86_64-unknown-trusty` follows the existing naming convention for similar targets.
> Target names should not introduce undue confusion or ambiguity unless absolutely necessary to maintain ecosystem compatibility. For example, if the name of the target makes people extremely likely to form incorrect beliefs about what it targets, the name should be changed or augmented to disambiguate it.
👍
> Tier 3 targets may have unusual requirements to build or use, but must not create legal issues or impose onerous legal terms for the Rust project or for Rust developers or users.
There are no known legal issues or license incompatibilities.
> Neither this policy nor any decisions made regarding targets shall create any binding agreement or estoppel by any party. If any member of an approving Rust team serves as one of the maintainers of a target, or has any legal or employment requirement (explicit or implicit) that might affect their decisions regarding a target, they must recuse themselves from any approval decisions regarding the target's tier status, though they may otherwise participate in discussions.
👍
> Tier 3 targets should attempt to implement as much of the standard libraries as possible and appropriate (core for most targets, alloc for targets that can support dynamic memory allocation, std for targets with an operating system or equivalent layer of system-provided functionality), but may leave some code unimplemented (either unavailable or stubbed out as appropriate), whether because the target makes it impossible to implement or challenging to implement. The authors of pull requests are not obligated to avoid calling any portions of the standard library on the basis of a tier 3 target not implementing those portions.
This PR only adds the target. `std` support is being worked on and will be added in a future PR.
> The target must provide documentation for the Rust community explaining how to build for the target, using cross-compilation if possible. If the target supports running binaries, or running tests (even if they do not pass), the documentation must explain how to run such binaries or tests for the target, using emulation if possible or dedicated hardware if necessary.
👍
> Tier 3 targets must not impose burden on the authors of pull requests, or other developers in the community, to maintain the target. In particular, do not post comments (automated or manual) on a PR that derail or suggest a block on the PR based on a tier 3 target. Do not send automated messages or notifications (via any medium, including via ```@)``` to a PR author or others involved with a PR regarding a tier 3 target, unless they have opted into such messages.
👍
> Patches adding or updating tier 3 targets must not break any existing tier 2 or tier 1 target, and must not knowingly break another tier 3 target without approval of either the compiler team or the maintainers of the other tier 3 target.
👍
> Tier 3 targets must be able to produce assembly using at least one of rustc's supported backends from any host target. (Having support in a fork of the backend is not sufficient, it must be upstream.)
👍
This was previously set to `target_abi = "elf"`, but `elf` is not used
elsewhere as a target ABI (even though there's many targets that have it
in their name).
Fix `target_abi` in SOLID targets
The `armv7a-kmc-solid_asp3-eabi` and `armv7a-kmc-solid_asp3-eabihf` targets clearly have the ABI in their name, so it should also be exposed in Rust's `target_abi` cfg variable.
CC target maintainer `@kawadakk.`
Fix `target_vendor` for `aarch64-nintendo-switch-freestanding`
Previously set to `target_vendor = "unknown"`, but Nintendo is clearly the vendor of the Switch, and is also reflected in the target name itself.
CC target maintainers `@leo60228` and `@jam1garner`
Previously set to `target_os = "none"` and `target_env = "psx"`, but
although the Playstation 1 is _close_ to a bare metal target in some
regards, it's still very much an operating system, so we should set
`target_os = "psx"`.
This also matches the `mipsel-sony-psp` target, which sets
`target_os = "psp"`.
The `armv7a-kmc-solid_asp3-eabi` and `armv7a-kmc-solid_asp3-eabihf`
targets clearly have the ABI in their name, so it should also be exposed
in Rust's `target_abi` cfg variable.
The Xtensa ESP32 targets are the following:
- xtensa-esp32-none-elf
- xtensa-esp32-espidf
- xtensa-esp32s2-none-elf
- xtensa-esp32s2-espidf
- xtensa-esp32s3-none-elf
- xtensa-esp32s3-espidf
The ESP-IDF targets already set `target_vendor="espressif"`, however,
the ESP32 is produced by Espressif regardless of whether using the IDF
or not, so we should set the target vendor there as well.
Apple: Do not specify an SDK version in `rlib` object files
This was added in https://github.com/rust-lang/rust/pull/114114, but is unnecessary, since it ends up being overwritten when linking anyhow, and it feels wrong to embed some arbitrary SDK version in here. The object files produced by LLVM also do not set this, and the tooling shows `n/a` when it's `0`, so it seems to genuinely be optional in object files.
I've also added a test for the different places the SDK version shows up, and documented a bit more in the code how SDK versions work.
See https://github.com/rust-lang/rust/issues/129432 for the bigger picture.
Tested with (excludes the same few targets as in https://github.com/rust-lang/rust/pull/130435):
```console
./x test tests/run-make/apple-sdk-version --target aarch64-apple-darwin,aarch64-apple-ios,aarch64-apple-ios-macabi,aarch64-apple-ios-sim,aarch64-apple-tvos,aarch64-apple-tvos-sim,aarch64-apple-visionos,aarch64-apple-visionos-sim,aarch64-apple-watchos,aarch64-apple-watchos-sim,arm64_32-apple-watchos,armv7k-apple-watchos,armv7s-apple-ios,x86_64-apple-darwin,x86_64-apple-ios,x86_64-apple-ios-macabi,x86_64-apple-tvos,x86_64-apple-watchos-sim,x86_64h-apple-darwin
IPHONEOS_DEPLOYMENT_TARGET=10.0 ./x test tests/run-make/apple-sdk-version --target=i386-apple-ios
```
CC `@BlackHoleFox,` you [originally commented on these values](https://github.com/rust-lang/rust/pull/114114#discussion_r1300599445).
`@rustbot` label O-apple
Move Apple linker args from `rustc_target` to `rustc_codegen_ssa`
They are dependent on the deployment target and SDK version, but having these in `rustc_target` makes it hard to introduce that dependency. Part of the work needed to do https://github.com/rust-lang/rust/issues/118204, see https://github.com/rust-lang/rust/pull/129342 for some discussion.
Tested using:
```console
./x test tests/run-make/apple-deployment-target --target="aarch64-apple-darwin,aarch64-apple-ios,aarch64-apple-ios-macabi,aarch64-apple-ios-sim,aarch64-apple-tvos,aarch64-apple-tvos-sim,aarch64-apple-visionos,aarch64-apple-visionos-sim,aarch64-apple-watchos,aarch64-apple-watchos-sim,arm64_32-apple-watchos,armv7k-apple-watchos,armv7s-apple-ios,x86_64-apple-darwin,x86_64-apple-ios,x86_64-apple-ios-macabi,x86_64-apple-tvos,x86_64-apple-watchos-sim,x86_64h-apple-darwin"
IPHONEOS_DEPLOYMENT_TARGET=10.0 ./x test tests/run-make/apple-deployment-target --target=i386-apple-ios
```
`arm64e-apple-darwin` and `arm64e-apple-ios` have not been tested, see https://github.com/rust-lang/rust/issues/130085, neither is `i686-apple-darwin`, since that requires using an x86_64 macbook, and I currently can't get mine to work, see https://github.com/rust-lang/rust/issues/130434.
CC `@petrochenkov`
Fixup Apple target's description strings
Noticed this inconsistency in how the Apple target's had their new descriptions written while looking at https://github.com/rust-lang/rust/pull/130614, and figured it was easy enough to fixup shortly. I think prefixing every OS with `Apple` is clearer, especially for less known ones like `visionOS` and `watchOS`; so that's what was done here along with making the architecture names more consistent and then some other small tweaks.
~~r? `@thomcc~~`
cc `@madsmtm`