@@ -147,6 +147,9 @@ pub fn time_trace_profiler_finish(file_name: &Path) {
147147// Though note that Rust can also be build with an external precompiled version of LLVM
148148// which might lead to failures if the oldest tested / supported LLVM version
149149// doesn't yet support the relevant intrinsics
150+ //
151+ // Note: The first feature in the list that is returned is the mapping to the feature that is
152+ // provided from the `s` parameter.
150153pub fn to_llvm_features < ' a > ( sess : & Session , s : & ' a str ) -> SmallVec < [ & ' a str ; 2 ] > {
151154 let arch = if sess. target . arch == "x86_64" { "x86" } else { & * sess. target . arch } ;
152155 match ( arch, s) {
@@ -182,6 +185,23 @@ pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]
182185 }
183186}
184187
188+ pub enum TargetFeatureFoldStrength {
189+ // The feature is only tied when enabling the feature, disabling
190+ // this feature shouldn't disable the tied feature.
191+ EnableOnly ,
192+ // The feature is tied for both enabling and disabling this feature.
193+ Both ,
194+ }
195+
196+ // Determines how the features are folded together, some features are
197+ // linked a lot more than some others.
198+ pub fn feature_fold_strength < ' a > ( feats : & SmallVec < [ & ' a str ; 2 ] > ) -> TargetFeatureFoldStrength {
199+ match ( feats. get ( 0 ) , feats. get ( 1 ) ) {
200+ ( Some ( & "neon" ) , Some ( & "fp-armv8" ) ) => TargetFeatureFoldStrength :: Both ,
201+ _ => TargetFeatureFoldStrength :: EnableOnly ,
202+ }
203+ }
204+
185205/// Given a map from target_features to whether they are enabled or disabled,
186206/// ensure only valid combinations are allowed.
187207pub fn check_tied_features (
@@ -471,11 +491,17 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
471491 // passing requests down to LLVM. This means that all in-language
472492 // features also work on the command line instead of having two
473493 // different names when the LLVM name and the Rust name differ.
474- Some (
475- to_llvm_features ( sess, feature)
476- . into_iter ( )
477- . map ( move |f| format ! ( "{}{}" , enable_disable, f) ) ,
478- )
494+ let llvm_features = to_llvm_features ( sess, feature) ;
495+ Some ( to_llvm_features ( sess, feature) . into_iter ( ) . enumerate ( ) . filter_map (
496+ move |( idx, f) | match ( enable_disable, feature_fold_strength ( & llvm_features) ) {
497+ ( '-' | '+' , TargetFeatureFoldStrength :: Both )
498+ | ( '+' , TargetFeatureFoldStrength :: EnableOnly ) => {
499+ Some ( format ! ( "{}{}" , enable_disable, f) )
500+ }
501+ _ if idx == 0 => Some ( format ! ( "{}{}" , enable_disable, f) ) ,
502+ _ => None ,
503+ } ,
504+ ) )
479505 } )
480506 . flatten ( ) ;
481507 features. extend ( feats) ;
0 commit comments