From aab0757c666504f36c5a382304ec5390fc4f7454 Mon Sep 17 00:00:00 2001 From: Jamie Cunliffe Date: Mon, 23 Jan 2023 13:15:53 +0000 Subject: [PATCH] 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. --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 36 +++++++++++++++++--- tests/codegen/tied-features-strength.rs | 25 ++++++++++++++ 2 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 tests/codegen/tied-features-strength.rs diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index abf46b914b7..a75c15ee4be 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -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 { + Some(format!("{}{}", enable_disable, f)) + } + _ if idx == 0 => Some(format!("{}{}", enable_disable, f)), + _ => None, + }, + )) }) .flatten(); features.extend(feats); diff --git a/tests/codegen/tied-features-strength.rs b/tests/codegen/tied-features-strength.rs new file mode 100644 index 00000000000..36fd717e914 --- /dev/null +++ b/tests/codegen/tied-features-strength.rs @@ -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() {}