diff --git a/Cargo.lock b/Cargo.lock
index 1b89223c8bef1..677c00b003662 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -444,7 +444,7 @@ dependencies = [
  "directories",
  "rustc-build-sysroot",
  "rustc-workspace-hack",
- "rustc_tools_util 0.2.1",
+ "rustc_tools_util",
  "rustc_version",
  "serde",
  "serde_json",
@@ -738,7 +738,7 @@ dependencies = [
  "regex",
  "rustc-semver",
  "rustc-workspace-hack",
- "rustc_tools_util 0.3.0",
+ "rustc_tools_util",
  "semver",
  "serde",
  "syn",
@@ -3810,6 +3810,8 @@ dependencies = [
  "rustc_span",
  "rustc_symbol_mangling",
  "rustc_target",
+ "serde",
+ "serde_json",
  "smallvec",
  "tempfile",
  "tracing",
@@ -4725,12 +4727,6 @@ dependencies = [
  "tracing",
 ]
 
-[[package]]
-name = "rustc_tools_util"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "598f48ce2a421542b3e64828aa742b687cc1b91d2f96591cfdb7ac5988cd6366"
-
 [[package]]
 name = "rustc_tools_util"
 version = "0.3.0"
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index aa3a666b0b29c..39574ca558f8b 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -1505,14 +1505,6 @@ pub struct PointeeInfo {
     pub safe: Option<PointerKind>,
 }
 
-/// Used in `might_permit_raw_init` to indicate the kind of initialisation
-/// that is checked to be valid
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum InitKind {
-    Zero,
-    UninitMitigated0x01Fill,
-}
-
 impl LayoutS {
     /// Returns `true` if the layout corresponds to an unsized type.
     pub fn is_unsized(&self) -> bool {
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
index 6feb3a7732e12..f00e932107058 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
@@ -21,7 +21,8 @@ mod simd;
 pub(crate) use cpuid::codegen_cpuid_call;
 pub(crate) use llvm::codegen_llvm_intrinsic_call;
 
-use rustc_middle::ty::layout::HasParamEnv;
+use rustc_middle::ty;
+use rustc_middle::ty::layout::{HasParamEnv, InitKind};
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_span::symbol::{kw, sym, Symbol};
@@ -642,7 +643,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             if intrinsic == sym::assert_zero_valid
                 && !fx
                     .tcx
-                    .permits_zero_init(fx.param_env().and(ty))
+                    .check_validity_of_init((InitKind::Zero, fx.param_env().and(ty)))
                     .expect("expected to have layout during codegen")
             {
                 with_no_trimmed_paths!({
@@ -661,7 +662,10 @@ fn codegen_regular_intrinsic_call<'tcx>(
             if intrinsic == sym::assert_mem_uninitialized_valid
                 && !fx
                     .tcx
-                    .permits_uninit_init(fx.param_env().and(ty))
+                    .check_validity_of_init((
+                        InitKind::UninitMitigated0x01Fill,
+                        fx.param_env().and(ty),
+                    ))
                     .expect("expected to have layout during codegen")
             {
                 with_no_trimmed_paths!({
diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml
index 773c0ebbe59db..a7ba2f8b69533 100644
--- a/compiler/rustc_codegen_llvm/Cargo.toml
+++ b/compiler/rustc_codegen_llvm/Cargo.toml
@@ -36,3 +36,5 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 rustc_ast = { path = "../rustc_ast" }
 rustc_span = { path = "../rustc_span" }
 tempfile = "3.2.0"
+serde = { version = "1", features = [ "derive" ]}
+serde_json = "1"
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 40f0594b40db3..a4ae1b01e869d 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -761,6 +761,7 @@ pub(crate) unsafe fn codegen(
             EmitObj::None => {}
         }
 
+        record_llvm_cgu_instructions_stats(&cgcx.prof, llmod);
         drop(handlers);
     }
 
@@ -974,3 +975,23 @@ fn record_artifact_size(
         self_profiler_ref.artifact_size(artifact_kind, artifact_name.to_string_lossy(), file_size);
     }
 }
+
+fn record_llvm_cgu_instructions_stats(prof: &SelfProfilerRef, llmod: &llvm::Module) {
+    if !prof.enabled() {
+        return;
+    }
+
+    let raw_stats =
+        llvm::build_string(|s| unsafe { llvm::LLVMRustModuleInstructionStats(&llmod, s) })
+            .expect("cannot get module instruction stats");
+
+    #[derive(serde::Deserialize)]
+    struct InstructionsStats {
+        module: String,
+        total: u64,
+    }
+
+    let InstructionsStats { module, total } =
+        serde_json::from_str(&raw_stats).expect("cannot parse llvm cgu instructions stats");
+    prof.artifact_size("cgu_instructions", module, total);
+}
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 7aab666fc5e8c..1b3ce2e83a979 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -2410,6 +2410,8 @@ extern "C" {
     pub fn LLVMRustModuleBufferLen(p: &ModuleBuffer) -> usize;
     pub fn LLVMRustModuleBufferFree(p: &'static mut ModuleBuffer);
     pub fn LLVMRustModuleCost(M: &Module) -> u64;
+    #[allow(improper_ctypes)]
+    pub fn LLVMRustModuleInstructionStats(M: &Module, Str: &RustString);
 
     pub fn LLVMRustThinLTOBufferCreate(M: &Module, is_thin: bool) -> &'static mut ThinLTOBuffer;
     pub fn LLVMRustThinLTOBufferFree(M: &'static mut ThinLTOBuffer);
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index f6c1b7a98aae7..b1abbd673a53a 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -14,7 +14,7 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
 use rustc_hir::lang_items::LangItem;
 use rustc_index::vec::Idx;
 use rustc_middle::mir::{self, AssertKind, SwitchTargets};
-use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
+use rustc_middle::ty::layout::{HasTyCtxt, InitKind, LayoutOf};
 use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
 use rustc_middle::ty::{self, Instance, Ty, TypeVisitableExt};
 use rustc_session::config::OptLevel;
@@ -676,11 +676,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 Inhabited => layout.abi.is_uninhabited(),
                 ZeroValid => !bx
                     .tcx()
-                    .permits_zero_init(bx.param_env().and(ty))
+                    .check_validity_of_init((InitKind::Zero, bx.param_env().and(ty)))
                     .expect("expected to have layout during codegen"),
                 MemUninitializedValid => !bx
                     .tcx()
-                    .permits_uninit_init(bx.param_env().and(ty))
+                    .check_validity_of_init((
+                        InitKind::UninitMitigated0x01Fill,
+                        bx.param_env().and(ty),
+                    ))
                     .expect("expected to have layout during codegen"),
             };
             Some(if do_panic {
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 6e47646caeda8..26c84b4ce6127 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -11,7 +11,7 @@ use rustc_middle::mir::{
     BinOp, NonDivergingIntrinsic,
 };
 use rustc_middle::ty;
-use rustc_middle::ty::layout::LayoutOf as _;
+use rustc_middle::ty::layout::{InitKind, LayoutOf as _};
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::{Ty, TyCtxt};
 use rustc_span::symbol::{sym, Symbol};
@@ -437,7 +437,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 if intrinsic_name == sym::assert_zero_valid {
                     let should_panic = !self
                         .tcx
-                        .permits_zero_init(self.param_env.and(ty))
+                        .check_validity_of_init((InitKind::Zero, self.param_env.and(ty)))
                         .map_err(|_| err_inval!(TooGeneric))?;
 
                     if should_panic {
@@ -454,7 +454,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 if intrinsic_name == sym::assert_mem_uninitialized_valid {
                     let should_panic = !self
                         .tcx
-                        .permits_uninit_init(self.param_env.and(ty))
+                        .check_validity_of_init((
+                            InitKind::UninitMitigated0x01Fill,
+                            self.param_env.and(ty),
+                        ))
                         .map_err(|_| err_inval!(TooGeneric))?;
 
                     if should_panic {
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index fc6d61c79c2c4..092a7dc3d3b51 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -38,7 +38,6 @@ use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
 use rustc_macros::fluent_messages;
 use rustc_middle::ty;
 use rustc_middle::ty::query::Providers;
-use rustc_target::abi::InitKind;
 
 fluent_messages! { "../locales/en-US.ftl" }
 
@@ -62,9 +61,7 @@ pub fn provide(providers: &mut Providers) {
         let (param_env, value) = param_env_and_value.into_parts();
         const_eval::deref_mir_constant(tcx, param_env, value)
     };
-    providers.permits_uninit_init = |tcx, param_env_and_ty| {
-        util::might_permit_raw_init(tcx, param_env_and_ty, InitKind::UninitMitigated0x01Fill)
+    providers.check_validity_of_init = |tcx, (init_kind, param_env_and_ty)| {
+        util::might_permit_raw_init(tcx, init_kind, param_env_and_ty)
     };
-    providers.permits_zero_init =
-        |tcx, param_env_and_ty| util::might_permit_raw_init(tcx, param_env_and_ty, InitKind::Zero);
 }
diff --git a/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs b/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs
index 2eba1e11466a4..a78bf927ca1dc 100644
--- a/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs
+++ b/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs
@@ -1,7 +1,7 @@
-use rustc_middle::ty::layout::{LayoutCx, LayoutError, LayoutOf, TyAndLayout};
+use rustc_middle::ty::layout::{InitKind, LayoutCx, LayoutError, LayoutOf, TyAndLayout};
 use rustc_middle::ty::{ParamEnv, ParamEnvAnd, Ty, TyCtxt};
 use rustc_session::Limit;
-use rustc_target::abi::{Abi, FieldsShape, InitKind, Scalar, Variants};
+use rustc_target::abi::{Abi, FieldsShape, Scalar, Variants};
 
 use crate::const_eval::{CheckAlignment, CompileTimeInterpreter};
 use crate::interpret::{InterpCx, MemoryKind, OpTy};
@@ -20,8 +20,8 @@ use crate::interpret::{InterpCx, MemoryKind, OpTy};
 /// to the full uninit check).
 pub fn might_permit_raw_init<'tcx>(
     tcx: TyCtxt<'tcx>,
-    param_env_and_ty: ParamEnvAnd<'tcx, Ty<'tcx>>,
     kind: InitKind,
+    param_env_and_ty: ParamEnvAnd<'tcx, Ty<'tcx>>,
 ) -> Result<bool, LayoutError<'tcx>> {
     if tcx.sess.opts.unstable_opts.strict_init_checks {
         might_permit_raw_init_strict(tcx.layout_of(param_env_and_ty)?, tcx, kind)
diff --git a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
index 9146a3739b2b1..0589062837866 100644
--- a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
+++ b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
@@ -14,6 +14,7 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/DynamicLibrary.h"
 #include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/JSON.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/Memory.h"
 #include "llvm/Support/SourceMgr.h"
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index b1e6534944db3..e3493caaaf74e 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -1751,6 +1751,19 @@ LLVMRustModuleCost(LLVMModuleRef M) {
   return std::distance(std::begin(f), std::end(f));
 }
 
+extern "C" void
+LLVMRustModuleInstructionStats(LLVMModuleRef M, RustStringRef Str)
+{
+  RawRustStringOstream OS(Str);
+  llvm::json::OStream JOS(OS);
+  auto Module = unwrap(M);
+
+  JOS.object([&] {
+    JOS.attribute("module", Module->getName());
+    JOS.attribute("total", Module->getInstructionCount());
+  });
+}
+
 // Vector reductions:
 extern "C" LLVMValueRef
 LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index 2e2ca6a27888e..ad119c4e07306 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -64,13 +64,17 @@ impl ModuleItems {
         self.foreign_items.iter().copied()
     }
 
-    pub fn definitions(&self) -> impl Iterator<Item = LocalDefId> + '_ {
+    pub fn owners(&self) -> impl Iterator<Item = OwnerId> + '_ {
         self.items
             .iter()
-            .map(|id| id.owner_id.def_id)
-            .chain(self.trait_items.iter().map(|id| id.owner_id.def_id))
-            .chain(self.impl_items.iter().map(|id| id.owner_id.def_id))
-            .chain(self.foreign_items.iter().map(|id| id.owner_id.def_id))
+            .map(|id| id.owner_id)
+            .chain(self.trait_items.iter().map(|id| id.owner_id))
+            .chain(self.impl_items.iter().map(|id| id.owner_id))
+            .chain(self.foreign_items.iter().map(|id| id.owner_id))
+    }
+
+    pub fn definitions(&self) -> impl Iterator<Item = LocalDefId> + '_ {
+        self.owners().map(|id| id.def_id)
     }
 
     pub fn par_items(&self, f: impl Fn(ItemId) + Send + Sync) {
diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs
index dc02fd53ed02c..111ea6b8cddc0 100644
--- a/compiler/rustc_middle/src/query/keys.rs
+++ b/compiler/rustc_middle/src/query/keys.rs
@@ -4,8 +4,9 @@ use crate::infer::canonical::Canonical;
 use crate::mir;
 use crate::traits;
 use crate::ty::fast_reject::SimplifiedType;
+use crate::ty::layout::{InitKind, TyAndLayout};
 use crate::ty::subst::{GenericArg, SubstsRef};
-use crate::ty::{self, layout::TyAndLayout, Ty, TyCtxt};
+use crate::ty::{self, Ty, TyCtxt};
 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
 use rustc_hir::hir_id::{HirId, OwnerId};
 use rustc_query_system::query::{DefaultCacheSelector, SingleCacheSelector, VecCacheSelector};
@@ -696,3 +697,24 @@ impl Key for HirId {
         None
     }
 }
+
+impl<'tcx> Key for (InitKind, ty::ParamEnvAnd<'tcx, Ty<'tcx>>) {
+    type CacheSelector = DefaultCacheSelector<Self>;
+
+    // Just forward to `Ty<'tcx>`
+    #[inline(always)]
+    fn query_crate_is_local(&self) -> bool {
+        true
+    }
+
+    fn default_span(&self, _: TyCtxt<'_>) -> Span {
+        DUMMY_SP
+    }
+
+    fn ty_adt_id(&self) -> Option<DefId> {
+        match self.1.value.kind() {
+            ty::Adt(adt, _) => Some(adt.did()),
+            _ => None,
+        }
+    }
+}
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 6a34e5ede1938..d4435a54b4ab6 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -2173,12 +2173,8 @@ rustc_queries! {
         separate_provide_extern
     }
 
-    query permits_uninit_init(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> Result<bool, ty::layout::LayoutError<'tcx>> {
-        desc { "checking to see if `{}` permits being left uninit", key.value }
-    }
-
-    query permits_zero_init(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> Result<bool, ty::layout::LayoutError<'tcx>> {
-        desc { "checking to see if `{}` permits being left zeroed", key.value }
+    query check_validity_of_init(key: (InitKind, ty::ParamEnvAnd<'tcx, Ty<'tcx>>)) -> Result<bool, ty::layout::LayoutError<'tcx>> {
+        desc { "checking to see if `{}` permits being left {}", key.1.value, key.0 }
     }
 
     query compare_impl_const(
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 6c59cde86e39b..f0b52455889aa 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -169,6 +169,23 @@ pub const FAT_PTR_EXTRA: usize = 1;
 /// * Cranelift stores the base-2 log of the lane count in a 4 bit integer.
 pub const MAX_SIMD_LANES: u64 = 1 << 0xF;
 
+/// Used in `might_permit_raw_init` to indicate the kind of initialisation
+/// that is checked to be valid
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
+pub enum InitKind {
+    Zero,
+    UninitMitigated0x01Fill,
+}
+
+impl fmt::Display for InitKind {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Self::Zero => f.write_str("zeroed"),
+            Self::UninitMitigated0x01Fill => f.write_str("filled with 0x01"),
+        }
+    }
+}
+
 #[derive(Copy, Clone, Debug, HashStable, TyEncodable, TyDecodable)]
 pub enum LayoutError<'tcx> {
     Unknown(Ty<'tcx>),
diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs
index 3d9a5075d4ade..d743c30684958 100644
--- a/compiler/rustc_middle/src/ty/query.rs
+++ b/compiler/rustc_middle/src/ty/query.rs
@@ -32,6 +32,7 @@ use crate::traits::specialization_graph;
 use crate::traits::{self, ImplSource};
 use crate::ty::context::TyCtxtFeed;
 use crate::ty::fast_reject::SimplifiedType;
+use crate::ty::layout::InitKind;
 use crate::ty::subst::{GenericArg, SubstsRef};
 use crate::ty::util::AlwaysRequiresDrop;
 use crate::ty::GeneratorDiagnosticData;
diff --git a/compiler/rustc_mir_transform/src/instcombine.rs b/compiler/rustc_mir_transform/src/instcombine.rs
index 14e644bc344ca..05286b71d47e4 100644
--- a/compiler/rustc_mir_transform/src/instcombine.rs
+++ b/compiler/rustc_mir_transform/src/instcombine.rs
@@ -6,8 +6,8 @@ use rustc_middle::mir::{
     BinOp, Body, Constant, ConstantKind, LocalDecls, Operand, Place, ProjectionElem, Rvalue,
     SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, UnOp,
 };
-use rustc_middle::ty::layout::LayoutError;
-use rustc_middle::ty::{self, ParamEnv, ParamEnvAnd, SubstsRef, Ty, TyCtxt};
+use rustc_middle::ty::layout::InitKind;
+use rustc_middle::ty::{self, ParamEnv, SubstsRef, Ty, TyCtxt};
 use rustc_span::symbol::{sym, Symbol};
 
 pub struct InstCombine;
@@ -234,16 +234,15 @@ impl<'tcx> InstCombineContext<'tcx, '_> {
         }
         let ty = substs.type_at(0);
 
-        // Check this is a foldable intrinsic before we query the layout of our generic parameter
-        let Some(assert_panics) = intrinsic_assert_panics(intrinsic_name) else { return; };
-        match assert_panics(self.tcx, self.param_env.and(ty)) {
-            // We don't know the layout, don't touch the assertion
-            Err(_) => {}
-            Ok(true) => {
+        let known_is_valid = intrinsic_assert_panics(self.tcx, self.param_env, ty, intrinsic_name);
+        match known_is_valid {
+            // We don't know the layout or it's not validity assertion at all, don't touch it
+            None => {}
+            Some(true) => {
                 // If we know the assert panics, indicate to later opts that the call diverges
                 *target = None;
             }
-            Ok(false) => {
+            Some(false) => {
                 // If we know the assert does not panic, turn the call into a Goto
                 terminator.kind = TerminatorKind::Goto { target: *target_block };
             }
@@ -252,33 +251,21 @@ impl<'tcx> InstCombineContext<'tcx, '_> {
 }
 
 fn intrinsic_assert_panics<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+    ty: Ty<'tcx>,
     intrinsic_name: Symbol,
-) -> Option<fn(TyCtxt<'tcx>, ParamEnvAnd<'tcx, Ty<'tcx>>) -> Result<bool, LayoutError<'tcx>>> {
-    fn inhabited_predicate<'tcx>(
-        tcx: TyCtxt<'tcx>,
-        param_env_and_ty: ParamEnvAnd<'tcx, Ty<'tcx>>,
-    ) -> Result<bool, LayoutError<'tcx>> {
-        Ok(tcx.layout_of(param_env_and_ty)?.abi.is_uninhabited())
-    }
-    fn zero_valid_predicate<'tcx>(
-        tcx: TyCtxt<'tcx>,
-        param_env_and_ty: ParamEnvAnd<'tcx, Ty<'tcx>>,
-    ) -> Result<bool, LayoutError<'tcx>> {
-        Ok(!tcx.permits_zero_init(param_env_and_ty)?)
-    }
-    fn mem_uninitialized_valid_predicate<'tcx>(
-        tcx: TyCtxt<'tcx>,
-        param_env_and_ty: ParamEnvAnd<'tcx, Ty<'tcx>>,
-    ) -> Result<bool, LayoutError<'tcx>> {
-        Ok(!tcx.permits_uninit_init(param_env_and_ty)?)
-    }
-
-    match intrinsic_name {
-        sym::assert_inhabited => Some(inhabited_predicate),
-        sym::assert_zero_valid => Some(zero_valid_predicate),
-        sym::assert_mem_uninitialized_valid => Some(mem_uninitialized_valid_predicate),
-        _ => None,
-    }
+) -> Option<bool> {
+    Some(match intrinsic_name {
+        sym::assert_inhabited => tcx.layout_of(param_env.and(ty)).ok()?.abi.is_uninhabited(),
+        sym::assert_zero_valid => {
+            !tcx.check_validity_of_init((InitKind::Zero, param_env.and(ty))).ok()?
+        }
+        sym::assert_mem_uninitialized_valid => !tcx
+            .check_validity_of_init((InitKind::UninitMitigated0x01Fill, param_env.and(ty)))
+            .ok()?,
+        _ => return None,
+    })
 }
 
 fn resolve_rust_intrinsic<'tcx>(
diff --git a/compiler/rustc_parse/locales/en-US.ftl b/compiler/rustc_parse/locales/en-US.ftl
index a31b1f6ac1a0a..4ddeeed5b7e0a 100644
--- a/compiler/rustc_parse/locales/en-US.ftl
+++ b/compiler/rustc_parse/locales/en-US.ftl
@@ -220,7 +220,7 @@ parse_match_arm_body_without_braces = `match` arm body without braces
             [one] statement
            *[other] statements
         } with a body
-    .suggestion_use_comma_not_semicolon = use a comma to end a `match` arm expression
+    .suggestion_use_comma_not_semicolon = replace `;` with `,` to end a `match` arm expression
 
 parse_inclusive_range_extra_equals = unexpected `=` after inclusive range
     .suggestion_remove_eq = use `..=` instead
diff --git a/compiler/rustc_passes/locales/en-US.ftl b/compiler/rustc_passes/locales/en-US.ftl
index 0ed29ce0d4795..3fa78efc290ba 100644
--- a/compiler/rustc_passes/locales/en-US.ftl
+++ b/compiler/rustc_passes/locales/en-US.ftl
@@ -402,9 +402,6 @@ passes_invalid_attr_at_crate_level =
     `{$name}` attribute cannot be used at crate level
     .suggestion = perhaps you meant to use an outer attribute
 
-passes_duplicate_diagnostic_item =
-    duplicate diagnostic item found: `{$name}`.
-
 passes_duplicate_diagnostic_item_in_crate =
     duplicate diagnostic item in crate `{$crate_name}`: `{$name}`.
     .note = the diagnostic item is first defined in crate `{$orig_crate_name}`.
diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs
index 0ae7096642cf1..110eb210df9ad 100644
--- a/compiler/rustc_passes/src/diagnostic_items.rs
+++ b/compiler/rustc_passes/src/diagnostic_items.rs
@@ -11,19 +11,19 @@
 
 use rustc_ast as ast;
 use rustc_hir::diagnostic_items::DiagnosticItems;
+use rustc_hir::OwnerId;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::TyCtxt;
-use rustc_span::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
-use rustc_span::symbol::{kw::Empty, sym, Symbol};
+use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
+use rustc_span::symbol::{sym, Symbol};
 
-use crate::errors::{DuplicateDiagnosticItem, DuplicateDiagnosticItemInCrate};
+use crate::errors::DuplicateDiagnosticItemInCrate;
 
-fn observe_item(tcx: TyCtxt<'_>, diagnostic_items: &mut DiagnosticItems, def_id: LocalDefId) {
-    let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
-    let attrs = tcx.hir().attrs(hir_id);
+fn observe_item<'tcx>(tcx: TyCtxt<'tcx>, diagnostic_items: &mut DiagnosticItems, owner: OwnerId) {
+    let attrs = tcx.hir().attrs(owner.into());
     if let Some(name) = extract(attrs) {
         // insert into our table
-        collect_item(tcx, diagnostic_items, name, def_id.to_def_id());
+        collect_item(tcx, diagnostic_items, name, owner.to_def_id());
     }
 }
 
@@ -31,23 +31,29 @@ fn collect_item(tcx: TyCtxt<'_>, items: &mut DiagnosticItems, name: Symbol, item
     items.id_to_name.insert(item_def_id, name);
     if let Some(original_def_id) = items.name_to_id.insert(name, item_def_id) {
         if original_def_id != item_def_id {
-            let orig_span = tcx.hir().span_if_local(original_def_id);
-            let orig_crate_name =
-                orig_span.is_none().then(|| tcx.crate_name(original_def_id.krate));
-            match tcx.hir().span_if_local(item_def_id) {
-                Some(span) => tcx.sess.emit_err(DuplicateDiagnosticItem { span, name }),
-                None => tcx.sess.emit_err(DuplicateDiagnosticItemInCrate {
-                    span: orig_span,
-                    orig_crate_name: orig_crate_name.unwrap_or(Empty),
-                    have_orig_crate_name: orig_crate_name.map(|_| ()),
-                    crate_name: tcx.crate_name(item_def_id.krate),
-                    name,
-                }),
-            };
+            report_duplicate_item(tcx, name, original_def_id, item_def_id);
         }
     }
 }
 
+fn report_duplicate_item(
+    tcx: TyCtxt<'_>,
+    name: Symbol,
+    original_def_id: DefId,
+    item_def_id: DefId,
+) {
+    let orig_span = tcx.hir().span_if_local(original_def_id);
+    let duplicate_span = tcx.hir().span_if_local(item_def_id);
+    tcx.sess.emit_err(DuplicateDiagnosticItemInCrate {
+        duplicate_span,
+        orig_span,
+        crate_name: tcx.crate_name(item_def_id.krate),
+        orig_crate_name: tcx.crate_name(original_def_id.krate),
+        different_crates: (item_def_id.krate != original_def_id.krate).then_some(()),
+        name,
+    });
+}
+
 /// Extract the first `rustc_diagnostic_item = "$name"` out of a list of attributes.
 fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> {
     attrs.iter().find_map(|attr| {
@@ -64,21 +70,8 @@ fn diagnostic_items(tcx: TyCtxt<'_>, cnum: CrateNum) -> DiagnosticItems {
 
     // Collect diagnostic items in this crate.
     let crate_items = tcx.hir_crate_items(());
-
-    for id in crate_items.items() {
-        observe_item(tcx, &mut diagnostic_items, id.owner_id.def_id);
-    }
-
-    for id in crate_items.trait_items() {
-        observe_item(tcx, &mut diagnostic_items, id.owner_id.def_id);
-    }
-
-    for id in crate_items.impl_items() {
-        observe_item(tcx, &mut diagnostic_items, id.owner_id.def_id);
-    }
-
-    for id in crate_items.foreign_items() {
-        observe_item(tcx, &mut diagnostic_items, id.owner_id.def_id);
+    for id in crate_items.owners() {
+        observe_item(tcx, &mut diagnostic_items, id);
     }
 
     diagnostic_items
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 2c0d21b479848..9f1c0b5a0b7bd 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -809,23 +809,17 @@ impl IntoDiagnostic<'_> for InvalidAttrAtCrateLevel {
     }
 }
 
-#[derive(Diagnostic)]
-#[diag(passes_duplicate_diagnostic_item)]
-pub struct DuplicateDiagnosticItem {
-    #[primary_span]
-    pub span: Span,
-    pub name: Symbol,
-}
-
 #[derive(Diagnostic)]
 #[diag(passes_duplicate_diagnostic_item_in_crate)]
 pub struct DuplicateDiagnosticItemInCrate {
+    #[primary_span]
+    pub duplicate_span: Option<Span>,
     #[note(passes_diagnostic_item_first_defined)]
-    pub span: Option<Span>,
-    pub orig_crate_name: Symbol,
+    pub orig_span: Option<Span>,
     #[note]
-    pub have_orig_crate_name: Option<()>,
+    pub different_crates: Option<()>,
     pub crate_name: Symbol,
+    pub orig_crate_name: Symbol,
     pub name: Symbol,
 }
 
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index 909d9bf4093b3..401def1845827 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -2,7 +2,8 @@ use crate::io::prelude::*;
 
 use crate::env;
 use crate::fs::{self, File, OpenOptions};
-use crate::io::{ErrorKind, SeekFrom};
+use crate::io::{BorrowedBuf, ErrorKind, SeekFrom};
+use crate::mem::MaybeUninit;
 use crate::path::Path;
 use crate::str;
 use crate::sync::Arc;
@@ -401,6 +402,23 @@ fn file_test_io_seek_read_write() {
     check!(fs::remove_file(&filename));
 }
 
+#[test]
+fn file_test_read_buf() {
+    let tmpdir = tmpdir();
+    let filename = &tmpdir.join("test");
+    check!(fs::write(filename, &[1, 2, 3, 4]));
+
+    let mut buf: [MaybeUninit<u8>; 128] = MaybeUninit::uninit_array();
+    let mut buf = BorrowedBuf::from(buf.as_mut_slice());
+    let mut file = check!(File::open(filename));
+    check!(file.read_buf(buf.unfilled()));
+    assert_eq!(buf.filled(), &[1, 2, 3, 4]);
+    // File::read_buf should omit buffer initialization.
+    assert_eq!(buf.init_len(), 4);
+
+    check!(fs::remove_file(filename));
+}
+
 #[test]
 fn file_test_stat_is_correct_on_is_file() {
     let tmpdir = tmpdir();
diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs
index 14bfef4c7aad9..0455a00956e6f 100644
--- a/library/std/src/io/stdio.rs
+++ b/library/std/src/io/stdio.rs
@@ -8,7 +8,7 @@ use crate::io::prelude::*;
 use crate::cell::{Cell, RefCell};
 use crate::fmt;
 use crate::fs::File;
-use crate::io::{self, BufReader, IoSlice, IoSliceMut, LineWriter, Lines};
+use crate::io::{self, BorrowedCursor, BufReader, IoSlice, IoSliceMut, LineWriter, Lines};
 use crate::sync::atomic::{AtomicBool, Ordering};
 use crate::sync::{Arc, Mutex, MutexGuard, OnceLock, ReentrantMutex, ReentrantMutexGuard};
 use crate::sys::stdio;
@@ -97,6 +97,10 @@ impl Read for StdinRaw {
         handle_ebadf(self.0.read(buf), 0)
     }
 
+    fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> {
+        handle_ebadf(self.0.read_buf(buf), ())
+    }
+
     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         handle_ebadf(self.0.read_vectored(bufs), 0)
     }
@@ -418,6 +422,9 @@ impl Read for Stdin {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.lock().read(buf)
     }
+    fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> {
+        self.lock().read_buf(buf)
+    }
     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         self.lock().read_vectored(bufs)
     }
@@ -450,6 +457,10 @@ impl Read for StdinLock<'_> {
         self.inner.read(buf)
     }
 
+    fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> {
+        self.inner.read_buf(buf)
+    }
+
     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         self.inner.read_vectored(bufs)
     }
diff --git a/library/std/src/net/tcp.rs b/library/std/src/net/tcp.rs
index ac09a805975ef..3982d3636614e 100644
--- a/library/std/src/net/tcp.rs
+++ b/library/std/src/net/tcp.rs
@@ -6,7 +6,7 @@ mod tests;
 use crate::io::prelude::*;
 
 use crate::fmt;
-use crate::io::{self, IoSlice, IoSliceMut};
+use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
 use crate::iter::FusedIterator;
 use crate::net::{Shutdown, SocketAddr, ToSocketAddrs};
 use crate::sys_common::net as net_imp;
@@ -619,6 +619,10 @@ impl Read for TcpStream {
         self.0.read(buf)
     }
 
+    fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> {
+        self.0.read_buf(buf)
+    }
+
     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         self.0.read_vectored(bufs)
     }
@@ -653,6 +657,10 @@ impl Read for &TcpStream {
         self.0.read(buf)
     }
 
+    fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> {
+        self.0.read_buf(buf)
+    }
+
     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         self.0.read_vectored(bufs)
     }
diff --git a/library/std/src/net/tcp/tests.rs b/library/std/src/net/tcp/tests.rs
index 8c0adcfb0ebbb..b8cfead19d7ee 100644
--- a/library/std/src/net/tcp/tests.rs
+++ b/library/std/src/net/tcp/tests.rs
@@ -1,6 +1,7 @@
 use crate::fmt;
 use crate::io::prelude::*;
-use crate::io::{ErrorKind, IoSlice, IoSliceMut};
+use crate::io::{BorrowedBuf, ErrorKind, IoSlice, IoSliceMut};
+use crate::mem::MaybeUninit;
 use crate::net::test::{next_test_ip4, next_test_ip6};
 use crate::net::*;
 use crate::sync::mpsc::channel;
@@ -279,6 +280,27 @@ fn partial_read() {
     })
 }
 
+#[test]
+fn read_buf() {
+    each_ip(&mut |addr| {
+        let srv = t!(TcpListener::bind(&addr));
+        let t = thread::spawn(move || {
+            let mut s = t!(TcpStream::connect(&addr));
+            s.write_all(&[1, 2, 3, 4]).unwrap();
+        });
+
+        let mut s = t!(srv.accept()).0;
+        let mut buf: [MaybeUninit<u8>; 128] = MaybeUninit::uninit_array();
+        let mut buf = BorrowedBuf::from(buf.as_mut_slice());
+        t!(s.read_buf(buf.unfilled()));
+        assert_eq!(buf.filled(), &[1, 2, 3, 4]);
+        // TcpStream::read_buf should omit buffer initialization.
+        assert_eq!(buf.init_len(), 4);
+
+        t.join().ok().expect("thread panicked");
+    })
+}
+
 #[test]
 fn read_vectored() {
     each_ip(&mut |addr| {
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index 62ce2cb33dc55..27116f4b6139b 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -110,7 +110,7 @@ use crate::convert::Infallible;
 use crate::ffi::OsStr;
 use crate::fmt;
 use crate::fs;
-use crate::io::{self, IoSlice, IoSliceMut};
+use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
 use crate::num::NonZeroI32;
 use crate::path::Path;
 use crate::str;
@@ -354,6 +354,10 @@ impl Read for ChildStdout {
         self.inner.read(buf)
     }
 
+    fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> {
+        self.inner.read_buf(buf)
+    }
+
     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         self.inner.read_vectored(bufs)
     }
@@ -419,6 +423,10 @@ impl Read for ChildStderr {
         self.inner.read(buf)
     }
 
+    fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> {
+        self.inner.read_buf(buf)
+    }
+
     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         self.inner.read_vectored(bufs)
     }
diff --git a/library/std/src/process/tests.rs b/library/std/src/process/tests.rs
index b4f6cc2dabae3..0e3494e53d24b 100644
--- a/library/std/src/process/tests.rs
+++ b/library/std/src/process/tests.rs
@@ -1,7 +1,8 @@
 use crate::io::prelude::*;
 
 use super::{Command, Output, Stdio};
-use crate::io::ErrorKind;
+use crate::io::{BorrowedBuf, ErrorKind};
+use crate::mem::MaybeUninit;
 use crate::str;
 
 fn known_command() -> Command {
@@ -119,6 +120,34 @@ fn stdin_works() {
     assert_eq!(out, "foobar\n");
 }
 
+#[test]
+#[cfg_attr(any(target_os = "vxworks"), ignore)]
+fn child_stdout_read_buf() {
+    let mut cmd = shell_cmd();
+    if cfg!(target_os = "windows") {
+        cmd.arg("/C").arg("echo abc");
+    } else {
+        cmd.arg("-c").arg("echo abc");
+    };
+    cmd.stdin(Stdio::null());
+    cmd.stdout(Stdio::piped());
+    let child = cmd.spawn().unwrap();
+
+    let mut stdout = child.stdout.unwrap();
+    let mut buf: [MaybeUninit<u8>; 128] = MaybeUninit::uninit_array();
+    let mut buf = BorrowedBuf::from(buf.as_mut_slice());
+    stdout.read_buf(buf.unfilled()).unwrap();
+
+    // ChildStdout::read_buf should omit buffer initialization.
+    if cfg!(target_os = "windows") {
+        assert_eq!(buf.filled(), b"abc\r\n");
+        assert_eq!(buf.init_len(), 5);
+    } else {
+        assert_eq!(buf.filled(), b"abc\n");
+        assert_eq!(buf.init_len(), 4);
+    };
+}
+
 #[test]
 #[cfg_attr(any(target_os = "vxworks"), ignore)]
 fn test_process_status() {
diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs
index 66c33d58d6ca3..4798992c6b07c 100644
--- a/library/std/src/sys/unix/fd.rs
+++ b/library/std/src/sys/unix/fd.rs
@@ -283,6 +283,15 @@ impl<'a> Read for &'a FileDesc {
     fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
         (**self).read_buf(cursor)
     }
+
+    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        (**self).read_vectored(bufs)
+    }
+
+    #[inline]
+    fn is_read_vectored(&self) -> bool {
+        (**self).is_read_vectored()
+    }
 }
 
 impl AsInner<OwnedFd> for FileDesc {
diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs
index c86f80972a69d..58431a479f045 100644
--- a/library/std/src/sys/unix/net.rs
+++ b/library/std/src/sys/unix/net.rs
@@ -1,6 +1,6 @@
 use crate::cmp;
 use crate::ffi::CStr;
-use crate::io::{self, IoSlice, IoSliceMut};
+use crate::io::{self, BorrowedBuf, BorrowedCursor, IoSlice, IoSliceMut};
 use crate::mem;
 use crate::net::{Shutdown, SocketAddr};
 use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
@@ -240,19 +240,35 @@ impl Socket {
         self.0.duplicate().map(Socket)
     }
 
-    fn recv_with_flags(&self, buf: &mut [u8], flags: c_int) -> io::Result<usize> {
+    fn recv_with_flags(&self, mut buf: BorrowedCursor<'_>, flags: c_int) -> io::Result<()> {
         let ret = cvt(unsafe {
-            libc::recv(self.as_raw_fd(), buf.as_mut_ptr() as *mut c_void, buf.len(), flags)
+            libc::recv(
+                self.as_raw_fd(),
+                buf.as_mut().as_mut_ptr() as *mut c_void,
+                buf.capacity(),
+                flags,
+            )
         })?;
-        Ok(ret as usize)
+        unsafe {
+            buf.advance(ret as usize);
+        }
+        Ok(())
     }
 
     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
-        self.recv_with_flags(buf, 0)
+        let mut buf = BorrowedBuf::from(buf);
+        self.recv_with_flags(buf.unfilled(), 0)?;
+        Ok(buf.len())
     }
 
     pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
-        self.recv_with_flags(buf, MSG_PEEK)
+        let mut buf = BorrowedBuf::from(buf);
+        self.recv_with_flags(buf.unfilled(), MSG_PEEK)?;
+        Ok(buf.len())
+    }
+
+    pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> {
+        self.recv_with_flags(buf, 0)
     }
 
     pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
diff --git a/library/std/src/sys/unix/pipe.rs b/library/std/src/sys/unix/pipe.rs
index a744d0ab64043..dc17c9fac460a 100644
--- a/library/std/src/sys/unix/pipe.rs
+++ b/library/std/src/sys/unix/pipe.rs
@@ -1,4 +1,4 @@
-use crate::io::{self, IoSlice, IoSliceMut};
+use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
 use crate::mem;
 use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
 use crate::sys::fd::FileDesc;
@@ -49,6 +49,10 @@ impl AnonPipe {
         self.0.read(buf)
     }
 
+    pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> {
+        self.0.read_buf(buf)
+    }
+
     pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         self.0.read_vectored(bufs)
     }
diff --git a/library/std/src/sys/unix/stdio.rs b/library/std/src/sys/unix/stdio.rs
index b3626c564e86a..a26f20795a191 100644
--- a/library/std/src/sys/unix/stdio.rs
+++ b/library/std/src/sys/unix/stdio.rs
@@ -1,4 +1,4 @@
-use crate::io::{self, IoSlice, IoSliceMut};
+use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
 use crate::mem::ManuallyDrop;
 use crate::os::unix::io::FromRawFd;
 use crate::sys::fd::FileDesc;
@@ -18,6 +18,10 @@ impl io::Read for Stdin {
         unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(libc::STDIN_FILENO)).read(buf) }
     }
 
+    fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> {
+        unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(libc::STDIN_FILENO)).read_buf(buf) }
+    }
+
     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(libc::STDIN_FILENO)).read_vectored(bufs) }
     }
diff --git a/library/std/src/sys/unsupported/pipe.rs b/library/std/src/sys/unsupported/pipe.rs
index 0bba673b458cb..d7d8f297ae586 100644
--- a/library/std/src/sys/unsupported/pipe.rs
+++ b/library/std/src/sys/unsupported/pipe.rs
@@ -1,4 +1,4 @@
-use crate::io::{self, IoSlice, IoSliceMut};
+use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
 
 pub struct AnonPipe(!);
 
@@ -7,6 +7,10 @@ impl AnonPipe {
         self.0
     }
 
+    pub fn read_buf(&self, _buf: BorrowedCursor<'_>) -> io::Result<()> {
+        self.0
+    }
+
     pub fn read_vectored(&self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         self.0
     }
diff --git a/library/std/src/sys/windows/handle.rs b/library/std/src/sys/windows/handle.rs
index ae33d48c612ee..b290f4070e8fd 100644
--- a/library/std/src/sys/windows/handle.rs
+++ b/library/std/src/sys/windows/handle.rs
@@ -327,7 +327,16 @@ impl<'a> Read for &'a Handle {
         (**self).read(buf)
     }
 
+    fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> {
+        (**self).read_buf(buf)
+    }
+
     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         (**self).read_vectored(bufs)
     }
+
+    #[inline]
+    fn is_read_vectored(&self) -> bool {
+        (**self).is_read_vectored()
+    }
 }
diff --git a/library/std/src/sys/windows/net.rs b/library/std/src/sys/windows/net.rs
index e0701a498fad7..ee1f5482b47ee 100644
--- a/library/std/src/sys/windows/net.rs
+++ b/library/std/src/sys/windows/net.rs
@@ -1,7 +1,7 @@
 #![unstable(issue = "none", feature = "windows_net")]
 
 use crate::cmp;
-use crate::io::{self, IoSlice, IoSliceMut, Read};
+use crate::io::{self, BorrowedBuf, BorrowedCursor, IoSlice, IoSliceMut, Read};
 use crate::mem;
 use crate::net::{Shutdown, SocketAddr};
 use crate::os::windows::io::{
@@ -214,28 +214,38 @@ impl Socket {
         Ok(Self(self.0.try_clone()?))
     }
 
-    fn recv_with_flags(&self, buf: &mut [u8], flags: c_int) -> io::Result<usize> {
+    fn recv_with_flags(&self, mut buf: BorrowedCursor<'_>, flags: c_int) -> io::Result<()> {
         // On unix when a socket is shut down all further reads return 0, so we
         // do the same on windows to map a shut down socket to returning EOF.
-        let length = cmp::min(buf.len(), i32::MAX as usize) as i32;
-        let result =
-            unsafe { c::recv(self.as_raw_socket(), buf.as_mut_ptr() as *mut _, length, flags) };
+        let length = cmp::min(buf.capacity(), i32::MAX as usize) as i32;
+        let result = unsafe {
+            c::recv(self.as_raw_socket(), buf.as_mut().as_mut_ptr() as *mut _, length, flags)
+        };
 
         match result {
             c::SOCKET_ERROR => {
                 let error = unsafe { c::WSAGetLastError() };
 
                 if error == c::WSAESHUTDOWN {
-                    Ok(0)
+                    Ok(())
                 } else {
                     Err(io::Error::from_raw_os_error(error))
                 }
             }
-            _ => Ok(result as usize),
+            _ => {
+                unsafe { buf.advance(result as usize) };
+                Ok(())
+            }
         }
     }
 
     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
+        let mut buf = BorrowedBuf::from(buf);
+        self.recv_with_flags(buf.unfilled(), 0)?;
+        Ok(buf.len())
+    }
+
+    pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> {
         self.recv_with_flags(buf, 0)
     }
 
@@ -277,7 +287,9 @@ impl Socket {
     }
 
     pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
-        self.recv_with_flags(buf, c::MSG_PEEK)
+        let mut buf = BorrowedBuf::from(buf);
+        self.recv_with_flags(buf.unfilled(), c::MSG_PEEK)?;
+        Ok(buf.len())
     }
 
     fn recv_from_with_flags(
diff --git a/library/std/src/sys/windows/pipe.rs b/library/std/src/sys/windows/pipe.rs
index 7b25edaa556f0..0780b29584da4 100644
--- a/library/std/src/sys/windows/pipe.rs
+++ b/library/std/src/sys/windows/pipe.rs
@@ -1,7 +1,7 @@
 use crate::os::windows::prelude::*;
 
 use crate::ffi::OsStr;
-use crate::io::{self, IoSlice, IoSliceMut, Read};
+use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read};
 use crate::mem;
 use crate::path::Path;
 use crate::ptr;
@@ -252,6 +252,28 @@ impl AnonPipe {
         }
     }
 
+    pub fn read_buf(&self, mut buf: BorrowedCursor<'_>) -> io::Result<()> {
+        let result = unsafe {
+            let len = crate::cmp::min(buf.capacity(), c::DWORD::MAX as usize) as c::DWORD;
+            self.alertable_io_internal(c::ReadFileEx, buf.as_mut().as_mut_ptr() as _, len)
+        };
+
+        match result {
+            // The special treatment of BrokenPipe is to deal with Windows
+            // pipe semantics, which yields this error when *reading* from
+            // a pipe after the other end has closed; we interpret that as
+            // EOF on the pipe.
+            Err(ref e) if e.kind() == io::ErrorKind::BrokenPipe => Ok(()),
+            Err(e) => Err(e),
+            Ok(n) => {
+                unsafe {
+                    buf.advance(n);
+                }
+                Ok(())
+            }
+        }
+    }
+
     pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         self.inner.read_vectored(bufs)
     }
diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs
index 2c38dfecf9734..ab988b97193c4 100644
--- a/library/std/src/sys_common/net.rs
+++ b/library/std/src/sys_common/net.rs
@@ -4,7 +4,7 @@ mod tests;
 use crate::cmp;
 use crate::convert::{TryFrom, TryInto};
 use crate::fmt;
-use crate::io::{self, ErrorKind, IoSlice, IoSliceMut};
+use crate::io::{self, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut};
 use crate::mem;
 use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
 use crate::ptr;
@@ -271,6 +271,10 @@ impl TcpStream {
         self.inner.read(buf)
     }
 
+    pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> {
+        self.inner.read_buf(buf)
+    }
+
     pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         self.inner.read_vectored(bufs)
     }
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index ff7821fb9ff08..cd19667139ab6 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -105,10 +105,15 @@ impl Step for Std {
             cargo.arg("--lib");
         }
 
-        builder.info(&format!(
-            "Checking stage{} library artifacts ({} -> {})",
-            builder.top_stage, &compiler.host, target
-        ));
+        let msg = if compiler.host == target {
+            format!("Checking stage{} library artifacts ({target})", builder.top_stage)
+        } else {
+            format!(
+                "Checking stage{} library artifacts ({} -> {})",
+                builder.top_stage, &compiler.host, target
+            )
+        };
+        builder.info(&msg);
         run_cargo(
             builder,
             cargo,
@@ -162,10 +167,18 @@ impl Step for Std {
             cargo.arg("-p").arg(krate.name);
         }
 
-        builder.info(&format!(
-            "Checking stage{} library test/bench/example targets ({} -> {})",
-            builder.top_stage, &compiler.host, target
-        ));
+        let msg = if compiler.host == target {
+            format!(
+                "Checking stage{} library test/bench/example targets ({target})",
+                builder.top_stage
+            )
+        } else {
+            format!(
+                "Checking stage{} library test/bench/example targets ({} -> {})",
+                builder.top_stage, &compiler.host, target
+            )
+        };
+        builder.info(&msg);
         run_cargo(
             builder,
             cargo,
@@ -239,10 +252,15 @@ impl Step for Rustc {
             cargo.arg("-p").arg(krate.name);
         }
 
-        builder.info(&format!(
-            "Checking stage{} compiler artifacts ({} -> {})",
-            builder.top_stage, &compiler.host, target
-        ));
+        let msg = if compiler.host == target {
+            format!("Checking stage{} compiler artifacts ({target})", builder.top_stage)
+        } else {
+            format!(
+                "Checking stage{} compiler artifacts ({} -> {})",
+                builder.top_stage, &compiler.host, target
+            )
+        };
+        builder.info(&msg);
         run_cargo(
             builder,
             cargo,
@@ -299,10 +317,15 @@ impl Step for CodegenBackend {
             .arg(builder.src.join(format!("compiler/rustc_codegen_{}/Cargo.toml", backend)));
         rustc_cargo_env(builder, &mut cargo, target);
 
-        builder.info(&format!(
-            "Checking stage{} {} artifacts ({} -> {})",
-            builder.top_stage, backend, &compiler.host.triple, target.triple
-        ));
+        let msg = if compiler.host == target {
+            format!("Checking stage{} {} artifacts ({target})", builder.top_stage, backend)
+        } else {
+            format!(
+                "Checking stage{} {} library ({} -> {})",
+                builder.top_stage, backend, &compiler.host.triple, target.triple
+            )
+        };
+        builder.info(&msg);
 
         run_cargo(
             builder,
@@ -362,10 +385,15 @@ impl Step for RustAnalyzer {
             cargo.arg("--benches");
         }
 
-        builder.info(&format!(
-            "Checking stage{} {} artifacts ({} -> {})",
-            compiler.stage, "rust-analyzer", &compiler.host.triple, target.triple
-        ));
+        let msg = if compiler.host == target {
+            format!("Checking stage{} {} artifacts ({target})", compiler.stage, "rust-analyzer")
+        } else {
+            format!(
+                "Checking stage{} {} artifacts ({} -> {})",
+                compiler.stage, "rust-analyzer", &compiler.host.triple, target.triple
+            )
+        };
+        builder.info(&msg);
         run_cargo(
             builder,
             cargo,
@@ -432,14 +460,18 @@ macro_rules! tool_check_step {
                 // NOTE: this doesn't enable lints for any other tools unless they explicitly add `#![warn(rustc::internal)]`
                 // See https://github.com/rust-lang/rust/pull/80573#issuecomment-754010776
                 cargo.rustflag("-Zunstable-options");
-
-                builder.info(&format!(
-                    "Checking stage{} {} artifacts ({} -> {})",
-                    builder.top_stage,
-                    stringify!($name).to_lowercase(),
-                    &compiler.host.triple,
-                    target.triple
-                ));
+                let msg = if compiler.host == target {
+                    format!("Checking stage{} {} artifacts ({target})", builder.top_stage, stringify!($name).to_lowercase())
+                } else {
+                    format!(
+                        "Checking stage{} {} artifacts ({} -> {})",
+                        builder.top_stage,
+                        stringify!($name).to_lowercase(),
+                        &compiler.host.triple,
+                        target.triple
+                    )
+                };
+                builder.info(&msg);
                 run_cargo(
                     builder,
                     cargo,
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 1e6c94d29ba47..b3fc889431b38 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -463,11 +463,10 @@ function initSearch(rawSearchIndex) {
      * @param {ParserState} parserState
      */
     function parseInput(query, parserState) {
-        let c, before;
         let foundStopChar = true;
 
         while (parserState.pos < parserState.length) {
-            c = parserState.userQuery[parserState.pos];
+            const c = parserState.userQuery[parserState.pos];
             if (isStopCharacter(c)) {
                 foundStopChar = true;
                 if (isSeparatorCharacter(c)) {
@@ -506,7 +505,7 @@ function initSearch(rawSearchIndex) {
                 }
                 throw new Error(`Expected \`,\`, \` \`, \`:\` or \`->\`, found \`${c}\``);
             }
-            before = query.elems.length;
+            const before = query.elems.length;
             getNextElem(query, parserState, query.elems, false);
             if (query.elems.length === before) {
                 // Nothing was added, weird... Let's increase the position to not remain stuck.
@@ -515,7 +514,6 @@ function initSearch(rawSearchIndex) {
             foundStopChar = false;
         }
         while (parserState.pos < parserState.length) {
-            c = parserState.userQuery[parserState.pos];
             if (isReturnArrow(parserState)) {
                 parserState.pos += 2;
                 // Get returned elements.
@@ -1940,7 +1938,6 @@ function initSearch(rawSearchIndex) {
          */
         const searchWords = [];
         const charA = "A".charCodeAt(0);
-        let i, word;
         let currentIndex = 0;
         let id = 0;
 
@@ -2035,7 +2032,7 @@ function initSearch(rawSearchIndex) {
             // convert `rawPaths` entries into object form
             // generate normalizedPaths for function search mode
             let len = paths.length;
-            for (i = 0; i < len; ++i) {
+            for (let i = 0; i < len; ++i) {
                 lowercasePaths.push({ty: paths[i][0], name: paths[i][1].toLowerCase()});
                 paths[i] = {ty: paths[i][0], name: paths[i][1]};
             }
@@ -2049,16 +2046,14 @@ function initSearch(rawSearchIndex) {
             // faster analysis operations
             len = itemTypes.length;
             let lastPath = "";
-            for (i = 0; i < len; ++i) {
+            for (let i = 0; i < len; ++i) {
+                let word = "";
                 // This object should have exactly the same set of fields as the "crateRow"
                 // object defined above.
                 if (typeof itemNames[i] === "string") {
                     word = itemNames[i].toLowerCase();
-                    searchWords.push(word);
-                } else {
-                    word = "";
-                    searchWords.push("");
                 }
+                searchWords.push(word);
                 const row = {
                     crate: crate,
                     ty: itemTypes.charCodeAt(i) - charA,
diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js
index 0e1c864e62d84..6c0f03b5bb072 100644
--- a/src/librustdoc/html/static/js/source-script.js
+++ b/src/librustdoc/html/static/js/source-script.js
@@ -117,8 +117,7 @@ function createSourceSidebar() {
     sidebar.appendChild(title);
     Object.keys(sourcesIndex).forEach(key => {
         sourcesIndex[key][NAME_OFFSET] = key;
-        hasFoundFile = createDirEntry(sourcesIndex[key], sidebar, "",
-            hasFoundFile);
+        hasFoundFile = createDirEntry(sourcesIndex[key], sidebar, "", hasFoundFile);
     });
 
     container.appendChild(sidebar);
diff --git a/src/llvm-project b/src/llvm-project
index 477e7285b12f8..fd949f3034f8a 160000
--- a/src/llvm-project
+++ b/src/llvm-project
@@ -1 +1 @@
-Subproject commit 477e7285b12f876ad105188cfcfc8adda7dc29aa
+Subproject commit fd949f3034f8a422ecfffa889c2823485dde4bdd
diff --git a/src/tools/miri/CONTRIBUTING.md b/src/tools/miri/CONTRIBUTING.md
index 5b538691de183..476075e9c914d 100644
--- a/src/tools/miri/CONTRIBUTING.md
+++ b/src/tools/miri/CONTRIBUTING.md
@@ -242,6 +242,13 @@ josh-proxy --local=$HOME/.cache/josh --remote=https://github.com --no-background
 
 This uses a directory `$HOME/.cache/josh` as a cache, to speed up repeated pulling/pushing.
 
+To make josh push via ssh instead of https, you can add the following to your `.gitconfig`:
+
+```toml
+[url "git@github.com:"]
+    pushInsteadOf = https://github.com/
+```
+
 ### Importing changes from the rustc repo
 
 Josh needs to be running, as described above.
diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md
index 48581f6bbff1a..1086d0481c835 100644
--- a/src/tools/miri/README.md
+++ b/src/tools/miri/README.md
@@ -213,7 +213,9 @@ degree documented below):
 - The best-supported target is `x86_64-unknown-linux-gnu`. Miri releases are
   blocked on things working with this target. Most other Linux targets should
   also work well; we do run the test suite on `i686-unknown-linux-gnu` as a
-  32bit target and `mips64-unknown-linux-gnuabi64` as a big-endian target.
+  32bit target and `mips64-unknown-linux-gnuabi64` as a big-endian target, as
+  well as the ARM targets `aarch64-unknown-linux-gnu` and
+  `arm-unknown-linux-gnueabi`.
 - `x86_64-apple-darwin` should work basically as well as Linux. We also test
   `aarch64-apple-darwin`. However, we might ship Miri with a nightly even when
   some features on these targets regress.
@@ -590,7 +592,7 @@ extern "Rust" {
     /// `out` must point to at least `out_size` many bytes, and the result will be stored there
     /// with a null terminator.
     /// Returns 0 if the `out` buffer was large enough, and the required size otherwise.
-    fn miri_host_to_target_path(path: *const i8, out: *mut i8, out_size: usize) -> usize;
+    fn miri_host_to_target_path(path: *const std::ffi::c_char, out: *mut std::ffi::c_char, out_size: usize) -> usize;
 }
 ```
 
diff --git a/src/tools/miri/cargo-miri/Cargo.lock b/src/tools/miri/cargo-miri/Cargo.lock
index 37926db0166b7..76badcf94afb3 100644
--- a/src/tools/miri/cargo-miri/Cargo.lock
+++ b/src/tools/miri/cargo-miri/Cargo.lock
@@ -193,9 +193,9 @@ checksum = "fc71d2faa173b74b232dedc235e3ee1696581bb132fc116fa3626d6151a1a8fb"
 
 [[package]]
 name = "rustc_tools_util"
-version = "0.2.1"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "598f48ce2a421542b3e64828aa742b687cc1b91d2f96591cfdb7ac5988cd6366"
+checksum = "8ba09476327c4b70ccefb6180f046ef588c26a24cf5d269a9feba316eb4f029f"
 
 [[package]]
 name = "rustc_version"
diff --git a/src/tools/miri/cargo-miri/Cargo.toml b/src/tools/miri/cargo-miri/Cargo.toml
index 2197160bc9d44..09079dbb818be 100644
--- a/src/tools/miri/cargo-miri/Cargo.toml
+++ b/src/tools/miri/cargo-miri/Cargo.toml
@@ -30,4 +30,4 @@ rustc-workspace-hack = "1.0.0"
 serde = { version = "*", features = ["derive"] }
 
 [build-dependencies]
-rustc_tools_util = "0.2"
+rustc_tools_util = "0.3"
diff --git a/src/tools/miri/cargo-miri/build.rs b/src/tools/miri/cargo-miri/build.rs
index c111011545590..52e2a083512c4 100644
--- a/src/tools/miri/cargo-miri/build.rs
+++ b/src/tools/miri/cargo-miri/build.rs
@@ -2,12 +2,5 @@ fn main() {
     // Don't rebuild miri when nothing changed.
     println!("cargo:rerun-if-changed=build.rs");
     // gather version info
-    println!(
-        "cargo:rustc-env=GIT_HASH={}",
-        rustc_tools_util::get_commit_hash().unwrap_or_default()
-    );
-    println!(
-        "cargo:rustc-env=COMMIT_DATE={}",
-        rustc_tools_util::get_commit_date().unwrap_or_default()
-    );
+    rustc_tools_util::setup_version_info!();
 }
diff --git a/src/tools/miri/ci.sh b/src/tools/miri/ci.sh
index e01bfbc74d98a..60450d0981545 100755
--- a/src/tools/miri/ci.sh
+++ b/src/tools/miri/ci.sh
@@ -104,6 +104,7 @@ run_tests
 case $HOST_TARGET in
   x86_64-unknown-linux-gnu)
     MIRI_TEST_TARGET=i686-unknown-linux-gnu run_tests
+    MIRI_TEST_TARGET=aarch64-unknown-linux-gnu run_tests
     MIRI_TEST_TARGET=aarch64-apple-darwin run_tests
     MIRI_TEST_TARGET=i686-pc-windows-msvc run_tests
     MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple atomic data_race env/var
@@ -118,6 +119,7 @@ case $HOST_TARGET in
     MIRI_TEST_TARGET=x86_64-pc-windows-msvc run_tests
     ;;
   i686-pc-windows-msvc)
+    MIRI_TEST_TARGET=arm-unknown-linux-gnueabi run_tests
     MIRI_TEST_TARGET=x86_64-unknown-linux-gnu run_tests
     MIRI_TEST_TARGET=x86_64-pc-windows-gnu run_tests
     ;;
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index cf6d9c2808048..53ec1ba0821b0 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-c54c8cbac882e149e04a9e1f2d146fd548ae30ae
+c4e0cd966062ca67daed20775f4e8a60c28e57df
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
index cf1ff603281ee..b766916402e4f 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
@@ -148,8 +148,7 @@ impl NewPermission {
             NewPermission::Uniform {
                 perm: Permission::Unique,
                 access: Some(AccessKind::Write),
-                protector: (kind == RetagKind::FnEntry)
-                    .then_some(ProtectorKind::WeakProtector),
+                protector: (kind == RetagKind::FnEntry).then_some(ProtectorKind::WeakProtector),
             }
         } else {
             // `!Unpin` boxes do not get `noalias` nor `dereferenceable`.
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index 7024927b20561..f64f216520f00 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -13,6 +13,7 @@
 #![allow(
     clippy::collapsible_else_if,
     clippy::collapsible_if,
+    clippy::if_same_then_else,
     clippy::comparison_chain,
     clippy::enum_variant_names,
     clippy::field_reassign_with_default,
@@ -21,7 +22,7 @@
     clippy::single_match,
     clippy::useless_format,
     clippy::derive_partial_eq_without_eq,
-    clippy::derive_hash_xor_eq,
+    clippy::derived_hash_with_manual_eq,
     clippy::too_many_arguments,
     clippy::type_complexity,
     clippy::single_element_loop,
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 8bd1e802f8a52..8bbf9f87b43e5 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -477,7 +477,8 @@ pub struct MiriMachine<'mir, 'tcx> {
 
 impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
     pub(crate) fn new(config: &MiriConfig, layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Self {
-        let local_crates = helpers::get_local_crates(layout_cx.tcx);
+        let tcx = layout_cx.tcx;
+        let local_crates = helpers::get_local_crates(tcx);
         let layouts =
             PrimitiveLayouts::new(layout_cx).expect("Couldn't get layouts of primitive types");
         let profiler = config.measureme_out.as_ref().map(|out| {
@@ -486,10 +487,13 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
         let rng = StdRng::seed_from_u64(config.seed.unwrap_or(0));
         let borrow_tracker = config.borrow_tracker.map(|bt| bt.instanciate_global_state(config));
         let data_race = config.data_race_detector.then(|| data_race::GlobalState::new(config));
+        // Determinine page size, stack address, and stack size.
+        // These values are mostly meaningless, but the stack address is also where we start
+        // allocating physical integer addresses for all allocations.
         let page_size = if let Some(page_size) = config.page_size {
             page_size
         } else {
-            let target = &layout_cx.tcx.sess.target;
+            let target = &tcx.sess.target;
             match target.arch.as_ref() {
                 "wasm32" | "wasm64" => 64 * 1024, // https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances
                 "aarch64" =>
@@ -504,10 +508,12 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
                 _ => 4 * 1024,
             }
         };
-        let stack_addr = page_size * 32;
-        let stack_size = page_size * 16;
+        // On 16bit targets, 32 pages is more than the entire address space!
+        let stack_addr = if tcx.pointer_size().bits() < 32 { page_size } else { page_size * 32 };
+        let stack_size =
+            if tcx.pointer_size().bits() < 32 { page_size * 4 } else { page_size * 16 };
         MiriMachine {
-            tcx: layout_cx.tcx,
+            tcx,
             borrow_tracker,
             data_race,
             intptrcast: RefCell::new(intptrcast::GlobalStateInner::new(config, stack_addr)),
@@ -902,8 +908,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
             };
             let (shim_size, shim_align, _kind) = ecx.get_alloc_info(alloc_id);
             let def_ty = ecx.tcx.type_of(def_id).subst_identity();
-            let extern_decl_layout =
-                ecx.tcx.layout_of(ty::ParamEnv::empty().and(def_ty)).unwrap();
+            let extern_decl_layout = ecx.tcx.layout_of(ty::ParamEnv::empty().and(def_ty)).unwrap();
             if extern_decl_layout.size != shim_size || extern_decl_layout.align.abi != shim_align {
                 throw_unsup_format!(
                     "`extern` static `{name}` from crate `{krate}` has been declared \
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index 2d9eb37a25806..03275ed4ed163 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -885,6 +885,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     }
                 }
             }
+            "llvm.arm.hint" if this.tcx.sess.target.arch == "arm" => {
+                let [arg] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
+                let arg = this.read_scalar(arg)?.to_i32()?;
+                match arg {
+                    // YIELD
+                    1 => {
+                        this.yield_active_thread();
+                    }
+                    _ => {
+                        throw_unsup_format!("unsupported llvm.arm.hint argument {}", arg);
+                    }
+                }
+            }
 
             // Platform-specific shims
             _ =>
diff --git a/src/tools/miri/src/shims/unix/linux/fd.rs b/src/tools/miri/src/shims/unix/linux/fd.rs
index 212b7936341a7..fd4927fa10ce3 100644
--- a/src/tools/miri/src/shims/unix/linux/fd.rs
+++ b/src/tools/miri/src/shims/unix/linux/fd.rs
@@ -7,6 +7,8 @@ use socketpair::SocketPair;
 
 use shims::unix::fs::EvalContextExt as _;
 
+use std::cell::Cell;
+
 pub mod epoll;
 pub mod event;
 pub mod socketpair;
@@ -101,6 +103,60 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         }
     }
 
+    /// The `epoll_wait()` system call waits for events on the `Epoll`
+    /// instance referred to by the file descriptor `epfd`. The buffer
+    /// pointed to by `events` is used to return information from the ready
+    /// list about file descriptors in the interest list that have some
+    /// events available. Up to `maxevents` are returned by `epoll_wait()`.
+    /// The `maxevents` argument must be greater than zero.
+
+    /// The `timeout` argument specifies the number of milliseconds that
+    /// `epoll_wait()` will block. Time is measured against the
+    /// CLOCK_MONOTONIC clock.
+
+    /// A call to `epoll_wait()` will block until either:
+    /// • a file descriptor delivers an event;
+    /// • the call is interrupted by a signal handler; or
+    /// • the timeout expires.
+
+    /// Note that the timeout interval will be rounded up to the system
+    /// clock granularity, and kernel scheduling delays mean that the
+    /// blocking interval may overrun by a small amount. Specifying a
+    /// timeout of -1 causes `epoll_wait()` to block indefinitely, while
+    /// specifying a timeout equal to zero cause `epoll_wait()` to return
+    /// immediately, even if no events are available.
+    ///
+    /// On success, `epoll_wait()` returns the number of file descriptors
+    /// ready for the requested I/O, or zero if no file descriptor became
+    /// ready during the requested timeout milliseconds. On failure,
+    /// `epoll_wait()` returns -1 and errno is set to indicate the error.
+    ///
+    /// <https://man7.org/linux/man-pages/man2/epoll_wait.2.html>
+    fn epoll_wait(
+        &mut self,
+        epfd: &OpTy<'tcx, Provenance>,
+        events: &OpTy<'tcx, Provenance>,
+        maxevents: &OpTy<'tcx, Provenance>,
+        timeout: &OpTy<'tcx, Provenance>,
+    ) -> InterpResult<'tcx, Scalar<Provenance>> {
+        let this = self.eval_context_mut();
+
+        let epfd = this.read_scalar(epfd)?.to_i32()?;
+        let _events = this.read_scalar(events)?.to_pointer(this)?;
+        let _maxevents = this.read_scalar(maxevents)?.to_i32()?;
+        let _timeout = this.read_scalar(timeout)?.to_i32()?;
+
+        let numevents = 0;
+        if let Some(epfd) = this.machine.file_handler.handles.get_mut(&epfd) {
+            let _epfd = epfd.as_epoll_handle()?;
+
+            // FIXME return number of events ready when scheme for marking events ready exists
+            Ok(Scalar::from_i32(numevents))
+        } else {
+            Ok(Scalar::from_i32(this.handle_not_found()?))
+        }
+    }
+
     /// This function creates an `Event` that is used as an event wait/notify mechanism by
     /// user-space applications, and by the kernel to notify user-space applications of events.
     /// The `Event` contains an `u64` counter maintained by the kernel. The counter is initialized
@@ -142,7 +198,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         }
 
         let fh = &mut this.machine.file_handler;
-        let fd = fh.insert_fd(Box::new(Event { val }));
+        let fd = fh.insert_fd(Box::new(Event { val: Cell::new(val.into()) }));
         Ok(Scalar::from_i32(fd))
     }
 
diff --git a/src/tools/miri/src/shims/unix/linux/fd/event.rs b/src/tools/miri/src/shims/unix/linux/fd/event.rs
index 239eb462a1d23..b28a6e0c56eca 100644
--- a/src/tools/miri/src/shims/unix/linux/fd/event.rs
+++ b/src/tools/miri/src/shims/unix/linux/fd/event.rs
@@ -2,6 +2,7 @@ use crate::shims::unix::fs::FileDescriptor;
 
 use rustc_const_eval::interpret::InterpResult;
 
+use std::cell::Cell;
 use std::io;
 
 /// A kind of file descriptor created by `eventfd`.
@@ -13,7 +14,9 @@ use std::io;
 /// <https://man.netbsd.org/eventfd.2>
 #[derive(Debug)]
 pub struct Event {
-    pub val: u32,
+    /// The object contains an unsigned 64-bit integer (uint64_t) counter that is maintained by the
+    /// kernel. This counter is initialized with the value specified in the argument initval.
+    pub val: Cell<u64>,
 }
 
 impl FileDescriptor for Event {
@@ -22,7 +25,7 @@ impl FileDescriptor for Event {
     }
 
     fn dup(&mut self) -> io::Result<Box<dyn FileDescriptor>> {
-        Ok(Box::new(Event { val: self.val }))
+        Ok(Box::new(Event { val: self.val.clone() }))
     }
 
     fn is_tty(&self) -> bool {
@@ -35,4 +38,32 @@ impl FileDescriptor for Event {
     ) -> InterpResult<'tcx, io::Result<i32>> {
         Ok(Ok(0))
     }
+
+    /// A write call adds the 8-byte integer value supplied in
+    /// its buffer to the counter.  The maximum value that may be
+    /// stored in the counter is the largest unsigned 64-bit value
+    /// minus 1 (i.e., 0xfffffffffffffffe).  If the addition would
+    /// cause the counter's value to exceed the maximum, then the
+    /// write either blocks until a read is performed on the
+    /// file descriptor, or fails with the error EAGAIN if the
+    /// file descriptor has been made nonblocking.
+
+    /// A write fails with the error EINVAL if the size of the
+    /// supplied buffer is less than 8 bytes, or if an attempt is
+    /// made to write the value 0xffffffffffffffff.
+    ///
+    /// FIXME: use endianness
+    fn write<'tcx>(
+        &self,
+        _communicate_allowed: bool,
+        bytes: &[u8],
+    ) -> InterpResult<'tcx, io::Result<usize>> {
+        let v1 = self.val.get();
+        // FIXME handle blocking when addition results in exceeding the max u64 value
+        // or fail with EAGAIN if the file descriptor is nonblocking.
+        let v2 = v1.checked_add(u64::from_be_bytes(bytes.try_into().unwrap())).unwrap();
+        self.val.set(v2);
+        assert_eq!(8, bytes.len());
+        Ok(Ok(8))
+    }
 }
diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs
index 9f6938424fb2d..f4e7824d91df4 100644
--- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs
@@ -55,6 +55,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let result = this.epoll_ctl(epfd, op, fd, event)?;
                 this.write_scalar(result, dest)?;
             }
+            "epoll_wait" => {
+                let [epfd, events, maxevents, timeout] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let result = this.epoll_wait(epfd, events, maxevents, timeout)?;
+                this.write_scalar(result, dest)?;
+            }
             "eventfd" => {
                 let [val, flag] =
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
diff --git a/src/tools/miri/test-cargo-miri/src/main.rs b/src/tools/miri/test-cargo-miri/src/main.rs
index 048dbbbaa0f06..048577ef15a61 100644
--- a/src/tools/miri/test-cargo-miri/src/main.rs
+++ b/src/tools/miri/test-cargo-miri/src/main.rs
@@ -23,7 +23,7 @@ fn main() {
     // (We rely on the test runner to always disable isolation when passing no arguments.)
     if std::env::args().len() <= 1 {
         fn host_to_target_path(path: String) -> PathBuf {
-            use std::ffi::{CStr, CString};
+            use std::ffi::{c_char, CStr, CString};
 
             let path = CString::new(path).unwrap();
             let mut out = Vec::with_capacity(1024);
@@ -31,8 +31,8 @@ fn main() {
             unsafe {
                 extern "Rust" {
                     fn miri_host_to_target_path(
-                        path: *const i8,
-                        out: *mut i8,
+                        path: *const c_char,
+                        out: *mut c_char,
                         out_size: usize,
                     ) -> usize;
                 }
diff --git a/src/tools/miri/test-cargo-miri/subcrate/main.rs b/src/tools/miri/test-cargo-miri/subcrate/main.rs
index 1cb8091f87750..52161098788b5 100644
--- a/src/tools/miri/test-cargo-miri/subcrate/main.rs
+++ b/src/tools/miri/test-cargo-miri/subcrate/main.rs
@@ -5,7 +5,7 @@ fn main() {
     println!("subcrate running");
 
     fn host_to_target_path(path: String) -> PathBuf {
-        use std::ffi::{CStr, CString};
+        use std::ffi::{c_char, CStr, CString};
 
         let path = CString::new(path).unwrap();
         let mut out = Vec::with_capacity(1024);
@@ -13,8 +13,8 @@ fn main() {
         unsafe {
             extern "Rust" {
                 fn miri_host_to_target_path(
-                    path: *const i8,
-                    out: *mut i8,
+                    path: *const c_char,
+                    out: *mut c_char,
                     out_size: usize,
                 ) -> usize;
             }
diff --git a/src/tools/miri/test-cargo-miri/subcrate/test.rs b/src/tools/miri/test-cargo-miri/subcrate/test.rs
index 619d8c72fd0a7..1681c721dc2e2 100644
--- a/src/tools/miri/test-cargo-miri/subcrate/test.rs
+++ b/src/tools/miri/test-cargo-miri/subcrate/test.rs
@@ -8,7 +8,7 @@ fn main() {
     println!("subcrate testing");
 
     fn host_to_target_path(path: String) -> PathBuf {
-        use std::ffi::{CStr, CString};
+        use std::ffi::{c_char, CStr, CString};
 
         let path = CString::new(path).unwrap();
         let mut out = Vec::with_capacity(1024);
@@ -16,8 +16,8 @@ fn main() {
         unsafe {
             extern "Rust" {
                 fn miri_host_to_target_path(
-                    path: *const i8,
-                    out: *mut i8,
+                    path: *const c_char,
+                    out: *mut c_char,
                     out_size: usize,
                 ) -> usize;
             }
diff --git a/src/tools/miri/test_dependencies/Cargo.lock b/src/tools/miri/test_dependencies/Cargo.lock
index a84ed85976367..8be1ee54672d8 100644
--- a/src/tools/miri/test_dependencies/Cargo.lock
+++ b/src/tools/miri/test_dependencies/Cargo.lock
@@ -292,9 +292,9 @@ dependencies = [
 
 [[package]]
 name = "tokio"
-version = "1.23.1"
+version = "1.24.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38a54aca0c15d014013256222ba0ebed095673f89345dd79119d912eb561b7a8"
+checksum = "597a12a59981d9e3c38d216785b0c37399f6e415e8d0712047620f189371b0bb"
 dependencies = [
  "autocfg",
  "bytes",
diff --git a/src/tools/miri/test_dependencies/Cargo.toml b/src/tools/miri/test_dependencies/Cargo.toml
index f5ab6acf008c5..d1ff33379e40a 100644
--- a/src/tools/miri/test_dependencies/Cargo.toml
+++ b/src/tools/miri/test_dependencies/Cargo.toml
@@ -18,6 +18,6 @@ rand = { version = "0.8", features = ["small_rng"] }
 
 [target.'cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))'.dependencies]
 page_size = "0.5"
-tokio = { version = "1.23", features = ["full"] }
+tokio = { version = "1.24", features = ["full"] }
 
 [workspace]
diff --git a/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.rs b/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.rs
index 816b6ab9fb32f..4a43db0aac50a 100644
--- a/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.rs
+++ b/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.rs
@@ -3,7 +3,7 @@
 
 #![allow(dead_code, unused_variables)]
 
-use std::{ptr, mem};
+use std::{mem, ptr};
 
 #[repr(packed)]
 struct Foo {
diff --git a/src/tools/miri/tests/pass-dep/shims/libc-fs.rs b/src/tools/miri/tests/pass-dep/shims/libc-fs.rs
index ba5b269f65242..cd071a7f32ac1 100644
--- a/src/tools/miri/tests/pass-dep/shims/libc-fs.rs
+++ b/src/tools/miri/tests/pass-dep/shims/libc-fs.rs
@@ -5,7 +5,7 @@
 #![feature(io_error_uncategorized)]
 
 use std::convert::TryInto;
-use std::ffi::{CStr, CString};
+use std::ffi::{c_char, CStr, CString};
 use std::fs::{canonicalize, remove_dir_all, remove_file, File};
 use std::io::{Error, ErrorKind, Write};
 use std::os::unix::ffi::OsStrExt;
@@ -31,7 +31,11 @@ fn tmp() -> PathBuf {
 
     unsafe {
         extern "Rust" {
-            fn miri_host_to_target_path(path: *const i8, out: *mut i8, out_size: usize) -> usize;
+            fn miri_host_to_target_path(
+                path: *const c_char,
+                out: *mut c_char,
+                out_size: usize,
+            ) -> usize;
         }
         let ret = miri_host_to_target_path(path.as_ptr(), out.as_mut_ptr(), out.capacity());
         assert_eq!(ret, 0);
diff --git a/src/tools/miri/tests/pass-dep/shims/libc-misc.rs b/src/tools/miri/tests/pass-dep/shims/libc-misc.rs
index 20e96a92c7c5f..98e1c3a0adb2e 100644
--- a/src/tools/miri/tests/pass-dep/shims/libc-misc.rs
+++ b/src/tools/miri/tests/pass-dep/shims/libc-misc.rs
@@ -7,7 +7,7 @@ use std::os::unix::io::AsRawFd;
 use std::path::PathBuf;
 
 fn tmp() -> PathBuf {
-    use std::ffi::{CStr, CString};
+    use std::ffi::{c_char, CStr, CString};
 
     let path = std::env::var("MIRI_TEMP")
         .unwrap_or_else(|_| std::env::temp_dir().into_os_string().into_string().unwrap());
@@ -17,7 +17,11 @@ fn tmp() -> PathBuf {
 
     unsafe {
         extern "Rust" {
-            fn miri_host_to_target_path(path: *const i8, out: *mut i8, out_size: usize) -> usize;
+            fn miri_host_to_target_path(
+                path: *const c_char,
+                out: *mut c_char,
+                out_size: usize,
+            ) -> usize;
         }
         let ret = miri_host_to_target_path(path.as_ptr(), out.as_mut_ptr(), out.capacity());
         assert_eq!(ret, 0);
diff --git a/src/tools/miri/tests/pass-dep/tokio/sleep.rs b/src/tools/miri/tests/pass-dep/tokio/sleep.rs
new file mode 100644
index 0000000000000..1341484dda475
--- /dev/null
+++ b/src/tools/miri/tests/pass-dep/tokio/sleep.rs
@@ -0,0 +1,14 @@
+//@compile-flags: -Zmiri-disable-isolation -Zmiri-permissive-provenance -Zmiri-backtrace=full
+//@only-target-x86_64-unknown-linux: support for tokio only on linux and x86
+
+use tokio::time::{sleep, Duration, Instant};
+
+#[tokio::main]
+async fn main() {
+    let start = Instant::now();
+    sleep(Duration::from_secs(1)).await;
+    // It takes 96 millisecond to sleep for 1 millisecond
+    // It takes 1025 millisecond to sleep for 1 second
+    let time_elapsed = &start.elapsed().as_millis();
+    assert!(time_elapsed > &1000, "{}", time_elapsed);
+}
diff --git a/src/tools/miri/tests/pass-dep/tokio_mvp.rs b/src/tools/miri/tests/pass-dep/tokio/tokio_mvp.rs
similarity index 88%
rename from src/tools/miri/tests/pass-dep/tokio_mvp.rs
rename to src/tools/miri/tests/pass-dep/tokio/tokio_mvp.rs
index 642168253c2fa..0bca7cc069a78 100644
--- a/src/tools/miri/tests/pass-dep/tokio_mvp.rs
+++ b/src/tools/miri/tests/pass-dep/tokio/tokio_mvp.rs
@@ -1,5 +1,5 @@
 // Need to disable preemption to stay on the supported MVP codepath in mio.
-//@compile-flags: -Zmiri-disable-isolation -Zmiri-permissive-provenance -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-disable-isolation -Zmiri-permissive-provenance
 //@only-target-x86_64-unknown-linux: support for tokio exists only on linux and x86
 
 #[tokio::main]
diff --git a/src/tools/miri/tests/pass/dyn-star.rs b/src/tools/miri/tests/pass/dyn-star.rs
index 16a8cec6cdae1..1fac16352a448 100644
--- a/src/tools/miri/tests/pass/dyn-star.rs
+++ b/src/tools/miri/tests/pass/dyn-star.rs
@@ -1,5 +1,8 @@
 #![feature(dyn_star)]
 #![allow(incomplete_features)]
+#![feature(custom_inner_attributes)]
+// rustfmt destroys `dyn* Trait` syntax
+#![rustfmt::skip]
 
 use std::fmt::{Debug, Display};
 
diff --git a/src/tools/miri/tests/pass/move-data-across-await-point.rs b/src/tools/miri/tests/pass/move-data-across-await-point.rs
new file mode 100644
index 0000000000000..489fae66ffb2b
--- /dev/null
+++ b/src/tools/miri/tests/pass/move-data-across-await-point.rs
@@ -0,0 +1,81 @@
+use std::future::Future;
+use std::ptr;
+
+// This test:
+// - Compares addresses of non-Copy data before and after moving it
+// - Writes to the pointer after it has moved across the await point
+//
+// This is only meant to assert current behavior, not guarantee that this is
+// how it should work in the future. In fact, upcoming changes to rustc
+// *should* break these tests.
+// See: https://github.com/rust-lang/rust/issues/62958
+async fn data_moved_async() {
+    async fn helper(mut data: Vec<u8>, raw_pointer: *mut Vec<u8>) {
+        let raw_pointer2 = ptr::addr_of_mut!(data);
+        // `raw_pointer` points to the original location where the Vec was stored in the caller.
+        // `data` is where that Vec (to be precise, its ptr+capacity+len on-stack data)
+        // got moved to. Those will usually not be the same since the Vec got moved twice
+        // (into the function call, and then into the generator upvar).
+        assert_ne!(raw_pointer, raw_pointer2);
+        unsafe {
+            // This writes into the `x` in `data_moved_async`, re-initializing it.
+            std::ptr::write(raw_pointer, vec![3]);
+        }
+    }
+    // Vec<T> is not Copy
+    let mut x: Vec<u8> = vec![2];
+    let raw_pointer = ptr::addr_of_mut!(x);
+    helper(x, raw_pointer).await;
+    unsafe {
+        assert_eq!(*raw_pointer, vec![3]);
+        // Drop to prevent leak.
+        std::ptr::drop_in_place(raw_pointer);
+    }
+}
+
+// Same thing as above, but non-async.
+fn data_moved() {
+    fn helper(mut data: Vec<u8>, raw_pointer: *mut Vec<u8>) {
+        let raw_pointer2 = ptr::addr_of_mut!(data);
+        assert_ne!(raw_pointer, raw_pointer2);
+        unsafe {
+            std::ptr::write(raw_pointer, vec![3]);
+        }
+    }
+
+    let mut x: Vec<u8> = vec![2];
+    let raw_pointer = ptr::addr_of_mut!(x);
+    helper(x, raw_pointer);
+    unsafe {
+        assert_eq!(*raw_pointer, vec![3]);
+        std::ptr::drop_in_place(raw_pointer);
+    }
+}
+
+fn run_fut<T>(fut: impl Future<Output = T>) -> T {
+    use std::sync::Arc;
+    use std::task::{Context, Poll, Wake, Waker};
+
+    struct MyWaker;
+    impl Wake for MyWaker {
+        fn wake(self: Arc<Self>) {
+            unimplemented!()
+        }
+    }
+
+    let waker = Waker::from(Arc::new(MyWaker));
+    let mut context = Context::from_waker(&waker);
+
+    let mut pinned = Box::pin(fut);
+    loop {
+        match pinned.as_mut().poll(&mut context) {
+            Poll::Pending => continue,
+            Poll::Ready(v) => return v,
+        }
+    }
+}
+
+fn main() {
+    run_fut(data_moved_async());
+    data_moved();
+}
diff --git a/src/tools/miri/tests/pass/shims/fs.rs b/src/tools/miri/tests/pass/shims/fs.rs
index a7d4800faecc4..7a9974f393895 100644
--- a/src/tools/miri/tests/pass/shims/fs.rs
+++ b/src/tools/miri/tests/pass/shims/fs.rs
@@ -6,7 +6,7 @@
 #![feature(is_terminal)]
 
 use std::collections::HashMap;
-use std::ffi::OsString;
+use std::ffi::{c_char, OsString};
 use std::fs::{
     canonicalize, create_dir, read_dir, read_link, remove_dir, remove_dir_all, remove_file, rename,
     File, OpenOptions,
@@ -39,7 +39,11 @@ fn host_to_target_path(path: String) -> PathBuf {
 
     unsafe {
         extern "Rust" {
-            fn miri_host_to_target_path(path: *const i8, out: *mut i8, out_size: usize) -> usize;
+            fn miri_host_to_target_path(
+                path: *const c_char,
+                out: *mut c_char,
+                out_size: usize,
+            ) -> usize;
         }
         let ret = miri_host_to_target_path(path.as_ptr(), out.as_mut_ptr(), out.capacity());
         assert_eq!(ret, 0);
diff --git a/tests/ui/numbers-arithmetic/issue-105626.rs b/tests/ui/numbers-arithmetic/issue-105626.rs
new file mode 100644
index 0000000000000..f97edd510c9e6
--- /dev/null
+++ b/tests/ui/numbers-arithmetic/issue-105626.rs
@@ -0,0 +1,17 @@
+// run-pass
+// only-x86
+// min-system-llvm-version: 16
+// compile-flags: -Ctarget-feature=+sse2
+
+use std::hint::black_box;
+
+fn main() {
+    let n: i64 = black_box(0x3fffffdfffffff);
+    let r = f32::from_bits(0x5a7fffff);
+
+    assert_ne!((n as f64) as f32, n as f32);
+
+    // FIXME: these assertions fail if only x87 is enabled
+    assert_eq!(n as i64 as f32, r);
+    assert_eq!(n as u64 as f32, r);
+}
diff --git a/tests/ui/parser/match-arm-without-braces.stderr b/tests/ui/parser/match-arm-without-braces.stderr
index 37d55aa53f87c..ee1c8e562fc33 100644
--- a/tests/ui/parser/match-arm-without-braces.stderr
+++ b/tests/ui/parser/match-arm-without-braces.stderr
@@ -2,10 +2,14 @@ error: `match` arm body without braces
   --> $DIR/match-arm-without-braces.rs:26:27
    |
 LL |         Some(Val::Foo) => 3;
-   |                        -- ^- help: use a comma to end a `match` arm expression: `,`
-   |                        |  |
-   |                        |  this statement is not surrounded by a body
+   |                        -- ^ this statement is not surrounded by a body
+   |                        |
    |                        while parsing the `match` arm starting here
+   |
+help: replace `;` with `,` to end a `match` arm expression
+   |
+LL |         Some(Val::Foo) => 3,
+   |                            ~
 
 error: `match` arm body without braces
   --> $DIR/match-arm-without-braces.rs:31:11
diff --git a/tests/ui/tool-attributes/duplicate-diagnostic.rs b/tests/ui/tool-attributes/duplicate-diagnostic.rs
index 39c2ca1cb860c..e2cf9508757be 100644
--- a/tests/ui/tool-attributes/duplicate-diagnostic.rs
+++ b/tests/ui/tool-attributes/duplicate-diagnostic.rs
@@ -9,5 +9,5 @@ extern crate p1;
 extern crate p2;
 
 #[rustc_diagnostic_item = "Foo"]
-pub struct Foo {} //~ ERROR duplicate diagnostic item found
+pub struct Foo {} //~ ERROR duplicate diagnostic item in crate `duplicate_diagnostic`: `Foo`
 fn main() {}
diff --git a/tests/ui/tool-attributes/duplicate-diagnostic.stderr b/tests/ui/tool-attributes/duplicate-diagnostic.stderr
index e315fdc7d84bc..26bd6a82e3417 100644
--- a/tests/ui/tool-attributes/duplicate-diagnostic.stderr
+++ b/tests/ui/tool-attributes/duplicate-diagnostic.stderr
@@ -2,11 +2,13 @@ error: duplicate diagnostic item in crate `p2`: `Foo`.
    |
    = note: the diagnostic item is first defined in crate `p1`.
 
-error: duplicate diagnostic item found: `Foo`.
+error: duplicate diagnostic item in crate `duplicate_diagnostic`: `Foo`.
   --> $DIR/duplicate-diagnostic.rs:12:1
    |
 LL | pub struct Foo {}
    | ^^^^^^^^^^^^^^
+   |
+   = note: the diagnostic item is first defined in crate `p2`.
 
 error: aborting due to 2 previous errors