@@ -166,25 +166,32 @@ pub fn time_trace_profiler_finish(file_name: &str) {
166
166
// Though note that Rust can also be build with an external precompiled version of LLVM
167
167
// which might lead to failures if the oldest tested / supported LLVM version
168
168
// doesn't yet support the relevant intrinsics
169
- pub fn to_llvm_feature < ' a > ( sess : & Session , s : & ' a str ) -> & ' a str {
169
+ pub fn to_llvm_feature < ' a > ( sess : & Session , s : & ' a str ) -> Vec < & ' a str > {
170
170
let arch = if sess. target . arch == "x86_64" { "x86" } else { & * sess. target . arch } ;
171
171
match ( arch, s) {
172
- ( "x86" , "pclmulqdq" ) => "pclmul" ,
173
- ( "x86" , "rdrand" ) => "rdrnd" ,
174
- ( "x86" , "bmi1" ) => "bmi" ,
175
- ( "x86" , "cmpxchg16b" ) => "cx16" ,
176
- ( "x86" , "avx512vaes" ) => "vaes" ,
177
- ( "x86" , "avx512gfni" ) => "gfni" ,
178
- ( "x86" , "avx512vpclmulqdq" ) => "vpclmulqdq" ,
179
- ( "aarch64" , "fp" ) => "fp-armv8" ,
180
- ( "aarch64" , "fp16" ) => "fullfp16" ,
181
- ( "aarch64" , "fhm" ) => "fp16fml" ,
182
- ( "aarch64" , "rcpc2" ) => "rcpc-immo" ,
183
- ( "aarch64" , "dpb" ) => "ccpp" ,
184
- ( "aarch64" , "dpb2" ) => "ccdp" ,
185
- ( "aarch64" , "frintts" ) => "fptoint" ,
186
- ( "aarch64" , "fcma" ) => "complxnum" ,
187
- ( _, s) => s,
172
+ ( "x86" , "sse4.2" ) => {
173
+ if get_version ( ) >= ( 14 , 0 , 0 ) {
174
+ vec ! [ "sse4.2" , "crc32" ]
175
+ } else {
176
+ vec ! [ "sse4.2" ]
177
+ }
178
+ }
179
+ ( "x86" , "pclmulqdq" ) => vec ! [ "pclmul" ] ,
180
+ ( "x86" , "rdrand" ) => vec ! [ "rdrnd" ] ,
181
+ ( "x86" , "bmi1" ) => vec ! [ "bmi" ] ,
182
+ ( "x86" , "cmpxchg16b" ) => vec ! [ "cx16" ] ,
183
+ ( "x86" , "avx512vaes" ) => vec ! [ "vaes" ] ,
184
+ ( "x86" , "avx512gfni" ) => vec ! [ "gfni" ] ,
185
+ ( "x86" , "avx512vpclmulqdq" ) => vec ! [ "vpclmulqdq" ] ,
186
+ ( "aarch64" , "fp" ) => vec ! [ "fp-armv8" ] ,
187
+ ( "aarch64" , "fp16" ) => vec ! [ "fullfp16" ] ,
188
+ ( "aarch64" , "fhm" ) => vec ! [ "fp16fml" ] ,
189
+ ( "aarch64" , "rcpc2" ) => vec ! [ "rcpc-immo" ] ,
190
+ ( "aarch64" , "dpb" ) => vec ! [ "ccpp" ] ,
191
+ ( "aarch64" , "dpb2" ) => vec ! [ "ccdp" ] ,
192
+ ( "aarch64" , "frintts" ) => vec ! [ "fptoint" ] ,
193
+ ( "aarch64" , "fcma" ) => vec ! [ "complxnum" ] ,
194
+ ( _, s) => vec ! [ s] ,
188
195
}
189
196
}
190
197
@@ -198,9 +205,13 @@ pub fn target_features(sess: &Session) -> Vec<Symbol> {
198
205
} ,
199
206
)
200
207
. filter ( |feature| {
201
- let llvm_feature = to_llvm_feature ( sess, feature) ;
202
- let cstr = CString :: new ( llvm_feature) . unwrap ( ) ;
203
- unsafe { llvm:: LLVMRustHasFeature ( target_machine, cstr. as_ptr ( ) ) }
208
+ for llvm_feature in to_llvm_feature ( sess, feature) {
209
+ let cstr = CString :: new ( llvm_feature) . unwrap ( ) ;
210
+ if unsafe { llvm:: LLVMRustHasFeature ( target_machine, cstr. as_ptr ( ) ) } {
211
+ return true ;
212
+ }
213
+ }
214
+ false
204
215
} )
205
216
. map ( |feature| Symbol :: intern ( feature) )
206
217
. collect ( )
@@ -253,12 +264,19 @@ fn print_target_features(sess: &Session, tm: &llvm::TargetMachine) {
253
264
let mut rustc_target_features = supported_target_features ( sess)
254
265
. iter ( )
255
266
. filter_map ( |( feature, _gate) | {
256
- let llvm_feature = to_llvm_feature ( sess, * feature) ;
257
- // LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these strings.
258
- target_features. binary_search_by_key ( & llvm_feature, |( f, _d) | * f) . ok ( ) . map ( |index| {
259
- let ( _f, desc) = target_features. remove ( index) ;
260
- ( * feature, desc)
261
- } )
267
+ for llvm_feature in to_llvm_feature ( sess, * feature) {
268
+ // LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these strings.
269
+ match target_features. binary_search_by_key ( & llvm_feature, |( f, _d) | ( * f) ) . ok ( ) . map (
270
+ |index| {
271
+ let ( _f, desc) = target_features. remove ( index) ;
272
+ ( * feature, desc)
273
+ } ,
274
+ ) {
275
+ Some ( v) => return Some ( v) ,
276
+ None => { }
277
+ }
278
+ }
279
+ None
262
280
} )
263
281
. collect :: < Vec < _ > > ( ) ;
264
282
rustc_target_features. extend_from_slice ( & [ (
@@ -373,30 +391,30 @@ pub fn llvm_global_features(sess: &Session) -> Vec<String> {
373
391
374
392
let filter = |s : & str | {
375
393
if s. is_empty ( ) {
376
- return None ;
394
+ return vec ! [ ] ;
377
395
}
378
396
let feature = if s. starts_with ( '+' ) || s. starts_with ( '-' ) {
379
397
& s[ 1 ..]
380
398
} else {
381
- return Some ( s. to_string ( ) ) ;
399
+ return vec ! [ s. to_string( ) ] ;
382
400
} ;
383
401
// Rustc-specific feature requests like `+crt-static` or `-crt-static`
384
402
// are not passed down to LLVM.
385
403
if RUSTC_SPECIFIC_FEATURES . contains ( & feature) {
386
- return None ;
404
+ return vec ! [ ] ;
387
405
}
388
406
// ... otherwise though we run through `to_llvm_feature` feature when
389
407
// passing requests down to LLVM. This means that all in-language
390
408
// features also work on the command line instead of having two
391
409
// different names when the LLVM name and the Rust name differ.
392
- Some ( format ! ( "{}{}" , & s[ ..1 ] , to_llvm_feature ( sess , feature ) ) )
410
+ to_llvm_feature ( sess , feature ) . iter ( ) . map ( |f| format ! ( "{}{}" , & s[ ..1 ] , f ) ) . collect ( )
393
411
} ;
394
412
395
413
// Features implied by an implicit or explicit `--target`.
396
- features. extend ( sess. target . features . split ( ',' ) . filter_map ( & filter) ) ;
414
+ features. extend ( sess. target . features . split ( ',' ) . flat_map ( & filter) ) ;
397
415
398
416
// -Ctarget-features
399
- features. extend ( sess. opts . cg . target_feature . split ( ',' ) . filter_map ( & filter) ) ;
417
+ features. extend ( sess. opts . cg . target_feature . split ( ',' ) . flat_map ( & filter) ) ;
400
418
401
419
features
402
420
}
0 commit comments