Rollup merge of #99155 - Amanieu:unstable-target-features, r=davidtwco

Keep unstable target features for asm feature checking

Inline assembly uses the target features to determine which registers
are available on the current target. However it needs to be able to
access unstable target features for this.

Fixes #99071
This commit is contained in:
Dylan DPC 2022-07-13 19:32:36 +05:30 committed by GitHub
commit 68cfdbb5c1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 67 additions and 28 deletions

View file

@ -167,7 +167,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
}
}
fn target_features(&self, _sess: &Session) -> Vec<rustc_span::Symbol> {
fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<rustc_span::Symbol> {
vec![]
}

View file

@ -140,8 +140,8 @@ impl CodegenBackend for GccCodegenBackend {
)
}
fn target_features(&self, sess: &Session) -> Vec<Symbol> {
target_features(sess)
fn target_features(&self, sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
target_features(sess, allow_unstable)
}
}
@ -298,12 +298,12 @@ pub fn target_cpu(sess: &Session) -> &str {
}
}
pub fn target_features(sess: &Session) -> Vec<Symbol> {
pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
supported_target_features(sess)
.iter()
.filter_map(
|&(feature, gate)| {
if sess.is_nightly_build() || gate.is_none() { Some(feature) } else { None }
if sess.is_nightly_build() || allow_unstable || gate.is_none() { Some(feature) } else { None }
},
)
.filter(|_feature| {

View file

@ -324,8 +324,8 @@ impl CodegenBackend for LlvmCodegenBackend {
llvm_util::print_version();
}
fn target_features(&self, sess: &Session) -> Vec<Symbol> {
target_features(sess)
fn target_features(&self, sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
target_features(sess, allow_unstable)
}
fn codegen_crate<'tcx>(

View file

@ -233,13 +233,16 @@ pub fn check_tied_features(
// Used to generate cfg variables and apply features
// Must express features in the way Rust understands them
pub fn target_features(sess: &Session) -> Vec<Symbol> {
pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
let target_machine = create_informational_target_machine(sess);
let mut features: Vec<Symbol> =
supported_target_features(sess)
let mut features: Vec<Symbol> = supported_target_features(sess)
.iter()
.filter_map(|&(feature, gate)| {
if sess.is_nightly_build() || gate.is_none() { Some(feature) } else { None }
if sess.is_nightly_build() || allow_unstable || gate.is_none() {
Some(feature)
} else {
None
}
})
.filter(|feature| {
// check that all features in a given smallvec are enabled

View file

@ -59,7 +59,7 @@ impl<'tcx, T> Backend<'tcx> for T where
pub trait CodegenBackend {
fn init(&self, _sess: &Session) {}
fn print(&self, _req: PrintRequest, _sess: &Session) {}
fn target_features(&self, _sess: &Session) -> Vec<Symbol> {
fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<Symbol> {
vec![]
}
fn print_passes(&self) {}

View file

@ -48,7 +48,10 @@ pub fn add_configuration(
) {
let tf = sym::target_feature;
let target_features = codegen_backend.target_features(sess);
let unstable_target_features = codegen_backend.target_features(sess, true);
sess.unstable_target_features.extend(unstable_target_features.iter().cloned());
let target_features = codegen_backend.target_features(sess, false);
sess.target_features.extend(target_features.iter().cloned());
cfg.extend(target_features.into_iter().map(|feat| (tf, Some(feat))));

View file

@ -194,6 +194,9 @@ pub struct Session {
/// Set of enabled features for the current target.
pub target_features: FxHashSet<Symbol>,
/// Set of enabled features for the current target, including unstable ones.
pub unstable_target_features: FxHashSet<Symbol>,
}
pub struct PerfStats {
@ -1390,6 +1393,7 @@ pub fn build_session(
miri_unleashed_features: Lock::new(Default::default()),
asm_arch,
target_features: FxHashSet::default(),
unstable_target_features: FxHashSet::default(),
};
validate_commandline_args_with_session_available(&sess);

View file

@ -3196,7 +3196,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
/// Computes the set of target features used in a function for the purposes of
/// inline assembly.
fn asm_target_features<'tcx>(tcx: TyCtxt<'tcx>, did: DefId) -> &'tcx FxHashSet<Symbol> {
let mut target_features = tcx.sess.target_features.clone();
let mut target_features = tcx.sess.unstable_target_features.clone();
if tcx.def_kind(did).has_codegen_attrs() {
let attrs = tcx.codegen_fn_attrs(did);
target_features.extend(&attrs.target_features);

View file

@ -0,0 +1,21 @@
// compile-flags: --target thumbv6m-none-eabi
// needs-llvm-components: arm
// needs-asm-support
#![feature(no_core, lang_items, rustc_attrs)]
#![no_core]
#![crate_type = "rlib"]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[lang = "sized"]
trait Sized {}
pub fn foo() {
unsafe {
asm!("", in("r8") 0);
//~^ cannot use register `r8`: high registers (r8+) can only be used as clobbers in Thumb-1 code
}
}

View file

@ -0,0 +1,8 @@
error: cannot use register `r8`: high registers (r8+) can only be used as clobbers in Thumb-1 code
--> $DIR/issue-99071.rs:18:18
|
LL | asm!("", in("r8") 0);
| ^^^^^^^^^^
error: aborting due to previous error