about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2022-07-13 19:32:36 +0530
committerGitHub <noreply@github.com>2022-07-13 19:32:36 +0530
commit68cfdbb5c1a6f5c7d796df65701edfd0abee89f4 (patch)
treefeec2d8fddb9c59fcc2018d9cca71399b6eacb59
parent980579a5e9f5fcad63ef71f536efec15ccd56511 (diff)
parentdfe68eede3cef45c8a420aeb8ab4a57426662e04 (diff)
downloadrust-68cfdbb5c1a6f5c7d796df65701edfd0abee89f4.tar.gz
rust-68cfdbb5c1a6f5c7d796df65701edfd0abee89f4.zip
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
-rw-r--r--compiler/rustc_codegen_cranelift/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/lib.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs39
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/backend.rs2
-rw-r--r--compiler/rustc_interface/src/util.rs5
-rw-r--r--compiler/rustc_session/src/session.rs4
-rw-r--r--compiler/rustc_typeck/src/collect.rs2
-rw-r--r--src/test/ui/asm/issue-99071.rs21
-rw-r--r--src/test/ui/asm/issue-99071.stderr8
10 files changed, 67 insertions, 28 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs
index be2d3108c5f..3ed3453c6c7 100644
--- a/compiler/rustc_codegen_cranelift/src/lib.rs
+++ b/compiler/rustc_codegen_cranelift/src/lib.rs
@@ -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![]
     }
 
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index 399830de84c..c21e0c5a35b 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -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| {
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index a7dd8e16d28..fb196ee9f5d 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -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>(
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index ce6c6e3215c..5b3b7db12b7 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -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
diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs
index 1e53c73d1bb..779bd3ea278 100644
--- a/compiler/rustc_codegen_ssa/src/traits/backend.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs
@@ -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) {}
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 8796ad5a33c..f4b51b5a442 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -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))));
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 1cccef2f64f..16f4a099d80 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -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);
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 44b9c8392f8..9795be1a912 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -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);
diff --git a/src/test/ui/asm/issue-99071.rs b/src/test/ui/asm/issue-99071.rs
new file mode 100644
index 00000000000..bb6201861df
--- /dev/null
+++ b/src/test/ui/asm/issue-99071.rs
@@ -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
+    }
+}
diff --git a/src/test/ui/asm/issue-99071.stderr b/src/test/ui/asm/issue-99071.stderr
new file mode 100644
index 00000000000..47386ffa4a8
--- /dev/null
+++ b/src/test/ui/asm/issue-99071.stderr
@@ -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
+