@@ -19,6 +19,7 @@ use rustc_session::config::{PrintKind, PrintRequest};
19
19
use rustc_span:: Symbol ;
20
20
use rustc_target:: spec:: { MergeFunctions , PanicStrategy , SmallDataThresholdSupport } ;
21
21
use rustc_target:: target_features:: { RUSTC_SPECIAL_FEATURES , RUSTC_SPECIFIC_FEATURES } ;
22
+ use smallvec:: { SmallVec , smallvec} ;
22
23
23
24
use crate :: back:: write:: create_informational_target_machine;
24
25
use crate :: errors:: {
@@ -180,27 +181,27 @@ impl<'a> TargetFeatureFoldStrength<'a> {
180
181
181
182
pub ( crate ) struct LLVMFeature < ' a > {
182
183
llvm_feature_name : & ' a str ,
183
- dependency : Option < TargetFeatureFoldStrength < ' a > > ,
184
+ dependencies : SmallVec < [ TargetFeatureFoldStrength < ' a > ; 1 ] > ,
184
185
}
185
186
186
187
impl < ' a > LLVMFeature < ' a > {
187
188
fn new ( llvm_feature_name : & ' a str ) -> Self {
188
- Self { llvm_feature_name, dependency : None }
189
+ Self { llvm_feature_name, dependencies : SmallVec :: new ( ) }
189
190
}
190
191
191
- fn with_dependency (
192
+ fn with_dependencies (
192
193
llvm_feature_name : & ' a str ,
193
- dependency : TargetFeatureFoldStrength < ' a > ,
194
+ dependencies : SmallVec < [ TargetFeatureFoldStrength < ' a > ; 1 ] > ,
194
195
) -> Self {
195
- Self { llvm_feature_name, dependency : Some ( dependency ) }
196
+ Self { llvm_feature_name, dependencies }
196
197
}
197
198
198
- fn contains ( & self , feat : & str ) -> bool {
199
+ fn contains ( & ' a self , feat : & str ) -> bool {
199
200
self . iter ( ) . any ( |dep| dep == feat)
200
201
}
201
202
202
203
fn iter ( & ' a self ) -> impl Iterator < Item = & ' a str > {
203
- let dependencies = self . dependency . iter ( ) . map ( |feat| feat. as_str ( ) ) ;
204
+ let dependencies = self . dependencies . iter ( ) . map ( |feat| feat. as_str ( ) ) ;
204
205
std:: iter:: once ( self . llvm_feature_name ) . chain ( dependencies)
205
206
}
206
207
}
@@ -210,7 +211,7 @@ impl<'a> IntoIterator for LLVMFeature<'a> {
210
211
type IntoIter = impl Iterator < Item = & ' a str > ;
211
212
212
213
fn into_iter ( self ) -> Self :: IntoIter {
213
- let dependencies = self . dependency . into_iter ( ) . map ( |feat| feat. as_str ( ) ) ;
214
+ let dependencies = self . dependencies . into_iter ( ) . map ( |feat| feat. as_str ( ) ) ;
214
215
std:: iter:: once ( self . llvm_feature_name ) . chain ( dependencies)
215
216
}
216
217
}
@@ -240,9 +241,9 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
240
241
& * sess. target . arch
241
242
} ;
242
243
match ( arch, s) {
243
- ( "x86" , "sse4.2" ) => Some ( LLVMFeature :: with_dependency (
244
+ ( "x86" , "sse4.2" ) => Some ( LLVMFeature :: with_dependencies (
244
245
"sse4.2" ,
245
- TargetFeatureFoldStrength :: EnableOnly ( "crc32" ) ,
246
+ smallvec ! [ TargetFeatureFoldStrength :: EnableOnly ( "crc32" ) ] ,
246
247
) ) ,
247
248
( "x86" , "pclmulqdq" ) => Some ( LLVMFeature :: new ( "pclmul" ) ) ,
248
249
( "x86" , "rdrand" ) => Some ( LLVMFeature :: new ( "rdrnd" ) ) ,
@@ -262,9 +263,10 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
262
263
( "aarch64" , "sme-b16b16" ) if get_version ( ) . 0 < 20 => Some ( LLVMFeature :: new ( "b16b16" ) ) ,
263
264
( "aarch64" , "flagm2" ) => Some ( LLVMFeature :: new ( "altnzcv" ) ) ,
264
265
// Rust ties fp and neon together.
265
- ( "aarch64" , "neon" ) => {
266
- Some ( LLVMFeature :: with_dependency ( "neon" , TargetFeatureFoldStrength :: Both ( "fp-armv8" ) ) )
267
- }
266
+ ( "aarch64" , "neon" ) => Some ( LLVMFeature :: with_dependencies (
267
+ "neon" ,
268
+ smallvec ! [ TargetFeatureFoldStrength :: Both ( "fp-armv8" ) ] ,
269
+ ) ) ,
268
270
// In LLVM neon implicitly enables fp, but we manually enable
269
271
// neon when a feature only implicitly enables fp
270
272
( "aarch64" , "fhm" ) => Some ( LLVMFeature :: new ( "fp16fml" ) ) ,
@@ -281,9 +283,10 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
281
283
// Filter out features that are not supported by the current LLVM version
282
284
( "riscv32" | "riscv64" , "zacas" ) if get_version ( ) . 0 < 20 => None ,
283
285
// Enable the evex512 target feature if an avx512 target feature is enabled.
284
- ( "x86" , s) if s. starts_with ( "avx512" ) => {
285
- Some ( LLVMFeature :: with_dependency ( s, TargetFeatureFoldStrength :: EnableOnly ( "evex512" ) ) )
286
- }
286
+ ( "x86" , s) if s. starts_with ( "avx512" ) => Some ( LLVMFeature :: with_dependencies (
287
+ s,
288
+ smallvec ! [ TargetFeatureFoldStrength :: EnableOnly ( "evex512" ) ] ,
289
+ ) ) ,
287
290
// Support for `wide-arithmetic` will first land in LLVM 20 as part of
288
291
// llvm/llvm-project#111598
289
292
( "wasm32" | "wasm64" , "wide-arithmetic" ) if get_version ( ) < ( 20 , 0 , 0 ) => None ,
@@ -304,6 +307,18 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
304
307
( "x86" , "avx10.1" ) => Some ( LLVMFeature :: new ( "avx10.1-512" ) ) ,
305
308
( "x86" , "avx10.2" ) if get_version ( ) . 0 < 20 => None ,
306
309
( "x86" , "avx10.2" ) if get_version ( ) . 0 >= 20 => Some ( LLVMFeature :: new ( "avx10.2-512" ) ) ,
310
+ ( "x86" , "apxf" ) => Some ( LLVMFeature :: with_dependencies (
311
+ "egpr" ,
312
+ smallvec ! [
313
+ TargetFeatureFoldStrength :: Both ( "push2pop2" ) ,
314
+ TargetFeatureFoldStrength :: Both ( "ppx" ) ,
315
+ TargetFeatureFoldStrength :: Both ( "ndd" ) ,
316
+ TargetFeatureFoldStrength :: Both ( "ccmp" ) ,
317
+ TargetFeatureFoldStrength :: Both ( "cf" ) ,
318
+ TargetFeatureFoldStrength :: Both ( "nf" ) ,
319
+ TargetFeatureFoldStrength :: Both ( "zu" ) ,
320
+ ] ,
321
+ ) ) ,
307
322
( _, s) => Some ( LLVMFeature :: new ( s) ) ,
308
323
}
309
324
}
@@ -853,7 +868,7 @@ pub(crate) fn global_llvm_features(
853
868
"{}{}" ,
854
869
enable_disable, llvm_feature. llvm_feature_name
855
870
) )
856
- . chain ( llvm_feature. dependency . into_iter ( ) . filter_map (
871
+ . chain ( llvm_feature. dependencies . into_iter ( ) . filter_map (
857
872
move |feat| match ( enable, feat) {
858
873
( _, TargetFeatureFoldStrength :: Both ( f) )
859
874
| ( true , TargetFeatureFoldStrength :: EnableOnly ( f) ) => {
0 commit comments