Skip to content

Commit

Permalink
arm: use target.llvm_floatabi over soft-float target feature
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Dec 31, 2024
1 parent 8c59ce9 commit 8799588
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 14 deletions.
29 changes: 20 additions & 9 deletions compiler/rustc_target/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_span::{Symbol, sym};

use crate::spec::Target;
use crate::spec::{FloatAbi, Target};

/// Features that control behaviour of rustc, rather than the codegen.
/// These exist globally and are not in the target-specific lists below.
Expand Down Expand Up @@ -148,7 +148,6 @@ const ARM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("neon", Unstable(sym::arm_target_feature), &["vfp3"]),
("rclass", Unstable(sym::arm_target_feature), &[]),
("sha2", Unstable(sym::arm_target_feature), &["neon"]),
("soft-float", Stability::Forbidden { reason: "unsound because it changes float ABI" }, &[]),
// This is needed for inline assembly, but shouldn't be stabilized as-is
// since it should be enabled per-function using #[instruction_set], not
// #[target_feature].
Expand Down Expand Up @@ -204,6 +203,7 @@ const AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("flagm", Stable, &[]),
// FEAT_FLAGM2
("flagm2", Unstable(sym::aarch64_unstable_target_feature), &[]),
// We forbid directly toggling just `fp-armv8`; it must be toggled with `neon`.
("fp-armv8", Stability::Forbidden { reason: "Rust ties `fp-armv8` to `neon`" }, &[]),
// FEAT_FP16
// Rust ties FP and Neon: https://github.com/rust-lang/rust/pull/91608
Expand Down Expand Up @@ -758,6 +758,7 @@ impl Target {
match &*self.arch {
"x86" => {
// We support 2 ABIs, hardfloat (default) and softfloat.
// x86 has no sane ABI indicator so we have to use the target feature.
if self.has_feature("soft-float") {
NOTHING
} else {
Expand All @@ -767,6 +768,7 @@ impl Target {
}
"x86_64" => {
// We support 2 ABIs, hardfloat (default) and softfloat.
// x86 has no sane ABI indicator so we have to use the target feature.
if self.has_feature("soft-float") {
NOTHING
} else {
Expand All @@ -775,20 +777,27 @@ impl Target {
}
}
"arm" => {
// We support 2 ABIs, hardfloat (default) and softfloat.
if self.has_feature("soft-float") {
NOTHING
} else {
// Hardfloat ABI. x87 must be enabled.
(&["fpregs"], &[])
// On ARM, ABI handling is reasonably sane; we use `llvm_floatabi` to indicate
// to LLVM which ABI we are going for.
match self.llvm_floatabi.unwrap() {
FloatAbi::Soft => {
// Nothing special required, will use soft-float ABI throughout.
NOTHING
}
FloatAbi::Hard => {
// Must have `fpregs` and must not have `soft-float`.
(&["fpregs"], &["soft-float"])
}
}
}
"aarch64" | "arm64ec" => {
// Aarch64 has no sane ABI specifier, and LLVM doesn't even have a way to force
// the use of soft-float, so all we can do here is some crude hacks.
match &*self.abi {
"softfloat" => {
// This is not fully correct, LLVM actually doesn't let us enforce the softfloat
// ABI properly... see <https://github.com/rust-lang/rust/issues/134375>.
// FIXME: should be forbid "neon" here? But that would be a breaking change.
// FIXME: should we forbid "neon" here? But that would be a breaking change.
NOTHING
}
_ => {
Expand All @@ -799,6 +808,8 @@ impl Target {
}
}
"riscv32" | "riscv64" => {
// RISC-V handles ABI in a very sane way, being fully explicit via `llvm_abiname`
// about what the intended ABI is.
match &*self.llvm_abiname {
"ilp32d" | "lp64d" => {
// Requires d (which implies f), incompatible with e.
Expand Down
8 changes: 4 additions & 4 deletions tests/codegen/tied-features-strength.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// ignore-tidy-linelength
//@ revisions: ENABLE_SVE DISABLE_SVE ENABLE_NEON
//@ revisions: ENABLE_SVE DISABLE_SVE DISABLE_NEON ENABLE_NEON
//@ compile-flags: --crate-type=rlib --target=aarch64-unknown-linux-gnu
//@ needs-llvm-components: aarch64

Expand All @@ -13,9 +13,9 @@
//@ [DISABLE_SVE] compile-flags: -C target-feature=-sve -Copt-level=0
// DISABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fpmr,?)?|(-sve,?)|(\+neon,?)|(\+fp-armv8,?))*}}" }

// The DISABLE_NEON is disabled since neon is a required target feature for this targt, it cannot be disabled.
// it would have: compile-flags: -C target-feature=-neon -Copt-level=0
// DISABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fpmr,?)?|(-fp-armv8,?)|(-neon,?))*}}" }
//@ [DISABLE_NEON] compile-flags: -C target-feature=-neon -Copt-level=0
// `neon` and `fp-armv8` get enabled as target base features, but then disabled again at the end of the list.
// DISABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fp-armv8,?)|(\+neon,?))*}},-neon,-fp-armv8{{(,\+fpmr)?}}" }

//@ [ENABLE_NEON] compile-flags: -C target-feature=+neon -Copt-level=0
// ENABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fpmr,?)?|(\+fp-armv8,?)|(\+neon,?))*}}" }
Expand Down
2 changes: 1 addition & 1 deletion tests/run-make/simd-ffi/rmake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fn main() {
.target(&target)
.emit("llvm-ir,asm")
.input("simd.rs")
.arg("-Ctarget-feature=+neon,+sse")
.arg("-Ctarget-feature=-soft-float,+neon,+sse")
.arg(&format!("-Cextra-filename=-{target}"))
.run();
}
Expand Down

0 comments on commit 8799588

Please sign in to comment.