about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2024-12-31 12:20:30 +0100
committerRalf Jung <post@ralfj.de>2024-12-31 12:41:20 +0100
commit43ede97ebf7d874c9076723840c945b051b10ee2 (patch)
tree340d1ce37168bb2a8709e1b9307cb33c31f877d1
parent912b7291d0f8f477388282a04ccf085d1b3715b0 (diff)
downloadrust-43ede97ebf7d874c9076723840c945b051b10ee2.tar.gz
rust-43ede97ebf7d874c9076723840c945b051b10ee2.zip
arm: use target.llvm_floatabi over soft-float target feature
-rw-r--r--compiler/rustc_target/src/target_features.rs29
-rw-r--r--tests/codegen/tied-features-strength.rs8
-rw-r--r--tests/run-make/simd-ffi/rmake.rs2
3 files changed, 25 insertions, 14 deletions
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index b5e30c4d5c9..142ac0ff3d3 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -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.
@@ -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].
@@ -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
@@ -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 {
@@ -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 {
@@ -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
                     }
                     _ => {
@@ -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.
diff --git a/tests/codegen/tied-features-strength.rs b/tests/codegen/tied-features-strength.rs
index 4d96a7cde78..6daa5cd7d5e 100644
--- a/tests/codegen/tied-features-strength.rs
+++ b/tests/codegen/tied-features-strength.rs
@@ -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
 
@@ -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,?))*}}" }
diff --git a/tests/run-make/simd-ffi/rmake.rs b/tests/run-make/simd-ffi/rmake.rs
index 04990c8bdf4..ef71dfa4c30 100644
--- a/tests/run-make/simd-ffi/rmake.rs
+++ b/tests/run-make/simd-ffi/rmake.rs
@@ -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();
     }