Skip to content

Commit c001598

Browse files
authored
Rollup merge of rust-lang#84991 - alexcrichton:target-feature-remap, r=nagisa
rustc: Support Rust-specific features in -Ctarget-feature Since the beginning of time the `-Ctarget-feature` flag on the command line has largely been passed unmodified to LLVM. Afterwards, though, the `#[target_feature]` attribute was stabilized and some of the names in this attribute do not match the corresponding LLVM name. This is because Rust doesn't always want to stabilize the exact feature name in LLVM for the equivalent functionality in Rust. This creates a situation, however, where in Rust you'd write: #[target_feature(enable = "pclmulqdq")] unsafe fn foo() { // ... } but on the command line you would write: RUSTFLAGS="-Ctarget-feature=+pclmul" cargo build --release This difference is somewhat odd to deal with if you're a newcomer and the situation may be made worse with upcoming features like [WebAssembly SIMD](rust-lang#74372) which may be more prevalent. This commit implements a mapping to translate requests via `-Ctarget-feature` through the same name-mapping functionality that's present for attributes in Rust going to LLVM. This means that `+pclmulqdq` will work on x86 targets where as previously it did not. I've attempted to keep this backwards-compatible where the compiler will just opportunistically attempt to remap features found in `-Ctarget-feature`, but if there's something it doesn't understand it gets passed unmodified to LLVM just as it was before.
2 parents e33bcf1 + 97658e5 commit c001598

File tree

2 files changed

+28
-15
lines changed

2 files changed

+28
-15
lines changed

compiler/rustc_codegen_llvm/src/llvm_util.rs

+23-15
Original file line numberDiff line numberDiff line change
@@ -339,24 +339,32 @@ pub fn llvm_global_features(sess: &Session) -> Vec<String> {
339339
Some(_) | None => {}
340340
};
341341

342+
let filter = |s: &str| {
343+
if s.is_empty() {
344+
return None;
345+
}
346+
let feature = if s.starts_with("+") || s.starts_with("-") {
347+
&s[1..]
348+
} else {
349+
return Some(s.to_string());
350+
};
351+
// Rustc-specific feature requests like `+crt-static` or `-crt-static`
352+
// are not passed down to LLVM.
353+
if RUSTC_SPECIFIC_FEATURES.contains(&feature) {
354+
return None;
355+
}
356+
// ... otherwise though we run through `to_llvm_feature` feature when
357+
// passing requests down to LLVM. This means that all in-language
358+
// features also work on the command line instead of having two
359+
// different names when the LLVM name and the Rust name differ.
360+
Some(format!("{}{}", &s[..1], to_llvm_feature(sess, feature)))
361+
};
362+
342363
// Features implied by an implicit or explicit `--target`.
343-
features.extend(
344-
sess.target
345-
.features
346-
.split(',')
347-
.filter(|f| !f.is_empty() && !RUSTC_SPECIFIC_FEATURES.iter().any(|s| f.contains(s)))
348-
.map(String::from),
349-
);
364+
features.extend(sess.target.features.split(',').filter_map(&filter));
350365

351366
// -Ctarget-features
352-
features.extend(
353-
sess.opts
354-
.cg
355-
.target_feature
356-
.split(',')
357-
.filter(|f| !f.is_empty() && !RUSTC_SPECIFIC_FEATURES.iter().any(|s| f.contains(s)))
358-
.map(String::from),
359-
);
367+
features.extend(sess.opts.cg.target_feature.split(',').filter_map(&filter));
360368

361369
features
362370
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// build-pass
2+
// only-x86
3+
// compile-flags: -C target-feature=+pclmulqdq
4+
5+
fn main() {}

0 commit comments

Comments
 (0)