Skip to content

Commit 43ede97

Browse files
committed
arm: use target.llvm_floatabi over soft-float target feature
1 parent 912b729 commit 43ede97

File tree

3 files changed

+25
-14
lines changed

3 files changed

+25
-14
lines changed

compiler/rustc_target/src/target_features.rs

+20-9
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
55
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
66
use rustc_span::{Symbol, sym};
77

8-
use crate::spec::Target;
8+
use crate::spec::{FloatAbi, Target};
99

1010
/// Features that control behaviour of rustc, rather than the codegen.
1111
/// These exist globally and are not in the target-specific lists below.
@@ -148,7 +148,6 @@ const ARM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
148148
("neon", Unstable(sym::arm_target_feature), &["vfp3"]),
149149
("rclass", Unstable(sym::arm_target_feature), &[]),
150150
("sha2", Unstable(sym::arm_target_feature), &["neon"]),
151-
("soft-float", Stability::Forbidden { reason: "unsound because it changes float ABI" }, &[]),
152151
// This is needed for inline assembly, but shouldn't be stabilized as-is
153152
// since it should be enabled per-function using #[instruction_set], not
154153
// #[target_feature].
@@ -204,6 +203,7 @@ const AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
204203
("flagm", Stable, &[]),
205204
// FEAT_FLAGM2
206205
("flagm2", Unstable(sym::aarch64_unstable_target_feature), &[]),
206+
// We forbid directly toggling just `fp-armv8`; it must be toggled with `neon`.
207207
("fp-armv8", Stability::Forbidden { reason: "Rust ties `fp-armv8` to `neon`" }, &[]),
208208
// FEAT_FP16
209209
// Rust ties FP and Neon: https://github.com/rust-lang/rust/pull/91608
@@ -758,6 +758,7 @@ impl Target {
758758
match &*self.arch {
759759
"x86" => {
760760
// We support 2 ABIs, hardfloat (default) and softfloat.
761+
// x86 has no sane ABI indicator so we have to use the target feature.
761762
if self.has_feature("soft-float") {
762763
NOTHING
763764
} else {
@@ -767,6 +768,7 @@ impl Target {
767768
}
768769
"x86_64" => {
769770
// We support 2 ABIs, hardfloat (default) and softfloat.
771+
// x86 has no sane ABI indicator so we have to use the target feature.
770772
if self.has_feature("soft-float") {
771773
NOTHING
772774
} else {
@@ -775,20 +777,27 @@ impl Target {
775777
}
776778
}
777779
"arm" => {
778-
// We support 2 ABIs, hardfloat (default) and softfloat.
779-
if self.has_feature("soft-float") {
780-
NOTHING
781-
} else {
782-
// Hardfloat ABI. x87 must be enabled.
783-
(&["fpregs"], &[])
780+
// On ARM, ABI handling is reasonably sane; we use `llvm_floatabi` to indicate
781+
// to LLVM which ABI we are going for.
782+
match self.llvm_floatabi.unwrap() {
783+
FloatAbi::Soft => {
784+
// Nothing special required, will use soft-float ABI throughout.
785+
NOTHING
786+
}
787+
FloatAbi::Hard => {
788+
// Must have `fpregs` and must not have `soft-float`.
789+
(&["fpregs"], &["soft-float"])
790+
}
784791
}
785792
}
786793
"aarch64" | "arm64ec" => {
794+
// Aarch64 has no sane ABI specifier, and LLVM doesn't even have a way to force
795+
// the use of soft-float, so all we can do here is some crude hacks.
787796
match &*self.abi {
788797
"softfloat" => {
789798
// This is not fully correct, LLVM actually doesn't let us enforce the softfloat
790799
// ABI properly... see <https://github.com/rust-lang/rust/issues/134375>.
791-
// FIXME: should be forbid "neon" here? But that would be a breaking change.
800+
// FIXME: should we forbid "neon" here? But that would be a breaking change.
792801
NOTHING
793802
}
794803
_ => {
@@ -799,6 +808,8 @@ impl Target {
799808
}
800809
}
801810
"riscv32" | "riscv64" => {
811+
// RISC-V handles ABI in a very sane way, being fully explicit via `llvm_abiname`
812+
// about what the intended ABI is.
802813
match &*self.llvm_abiname {
803814
"ilp32d" | "lp64d" => {
804815
// Requires d (which implies f), incompatible with e.

tests/codegen/tied-features-strength.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// ignore-tidy-linelength
2-
//@ revisions: ENABLE_SVE DISABLE_SVE ENABLE_NEON
2+
//@ revisions: ENABLE_SVE DISABLE_SVE DISABLE_NEON ENABLE_NEON
33
//@ compile-flags: --crate-type=rlib --target=aarch64-unknown-linux-gnu
44
//@ needs-llvm-components: aarch64
55

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

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

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

tests/run-make/simd-ffi/rmake.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ fn main() {
5656
.target(&target)
5757
.emit("llvm-ir,asm")
5858
.input("simd.rs")
59-
.arg("-Ctarget-feature=+neon,+sse")
59+
.arg("-Ctarget-feature=-soft-float,+neon,+sse")
6060
.arg(&format!("-Cextra-filename=-{target}"))
6161
.run();
6262
}

0 commit comments

Comments
 (0)