Only disable folded features when it makes sense.

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.
This commit is contained in:
Jamie Cunliffe 2023-01-23 13:15:53 +00:00
parent 4cca436e30
commit aab0757c66
2 changed files with 56 additions and 5 deletions

View File

@ -147,6 +147,9 @@ pub fn time_trace_profiler_finish(file_name: &Path) {
// Though note that Rust can also be build with an external precompiled version of LLVM
// which might lead to failures if the oldest tested / supported LLVM version
// doesn't yet support the relevant intrinsics
//
// Note: The first feature in the list that is returned is the mapping to the feature that is
// provided from the `s` parameter.
pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]> {
let arch = if sess.target.arch == "x86_64" { "x86" } else { &*sess.target.arch };
match (arch, s) {
@ -182,6 +185,23 @@ pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]
}
}
pub enum TargetFeatureFoldStrength {
// The feature is only tied when enabling the feature, disabling
// this feature shouldn't disable the tied feature.
EnableOnly,
// The feature is tied for both enabling and disabling this feature.
Both,
}
// Determines how the features are folded together, some features are
// linked a lot more than some others.
pub fn feature_fold_strength<'a>(feats: &SmallVec<[&'a str; 2]>) -> TargetFeatureFoldStrength {
match (feats.get(0), feats.get(1)) {
(Some(&"neon"), Some(&"fp-armv8")) => TargetFeatureFoldStrength::Both,
_ => TargetFeatureFoldStrength::EnableOnly,
}
}
/// Given a map from target_features to whether they are enabled or disabled,
/// ensure only valid combinations are allowed.
pub fn check_tied_features(
@ -471,11 +491,17 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
// passing requests down to LLVM. This means that all in-language
// features also work on the command line instead of having two
// different names when the LLVM name and the Rust name differ.
Some(
to_llvm_features(sess, feature)
.into_iter()
.map(move |f| format!("{}{}", enable_disable, f)),
)
let llvm_features = to_llvm_features(sess, feature);
Some(to_llvm_features(sess, feature).into_iter().enumerate().filter_map(
move |(idx, f)| match (enable_disable, feature_fold_strength(&llvm_features)) {
('-' | '+', TargetFeatureFoldStrength::Both)
| ('+', TargetFeatureFoldStrength::EnableOnly) => {
Some(format!("{}{}", enable_disable, f))
}
_ if idx == 0 => Some(format!("{}{}", enable_disable, f)),
_ => None,
},
))
})
.flatten();
features.extend(feats);

View File

@ -0,0 +1,25 @@
// ignore-tidy-linelength
// revisions: ENABLE_SVE DISABLE_SVE DISABLE_NEON ENABLE_NEON
// compile-flags: --crate-type=rlib --target=aarch64-unknown-linux-gnu
// needs-llvm-components: aarch64
// [ENABLE_SVE] compile-flags: -C target-feature=+sve
// ENABLE_SVE: attributes #0 = { {{.*}} "target-features"="+outline-atomics,+sve,+neon,+v8a" }
// [DISABLE_SVE] compile-flags: -C target-feature=-sve
// DISABLE_SVE: attributes #0 = { {{.*}} "target-features"="+outline-atomics,-sve,+v8a" }
// [DISABLE_NEON] compile-flags: -C target-feature=-neon
// DISABLE_NEON: attributes #0 = { {{.*}} "target-features"="+outline-atomics,-neon,-fp-armv8,+v8a" }
// [ENABLE_NEON] compile-flags: -C target-feature=+neon
// ENABLE_NEON: attributes #0 = { {{.*}} "target-features"="+outline-atomics,+neon,+fp-armv8,+v8a" }
#![feature(no_core, lang_items)]
#![no_core]
#[lang = "sized"]
trait Sized {}
pub fn test() {}