@@ -147,6 +147,9 @@ pub fn time_trace_profiler_finish(file_name: &Path) {
147
147
// Though note that Rust can also be build with an external precompiled version of LLVM
148
148
// which might lead to failures if the oldest tested / supported LLVM version
149
149
// 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.
150
153
pub fn to_llvm_features < ' a > ( sess : & Session , s : & ' a str ) -> SmallVec < [ & ' a str ; 2 ] > {
151
154
let arch = if sess. target . arch == "x86_64" { "x86" } else { & * sess. target . arch } ;
152
155
match ( arch, s) {
@@ -182,6 +185,23 @@ pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]
182
185
}
183
186
}
184
187
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
+
185
205
/// Given a map from target_features to whether they are enabled or disabled,
186
206
/// ensure only valid combinations are allowed.
187
207
pub fn check_tied_features (
@@ -471,11 +491,17 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
471
491
// passing requests down to LLVM. This means that all in-language
472
492
// features also work on the command line instead of having two
473
493
// 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
+ ) )
479
505
} )
480
506
. flatten ( ) ;
481
507
features. extend ( feats) ;
0 commit comments