about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-10-05 19:32:38 +0000
committerbors <bors@rust-lang.org>2024-10-05 19:32:38 +0000
commit9096f4fafa2ac2d771f866337b4ee7064cde8575 (patch)
tree306347b3a41d8f5d001daf88cb069dabc8c00a6f
parent2b21f90d5efb8b76f9016dd88cf6f3c04216c33b (diff)
parent6a85c32f55fce74987cb600f23d609bda2360efe (diff)
downloadrust-9096f4fafa2ac2d771f866337b4ee7064cde8575.tar.gz
rust-9096f4fafa2ac2d771f866337b4ee7064cde8575.zip
Auto merge of #131302 - matthiaskrgr:rollup-56kbpzx, r=matthiaskrgr
Rollup of 5 pull requests

Successful merges:

 - #130555 ( Initial support for riscv32{e|em|emc}_unknown_none_elf)
 - #131280 (Handle `rustc_interface` cases of `rustc::potential_query_instability` lint)
 - #131281 (make Cell unstably const)
 - #131285 (clarify semantics of ConstantIndex MIR projection)
 - #131299 (fix typo in 'lang item with track_caller' message)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_interface/src/passes.rs1
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs6
-rw-r--r--compiler/rustc_passes/messages.ftl2
-rw-r--r--compiler/rustc_target/src/spec/mod.rs4
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32e_unknown_none_elf.rs34
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32em_unknown_none_elf.rs34
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32emc_unknown_none_elf.rs34
-rw-r--r--compiler/stable_mir/src/mir/body.rs6
-rw-r--r--library/core/src/cell.rs18
-rw-r--r--src/bootstrap/src/core/sanity.rs3
-rw-r--r--src/doc/rustc/src/platform-support.md3
-rw-r--r--src/doc/rustc/src/platform-support/riscv32-unknown-none-elf.md2
-rw-r--r--src/doc/rustc/src/platform-support/riscv32e-unknown-none-elf.md30
-rw-r--r--tests/assembly/targets/targets-elf.rs9
-rw-r--r--tests/ui/abi/riscv32e-registers.riscv32e.stderr194
-rw-r--r--tests/ui/abi/riscv32e-registers.riscv32em.stderr194
-rw-r--r--tests/ui/abi/riscv32e-registers.riscv32emc.stderr194
-rw-r--r--tests/ui/abi/riscv32e-registers.rs91
-rw-r--r--tests/ui/panic-handler/panic-handler-with-track-caller.stderr2
19 files changed, 847 insertions, 14 deletions
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 204ae437a3e..fd850d2f39a 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -470,7 +470,6 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P
             })
         }
 
-        #[allow(rustc::potential_query_instability)]
         let extra_tracked_files = hash_iter_files(
             file_depinfo.iter().map(|path_sym| normalize_path(PathBuf::from(path_sym.as_str()))),
             checksum_hash_algo,
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index ae75f2d4187..1722a7a1f35 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1135,8 +1135,10 @@ pub enum ProjectionElem<V, T> {
     ConstantIndex {
         /// index or -index (in Python terms), depending on from_end
         offset: u64,
-        /// The thing being indexed must be at least this long. For arrays this
-        /// is always the exact length.
+        /// The thing being indexed must be at least this long -- otherwise, the
+        /// projection is UB.
+        ///
+        /// For arrays this is always the exact length.
         min_length: u64,
         /// Counting backwards from end? This is always false when indexing an
         /// array.
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 5369f54afb9..f2682acf8aa 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -391,7 +391,7 @@ passes_lang_item_fn_with_target_feature =
 
 passes_lang_item_fn_with_track_caller =
     {passes_lang_item_fn} is not allowed to have `#[track_caller]`
-    .label = {passes_lang_item_fn} is not allowed to have `#[target_feature]`
+    .label = {passes_lang_item_fn} is not allowed to have `#[track_caller]`
 
 passes_lang_item_on_incorrect_target =
     `{$name}` lang item must be applied to a {$expected_target}
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 18ec8ee9476..82e11a3afce 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1841,6 +1841,10 @@ supported_targets! {
     ("riscv32imac-esp-espidf", riscv32imac_esp_espidf),
     ("riscv32imafc-esp-espidf", riscv32imafc_esp_espidf),
 
+    ("riscv32e-unknown-none-elf", riscv32e_unknown_none_elf),
+    ("riscv32em-unknown-none-elf", riscv32em_unknown_none_elf),
+    ("riscv32emc-unknown-none-elf", riscv32emc_unknown_none_elf),
+
     ("riscv32imac-unknown-none-elf", riscv32imac_unknown_none_elf),
     ("riscv32imafc-unknown-none-elf", riscv32imafc_unknown_none_elf),
     ("riscv32imac-unknown-xous-elf", riscv32imac_unknown_xous_elf),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32e_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32e_unknown_none_elf.rs
new file mode 100644
index 00000000000..b1f52973c10
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/riscv32e_unknown_none_elf.rs
@@ -0,0 +1,34 @@
+use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
+
+pub(crate) fn target() -> Target {
+    Target {
+        // The below `data_layout` is explicitly specified by the ilp32e ABI in LLVM. See also
+        // `options.llvm_abiname`.
+        data_layout: "e-m:e-p:32:32-i64:64-n32-S32".into(),
+        llvm_target: "riscv32".into(),
+        metadata: crate::spec::TargetMetadata {
+            description: Some("Bare RISC-V (RV32E ISA)".into()),
+            tier: Some(3),
+            host_tools: Some(false),
+            std: Some(false),
+        },
+        pointer_width: 32,
+        arch: "riscv32".into(),
+
+        options: TargetOptions {
+            linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
+            linker: Some("rust-lld".into()),
+            cpu: "generic-rv32".into(),
+            // The ilp32e ABI specifies the `data_layout`
+            llvm_abiname: "ilp32e".into(),
+            max_atomic_width: Some(32),
+            atomic_cas: false,
+            features: "+e,+forced-atomics".into(),
+            panic_strategy: PanicStrategy::Abort,
+            relocation_model: RelocModel::Static,
+            emit_debug_gdb_scripts: false,
+            eh_frame_header: false,
+            ..Default::default()
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/targets/riscv32em_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32em_unknown_none_elf.rs
new file mode 100644
index 00000000000..feeaa48778d
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/riscv32em_unknown_none_elf.rs
@@ -0,0 +1,34 @@
+use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
+
+pub(crate) fn target() -> Target {
+    Target {
+        // The below `data_layout` is explicitly specified by the ilp32e ABI in LLVM. See also
+        // `options.llvm_abiname`.
+        data_layout: "e-m:e-p:32:32-i64:64-n32-S32".into(),
+        llvm_target: "riscv32".into(),
+        metadata: crate::spec::TargetMetadata {
+            description: Some("Bare RISC-V (RV32EM ISA)".into()),
+            tier: Some(3),
+            host_tools: Some(false),
+            std: Some(false),
+        },
+        pointer_width: 32,
+        arch: "riscv32".into(),
+
+        options: TargetOptions {
+            linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
+            linker: Some("rust-lld".into()),
+            cpu: "generic-rv32".into(),
+            // The ilp32e ABI specifies the `data_layout`
+            llvm_abiname: "ilp32e".into(),
+            max_atomic_width: Some(32),
+            atomic_cas: false,
+            features: "+e,+m,+forced-atomics".into(),
+            panic_strategy: PanicStrategy::Abort,
+            relocation_model: RelocModel::Static,
+            emit_debug_gdb_scripts: false,
+            eh_frame_header: false,
+            ..Default::default()
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/targets/riscv32emc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32emc_unknown_none_elf.rs
new file mode 100644
index 00000000000..45d73c13233
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/riscv32emc_unknown_none_elf.rs
@@ -0,0 +1,34 @@
+use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
+
+pub(crate) fn target() -> Target {
+    Target {
+        // The below `data_layout` is explicitly specified by the ilp32e ABI in LLVM. See also
+        // `options.llvm_abiname`.
+        data_layout: "e-m:e-p:32:32-i64:64-n32-S32".into(),
+        llvm_target: "riscv32".into(),
+        metadata: crate::spec::TargetMetadata {
+            description: Some("Bare RISC-V (RV32EMC ISA)".into()),
+            tier: Some(3),
+            host_tools: Some(false),
+            std: Some(false),
+        },
+        pointer_width: 32,
+        arch: "riscv32".into(),
+
+        options: TargetOptions {
+            linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
+            linker: Some("rust-lld".into()),
+            cpu: "generic-rv32".into(),
+            // The ilp32e ABI specifies the `data_layout`
+            llvm_abiname: "ilp32e".into(),
+            max_atomic_width: Some(32),
+            atomic_cas: false,
+            features: "+e,+m,+c,+forced-atomics".into(),
+            panic_strategy: PanicStrategy::Abort,
+            relocation_model: RelocModel::Static,
+            emit_debug_gdb_scripts: false,
+            eh_frame_header: false,
+            ..Default::default()
+        },
+    }
+}
diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs
index 9f4db7e4833..742469a1c93 100644
--- a/compiler/stable_mir/src/mir/body.rs
+++ b/compiler/stable_mir/src/mir/body.rs
@@ -768,8 +768,10 @@ pub enum ProjectionElem {
     ConstantIndex {
         /// index or -index (in Python terms), depending on from_end
         offset: u64,
-        /// The thing being indexed must be at least this long. For arrays this
-        /// is always the exact length.
+        /// The thing being indexed must be at least this long -- otherwise, the
+        /// projection is UB.
+        ///
+        /// For arrays this is always the exact length.
         min_length: u64,
         /// Counting backwards from end? This is always false when indexing an
         /// array.
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 690d4395137..95cf55a923e 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -494,8 +494,9 @@ impl<T> Cell<T> {
     /// ```
     #[inline]
     #[stable(feature = "move_cell", since = "1.17.0")]
+    #[rustc_const_unstable(feature = "const_cell", issue = "131283")]
     #[rustc_confusables("swap")]
-    pub fn replace(&self, val: T) -> T {
+    pub const fn replace(&self, val: T) -> T {
         // SAFETY: This can cause data races if called from a separate thread,
         // but `Cell` is `!Sync` so this won't happen.
         mem::replace(unsafe { &mut *self.value.get() }, val)
@@ -535,7 +536,8 @@ impl<T: Copy> Cell<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn get(&self) -> T {
+    #[rustc_const_unstable(feature = "const_cell", issue = "131283")]
+    pub const fn get(&self) -> T {
         // SAFETY: This can cause data races if called from a separate thread,
         // but `Cell` is `!Sync` so this won't happen.
         unsafe { *self.value.get() }
@@ -613,7 +615,8 @@ impl<T: ?Sized> Cell<T> {
     /// ```
     #[inline]
     #[stable(feature = "cell_get_mut", since = "1.11.0")]
-    pub fn get_mut(&mut self) -> &mut T {
+    #[rustc_const_unstable(feature = "const_cell", issue = "131283")]
+    pub const fn get_mut(&mut self) -> &mut T {
         self.value.get_mut()
     }
 
@@ -632,7 +635,8 @@ impl<T: ?Sized> Cell<T> {
     /// ```
     #[inline]
     #[stable(feature = "as_cell", since = "1.37.0")]
-    pub fn from_mut(t: &mut T) -> &Cell<T> {
+    #[rustc_const_unstable(feature = "const_cell", issue = "131283")]
+    pub const fn from_mut(t: &mut T) -> &Cell<T> {
         // SAFETY: `&mut` ensures unique access.
         unsafe { &*(t as *mut T as *const Cell<T>) }
     }
@@ -686,7 +690,8 @@ impl<T> Cell<[T]> {
     /// assert_eq!(slice_cell.len(), 3);
     /// ```
     #[stable(feature = "as_cell", since = "1.37.0")]
-    pub fn as_slice_of_cells(&self) -> &[Cell<T>] {
+    #[rustc_const_unstable(feature = "const_cell", issue = "131283")]
+    pub const fn as_slice_of_cells(&self) -> &[Cell<T>] {
         // SAFETY: `Cell<T>` has the same memory layout as `T`.
         unsafe { &*(self as *const Cell<[T]> as *const [Cell<T>]) }
     }
@@ -706,7 +711,8 @@ impl<T, const N: usize> Cell<[T; N]> {
     /// let array_cell: &[Cell<i32>; 3] = cell_array.as_array_of_cells();
     /// ```
     #[unstable(feature = "as_array_of_cells", issue = "88248")]
-    pub fn as_array_of_cells(&self) -> &[Cell<T>; N] {
+    #[rustc_const_unstable(feature = "as_array_of_cells", issue = "88248")]
+    pub const fn as_array_of_cells(&self) -> &[Cell<T>; N] {
         // SAFETY: `Cell<T>` has the same memory layout as `T`.
         unsafe { &*(self as *const Cell<[T; N]> as *const [Cell<T>; N]) }
     }
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index 888ba8e2a3f..11260f87d00 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -37,6 +37,9 @@ pub struct Finder {
 const STAGE0_MISSING_TARGETS: &[&str] = &[
     // just a dummy comment so the list doesn't get onelined
     "armv7-rtems-eabihf",
+    "riscv32e-unknown-none-elf",
+    "riscv32em-unknown-none-elf",
+    "riscv32emc-unknown-none-elf",
 ];
 
 /// Minimum version threshold for libstdc++ required when using prebuilt LLVM
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 9d2efc0f6de..0ef95ba64a1 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -413,5 +413,8 @@ target | std | host | notes
 [`riscv32imafc-unknown-nuttx-elf`](platform-support/nuttx.md) | * |  | RISC-V 32bit with NuttX
 [`riscv64imac-unknown-nuttx-elf`](platform-support/nuttx.md) | * |  | RISC-V 64bit with NuttX
 [`riscv64gc-unknown-nuttx-elf`](platform-support/nuttx.md) | * |  | RISC-V 64bit with NuttX
+[`riscv32e-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * |  | Bare RISC-V (RV32E ISA)
+[`riscv32em-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * |  | Bare RISC-V (RV32EM ISA)
+[`riscv32emc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * |  | Bare RISC-V (RV32EMC ISA)
 
 [runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets
diff --git a/src/doc/rustc/src/platform-support/riscv32-unknown-none-elf.md b/src/doc/rustc/src/platform-support/riscv32-unknown-none-elf.md
index 9a27a568b57..38742143c4b 100644
--- a/src/doc/rustc/src/platform-support/riscv32-unknown-none-elf.md
+++ b/src/doc/rustc/src/platform-support/riscv32-unknown-none-elf.md
@@ -35,4 +35,4 @@ Rust test-suite on this target.
 ## Cross-compilation toolchains and C code
 
 This target supports C code. If interlinking with C or C++, you may need to use
-`riscv64-unknown-elf-gcc` as a linker instead of `rust-lld`.
+`riscv32-unknown-elf-gcc` as a linker instead of `rust-lld`.
diff --git a/src/doc/rustc/src/platform-support/riscv32e-unknown-none-elf.md b/src/doc/rustc/src/platform-support/riscv32e-unknown-none-elf.md
new file mode 100644
index 00000000000..69f08774f83
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/riscv32e-unknown-none-elf.md
@@ -0,0 +1,30 @@
+# `riscv32{e,em,emc}-unknown-none-elf`
+
+**Tier: 3**
+
+Bare-metal target for RISC-V CPUs with the RV32E, RV32EM and RV32EMC ISAs.
+
+## Target maintainers
+
+* Henri Lunnikivi, <henri.lunnikivi@gmail.com>, [@hegza](https://github.com/hegza)
+
+## Requirements
+
+The target is cross-compiled, and uses static linking. No external toolchain is
+required and the default `rust-lld` linker works, but you must specify a linker
+script.
+
+## Building the target
+
+This target is included in Rust and can be installed via `rustup`.
+
+## Testing
+
+This is a cross-compiled `no-std` target, which must be run either in a
+simulator or by programming them onto suitable hardware. It is not possible to
+run the Rust test-suite on this target.
+
+## Cross-compilation toolchains and C code
+
+This target supports C code. If interlinking with C or C++, you may need to use
+`riscv32-unknown-elf-gcc` as a linker instead of `rust-lld`.
diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs
index e08e6a8b174..f26d06a0ecb 100644
--- a/tests/assembly/targets/targets-elf.rs
+++ b/tests/assembly/targets/targets-elf.rs
@@ -375,6 +375,15 @@
 //@ revisions: riscv32_wrs_vxworks
 //@ [riscv32_wrs_vxworks] compile-flags: --target riscv32-wrs-vxworks
 //@ [riscv32_wrs_vxworks] needs-llvm-components: riscv
+//@ revisions: riscv32e_unknown_none_elf
+//@ [riscv32e_unknown_none_elf] compile-flags: --target riscv32e-unknown-none-elf
+//@ [riscv32e_unknown_none_elf] needs-llvm-components: riscv
+//@ revisions: riscv32em_unknown_none_elf
+//@ [riscv32em_unknown_none_elf] compile-flags: --target riscv32em-unknown-none-elf
+//@ [riscv32em_unknown_none_elf] needs-llvm-components: riscv
+//@ revisions: riscv32emc_unknown_none_elf
+//@ [riscv32emc_unknown_none_elf] compile-flags: --target riscv32emc-unknown-none-elf
+//@ [riscv32emc_unknown_none_elf] needs-llvm-components: riscv
 //@ revisions: riscv32gc_unknown_linux_gnu
 //@ [riscv32gc_unknown_linux_gnu] compile-flags: --target riscv32gc-unknown-linux-gnu
 //@ [riscv32gc_unknown_linux_gnu] needs-llvm-components: riscv
diff --git a/tests/ui/abi/riscv32e-registers.riscv32e.stderr b/tests/ui/abi/riscv32e-registers.riscv32e.stderr
new file mode 100644
index 00000000000..e3894431eb4
--- /dev/null
+++ b/tests/ui/abi/riscv32e-registers.riscv32e.stderr
@@ -0,0 +1,194 @@
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:43:11
+   |
+LL |     asm!("li x16, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x16, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:46:11
+   |
+LL |     asm!("li x17, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x17, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:49:11
+   |
+LL |     asm!("li x18, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x18, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:52:11
+   |
+LL |     asm!("li x19, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x19, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:55:11
+   |
+LL |     asm!("li x20, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x20, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:58:11
+   |
+LL |     asm!("li x21, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x21, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:61:11
+   |
+LL |     asm!("li x22, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x22, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:64:11
+   |
+LL |     asm!("li x23, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x23, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:67:11
+   |
+LL |     asm!("li x24, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x24, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:70:11
+   |
+LL |     asm!("li x25, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x25, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:73:11
+   |
+LL |     asm!("li x26, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x26, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:76:11
+   |
+LL |     asm!("li x27, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x27, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:79:11
+   |
+LL |     asm!("li x28, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x28, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:82:11
+   |
+LL |     asm!("li x29, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x29, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:85:11
+   |
+LL |     asm!("li x30, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x30, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:88:11
+   |
+LL |     asm!("li x31, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x31, 0
+   |        ^
+
+error: aborting due to 16 previous errors
+
diff --git a/tests/ui/abi/riscv32e-registers.riscv32em.stderr b/tests/ui/abi/riscv32e-registers.riscv32em.stderr
new file mode 100644
index 00000000000..e3894431eb4
--- /dev/null
+++ b/tests/ui/abi/riscv32e-registers.riscv32em.stderr
@@ -0,0 +1,194 @@
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:43:11
+   |
+LL |     asm!("li x16, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x16, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:46:11
+   |
+LL |     asm!("li x17, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x17, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:49:11
+   |
+LL |     asm!("li x18, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x18, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:52:11
+   |
+LL |     asm!("li x19, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x19, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:55:11
+   |
+LL |     asm!("li x20, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x20, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:58:11
+   |
+LL |     asm!("li x21, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x21, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:61:11
+   |
+LL |     asm!("li x22, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x22, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:64:11
+   |
+LL |     asm!("li x23, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x23, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:67:11
+   |
+LL |     asm!("li x24, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x24, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:70:11
+   |
+LL |     asm!("li x25, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x25, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:73:11
+   |
+LL |     asm!("li x26, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x26, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:76:11
+   |
+LL |     asm!("li x27, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x27, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:79:11
+   |
+LL |     asm!("li x28, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x28, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:82:11
+   |
+LL |     asm!("li x29, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x29, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:85:11
+   |
+LL |     asm!("li x30, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x30, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:88:11
+   |
+LL |     asm!("li x31, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x31, 0
+   |        ^
+
+error: aborting due to 16 previous errors
+
diff --git a/tests/ui/abi/riscv32e-registers.riscv32emc.stderr b/tests/ui/abi/riscv32e-registers.riscv32emc.stderr
new file mode 100644
index 00000000000..e3894431eb4
--- /dev/null
+++ b/tests/ui/abi/riscv32e-registers.riscv32emc.stderr
@@ -0,0 +1,194 @@
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:43:11
+   |
+LL |     asm!("li x16, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x16, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:46:11
+   |
+LL |     asm!("li x17, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x17, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:49:11
+   |
+LL |     asm!("li x18, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x18, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:52:11
+   |
+LL |     asm!("li x19, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x19, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:55:11
+   |
+LL |     asm!("li x20, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x20, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:58:11
+   |
+LL |     asm!("li x21, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x21, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:61:11
+   |
+LL |     asm!("li x22, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x22, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:64:11
+   |
+LL |     asm!("li x23, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x23, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:67:11
+   |
+LL |     asm!("li x24, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x24, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:70:11
+   |
+LL |     asm!("li x25, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x25, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:73:11
+   |
+LL |     asm!("li x26, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x26, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:76:11
+   |
+LL |     asm!("li x27, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x27, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:79:11
+   |
+LL |     asm!("li x28, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x28, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:82:11
+   |
+LL |     asm!("li x29, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x29, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:85:11
+   |
+LL |     asm!("li x30, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x30, 0
+   |        ^
+
+error: invalid operand for instruction
+  --> $DIR/riscv32e-registers.rs:88:11
+   |
+LL |     asm!("li x31, 0");
+   |           ^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:5
+   |
+LL |     li x31, 0
+   |        ^
+
+error: aborting due to 16 previous errors
+
diff --git a/tests/ui/abi/riscv32e-registers.rs b/tests/ui/abi/riscv32e-registers.rs
new file mode 100644
index 00000000000..714b0ee4633
--- /dev/null
+++ b/tests/ui/abi/riscv32e-registers.rs
@@ -0,0 +1,91 @@
+// Test that loads into registers x16..=x31 are never generated for riscv32{e,em,emc} targets
+//
+//@ build-fail
+//@ revisions: riscv32e riscv32em riscv32emc
+//
+//@ compile-flags: --crate-type=rlib
+//@ [riscv32e] needs-llvm-components: riscv
+//@ [riscv32e] compile-flags: --target=riscv32e-unknown-none-elf
+//@ [riscv32em] needs-llvm-components: riscv
+//@ [riscv32em] compile-flags: --target=riscv32em-unknown-none-elf
+//@ [riscv32emc] needs-llvm-components: riscv
+//@ [riscv32emc] compile-flags: --target=riscv32emc-unknown-none-elf
+
+#![no_core]
+#![feature(no_core, lang_items, rustc_attrs)]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+    () => {};
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+// Verify registers x1..=x15 are addressable on riscv32e, but registers x16..=x31 are not
+#[no_mangle]
+pub unsafe fn registers() {
+    asm!("li x1, 0");
+    asm!("li x2, 0");
+    asm!("li x3, 0");
+    asm!("li x4, 0");
+    asm!("li x5, 0");
+    asm!("li x6, 0");
+    asm!("li x7, 0");
+    asm!("li x8, 0");
+    asm!("li x9, 0");
+    asm!("li x10, 0");
+    asm!("li x11, 0");
+    asm!("li x12, 0");
+    asm!("li x13, 0");
+    asm!("li x14, 0");
+    asm!("li x15, 0");
+    asm!("li x16, 0");
+    //~^ ERROR invalid operand for instruction
+    //~| NOTE instantiated into assembly here
+    asm!("li x17, 0");
+    //~^ ERROR invalid operand for instruction
+    //~| NOTE instantiated into assembly here
+    asm!("li x18, 0");
+    //~^ ERROR invalid operand for instruction
+    //~| NOTE instantiated into assembly here
+    asm!("li x19, 0");
+    //~^ ERROR invalid operand for instruction
+    //~| NOTE instantiated into assembly here
+    asm!("li x20, 0");
+    //~^ ERROR invalid operand for instruction
+    //~| NOTE instantiated into assembly here
+    asm!("li x21, 0");
+    //~^ ERROR invalid operand for instruction
+    //~| NOTE instantiated into assembly here
+    asm!("li x22, 0");
+    //~^ ERROR invalid operand for instruction
+    //~| NOTE instantiated into assembly here
+    asm!("li x23, 0");
+    //~^ ERROR invalid operand for instruction
+    //~| NOTE instantiated into assembly here
+    asm!("li x24, 0");
+    //~^ ERROR invalid operand for instruction
+    //~| NOTE instantiated into assembly here
+    asm!("li x25, 0");
+    //~^ ERROR invalid operand for instruction
+    //~| NOTE instantiated into assembly here
+    asm!("li x26, 0");
+    //~^ ERROR invalid operand for instruction
+    //~| NOTE instantiated into assembly here
+    asm!("li x27, 0");
+    //~^ ERROR invalid operand for instruction
+    //~| NOTE instantiated into assembly here
+    asm!("li x28, 0");
+    //~^ ERROR invalid operand for instruction
+    //~| NOTE instantiated into assembly here
+    asm!("li x29, 0");
+    //~^ ERROR invalid operand for instruction
+    //~| NOTE instantiated into assembly here
+    asm!("li x30, 0");
+    //~^ ERROR invalid operand for instruction
+    //~| NOTE instantiated into assembly here
+    asm!("li x31, 0");
+    //~^ ERROR invalid operand for instruction
+    //~| NOTE instantiated into assembly here
+}
diff --git a/tests/ui/panic-handler/panic-handler-with-track-caller.stderr b/tests/ui/panic-handler/panic-handler-with-track-caller.stderr
index 9ed387fc8d1..605567acdb5 100644
--- a/tests/ui/panic-handler/panic-handler-with-track-caller.stderr
+++ b/tests/ui/panic-handler/panic-handler-with-track-caller.stderr
@@ -5,7 +5,7 @@ LL | #[track_caller]
    | ^^^^^^^^^^^^^^^
 LL |
 LL | fn panic(info: &PanicInfo) -> ! {
-   | ------------------------------- `#[panic_handler]` function is not allowed to have `#[target_feature]`
+   | ------------------------------- `#[panic_handler]` function is not allowed to have `#[track_caller]`
 
 error: aborting due to 1 previous error