Skip to content

Commit

Permalink
Rollup merge of #99155 - Amanieu:unstable-target-features, r=davidtwco
Browse files Browse the repository at this point in the history
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
Dylan-DPC authored Jul 13, 2022
2 parents 980579a + dfe68ee commit 68cfdbb
Showing 10 changed files with 67 additions and 28 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_cranelift/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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![]
}

8 changes: 4 additions & 4 deletions compiler/rustc_codegen_gcc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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| {
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_llvm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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>(
39 changes: 21 additions & 18 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
@@ -233,26 +233,29 @@ 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)
.iter()
.filter_map(|&(feature, gate)| {
if sess.is_nightly_build() || gate.is_none() { Some(feature) } else { None }
})
.filter(|feature| {
// check that all features in a given smallvec are enabled
for llvm_feature in to_llvm_features(sess, feature) {
let cstr = SmallCStr::new(llvm_feature);
if !unsafe { llvm::LLVMRustHasFeature(target_machine, cstr.as_ptr()) } {
return false;
}
let mut features: Vec<Symbol> = supported_target_features(sess)
.iter()
.filter_map(|&(feature, gate)| {
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
for llvm_feature in to_llvm_features(sess, feature) {
let cstr = SmallCStr::new(llvm_feature);
if !unsafe { llvm::LLVMRustHasFeature(target_machine, cstr.as_ptr()) } {
return false;
}
true
})
.map(|feature| Symbol::intern(feature))
.collect();
}
true
})
.map(|feature| Symbol::intern(feature))
.collect();

// LLVM 14 changed the ABI for i128 arguments to __float/__fix builtins on Win64
// (see https://reviews.llvm.org/D110413). This unstable target feature is intended for use
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/traits/backend.rs
Original file line number Diff line number Diff line change
@@ -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) {}
5 changes: 4 additions & 1 deletion compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
@@ -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))));
4 changes: 4 additions & 0 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
@@ -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);
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/collect.rs
Original file line number Diff line number Diff line change
@@ -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);
21 changes: 21 additions & 0 deletions src/test/ui/asm/issue-99071.rs
Original file line number Diff line number Diff line change
@@ -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
}
}
8 changes: 8 additions & 0 deletions src/test/ui/asm/issue-99071.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 68cfdbb

Please sign in to comment.