Skip to content

Commit 68cfdbb

Browse files
authored
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
2 parents 980579a + dfe68ee commit 68cfdbb

File tree

10 files changed

+67
-28
lines changed

10 files changed

+67
-28
lines changed

compiler/rustc_codegen_cranelift/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
167167
}
168168
}
169169

170-
fn target_features(&self, _sess: &Session) -> Vec<rustc_span::Symbol> {
170+
fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<rustc_span::Symbol> {
171171
vec![]
172172
}
173173

compiler/rustc_codegen_gcc/src/lib.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,8 @@ impl CodegenBackend for GccCodegenBackend {
140140
)
141141
}
142142

143-
fn target_features(&self, sess: &Session) -> Vec<Symbol> {
144-
target_features(sess)
143+
fn target_features(&self, sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
144+
target_features(sess, allow_unstable)
145145
}
146146
}
147147

@@ -298,12 +298,12 @@ pub fn target_cpu(sess: &Session) -> &str {
298298
}
299299
}
300300

301-
pub fn target_features(sess: &Session) -> Vec<Symbol> {
301+
pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
302302
supported_target_features(sess)
303303
.iter()
304304
.filter_map(
305305
|&(feature, gate)| {
306-
if sess.is_nightly_build() || gate.is_none() { Some(feature) } else { None }
306+
if sess.is_nightly_build() || allow_unstable || gate.is_none() { Some(feature) } else { None }
307307
},
308308
)
309309
.filter(|_feature| {

compiler/rustc_codegen_llvm/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -324,8 +324,8 @@ impl CodegenBackend for LlvmCodegenBackend {
324324
llvm_util::print_version();
325325
}
326326

327-
fn target_features(&self, sess: &Session) -> Vec<Symbol> {
328-
target_features(sess)
327+
fn target_features(&self, sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
328+
target_features(sess, allow_unstable)
329329
}
330330

331331
fn codegen_crate<'tcx>(

compiler/rustc_codegen_llvm/src/llvm_util.rs

+21-18
Original file line numberDiff line numberDiff line change
@@ -233,26 +233,29 @@ pub fn check_tied_features(
233233

234234
// Used to generate cfg variables and apply features
235235
// Must express features in the way Rust understands them
236-
pub fn target_features(sess: &Session) -> Vec<Symbol> {
236+
pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
237237
let target_machine = create_informational_target_machine(sess);
238-
let mut features: Vec<Symbol> =
239-
supported_target_features(sess)
240-
.iter()
241-
.filter_map(|&(feature, gate)| {
242-
if sess.is_nightly_build() || gate.is_none() { Some(feature) } else { None }
243-
})
244-
.filter(|feature| {
245-
// check that all features in a given smallvec are enabled
246-
for llvm_feature in to_llvm_features(sess, feature) {
247-
let cstr = SmallCStr::new(llvm_feature);
248-
if !unsafe { llvm::LLVMRustHasFeature(target_machine, cstr.as_ptr()) } {
249-
return false;
250-
}
238+
let mut features: Vec<Symbol> = supported_target_features(sess)
239+
.iter()
240+
.filter_map(|&(feature, gate)| {
241+
if sess.is_nightly_build() || allow_unstable || gate.is_none() {
242+
Some(feature)
243+
} else {
244+
None
245+
}
246+
})
247+
.filter(|feature| {
248+
// check that all features in a given smallvec are enabled
249+
for llvm_feature in to_llvm_features(sess, feature) {
250+
let cstr = SmallCStr::new(llvm_feature);
251+
if !unsafe { llvm::LLVMRustHasFeature(target_machine, cstr.as_ptr()) } {
252+
return false;
251253
}
252-
true
253-
})
254-
.map(|feature| Symbol::intern(feature))
255-
.collect();
254+
}
255+
true
256+
})
257+
.map(|feature| Symbol::intern(feature))
258+
.collect();
256259

257260
// LLVM 14 changed the ABI for i128 arguments to __float/__fix builtins on Win64
258261
// (see https://reviews.llvm.org/D110413). This unstable target feature is intended for use

compiler/rustc_codegen_ssa/src/traits/backend.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ impl<'tcx, T> Backend<'tcx> for T where
5959
pub trait CodegenBackend {
6060
fn init(&self, _sess: &Session) {}
6161
fn print(&self, _req: PrintRequest, _sess: &Session) {}
62-
fn target_features(&self, _sess: &Session) -> Vec<Symbol> {
62+
fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<Symbol> {
6363
vec![]
6464
}
6565
fn print_passes(&self) {}

compiler/rustc_interface/src/util.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ pub fn add_configuration(
4848
) {
4949
let tf = sym::target_feature;
5050

51-
let target_features = codegen_backend.target_features(sess);
51+
let unstable_target_features = codegen_backend.target_features(sess, true);
52+
sess.unstable_target_features.extend(unstable_target_features.iter().cloned());
53+
54+
let target_features = codegen_backend.target_features(sess, false);
5255
sess.target_features.extend(target_features.iter().cloned());
5356

5457
cfg.extend(target_features.into_iter().map(|feat| (tf, Some(feat))));

compiler/rustc_session/src/session.rs

+4
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,9 @@ pub struct Session {
194194

195195
/// Set of enabled features for the current target.
196196
pub target_features: FxHashSet<Symbol>,
197+
198+
/// Set of enabled features for the current target, including unstable ones.
199+
pub unstable_target_features: FxHashSet<Symbol>,
197200
}
198201

199202
pub struct PerfStats {
@@ -1390,6 +1393,7 @@ pub fn build_session(
13901393
miri_unleashed_features: Lock::new(Default::default()),
13911394
asm_arch,
13921395
target_features: FxHashSet::default(),
1396+
unstable_target_features: FxHashSet::default(),
13931397
};
13941398

13951399
validate_commandline_args_with_session_available(&sess);

compiler/rustc_typeck/src/collect.rs

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

src/test/ui/asm/issue-99071.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// compile-flags: --target thumbv6m-none-eabi
2+
// needs-llvm-components: arm
3+
// needs-asm-support
4+
5+
#![feature(no_core, lang_items, rustc_attrs)]
6+
#![no_core]
7+
#![crate_type = "rlib"]
8+
9+
#[rustc_builtin_macro]
10+
macro_rules! asm {
11+
() => {};
12+
}
13+
#[lang = "sized"]
14+
trait Sized {}
15+
16+
pub fn foo() {
17+
unsafe {
18+
asm!("", in("r8") 0);
19+
//~^ cannot use register `r8`: high registers (r8+) can only be used as clobbers in Thumb-1 code
20+
}
21+
}

src/test/ui/asm/issue-99071.stderr

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

0 commit comments

Comments
 (0)