about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-12-17 10:18:25 +0000
committerbors <bors@rust-lang.org>2023-12-17 10:18:25 +0000
commit5151b8c42712c473e7da56e213926b929d0212ef (patch)
tree88a1e7487fd90048710e1e6aa58e93a0350e5f47
parent9f13b9d9cafa8df425dedf124e7b7e30f01ff231 (diff)
parent00a82a5f3cbbab07e90fe80ec127778abea62f4e (diff)
Auto merge of #119039 - RalfJung:miri, r=RalfJung
Miri subtree update

r? `@ghost`
-rw-r--r--src/tools/miri/CONTRIBUTING.md2
-rw-r--r--src/tools/miri/cargo-miri/src/util.rs3
-rwxr-xr-xsrc/tools/miri/miri5
-rw-r--r--src/tools/miri/miri-script/src/util.rs4
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/borrow_tracker/mod.rs16
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs4
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs3
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs4
-rw-r--r--src/tools/miri/src/shims/unix/linux/mem.rs2
-rw-r--r--src/tools/miri/src/shims/unix/mem.rs6
-rw-r--r--src/tools/miri/src/shims/x86/mod.rs288
-rw-r--r--src/tools/miri/src/shims/x86/sse.rs130
-rw-r--r--src/tools/miri/src/shims/x86/sse41.rs149
-rwxr-xr-xsrc/tools/miri/test-cargo-miri/run-test.py2
-rw-r--r--src/tools/miri/tests/pass-dep/shims/mmap.rs79
-rw-r--r--src/tools/miri/tests/pass/async-fn.rs25
-rw-r--r--src/tools/miri/tests/pass/coroutine.rs31
-rw-r--r--src/tools/miri/tests/pass/dyn-star.rs18
-rw-r--r--src/tools/miri/tests/pass/enum-nullable-const-null-with-fields.rs1
-rw-r--r--src/tools/miri/tests/pass/future-self-referential.rs18
-rw-r--r--src/tools/miri/tests/pass/intrinsics-x86-sse41.rs5
-rw-r--r--src/tools/miri/tests/pass/issues/issue-miri-2068.rs18
-rw-r--r--src/tools/miri/tests/pass/move-data-across-await-point.rs13
-rw-r--r--src/tools/miri/tests/pass/protector-gc.rs17
25 files changed, 491 insertions, 354 deletions
diff --git a/src/tools/miri/CONTRIBUTING.md b/src/tools/miri/CONTRIBUTING.md
index 40a4332cdb9..7a49ff3372f 100644
--- a/src/tools/miri/CONTRIBUTING.md
+++ b/src/tools/miri/CONTRIBUTING.md
@@ -109,7 +109,7 @@ to run the other checks while ignoring the ui output, use `MIRI_SKIP_UI_CHECKS=1
 
 For more info on how to configure ui tests see [the documentation on the ui test crate][ui_test]
 
-[ui_test]: ui_test/README.md
+[ui_test]: https://github.com/oli-obk/ui_test/blob/main/README.md
 
 ### Testing `cargo miri`
 
diff --git a/src/tools/miri/cargo-miri/src/util.rs b/src/tools/miri/cargo-miri/src/util.rs
index 6381a4db861..3c591268455 100644
--- a/src/tools/miri/cargo-miri/src/util.rs
+++ b/src/tools/miri/cargo-miri/src/util.rs
@@ -200,9 +200,6 @@ pub fn ask_to_run(mut cmd: Command, ask: bool, text: &str) {
 // cargo invocation.
 fn cargo_extra_flags() -> Vec<String> {
     let mut flags = Vec::new();
-    // `-Zunstable-options` is required by `--config`.
-    flags.push("-Zunstable-options".to_string());
-
     // Forward `--config` flags.
     let config_flag = "--config";
     for arg in get_arg_flag_values(config_flag) {
diff --git a/src/tools/miri/miri b/src/tools/miri/miri
index e21738c3618..169f4521f2d 100755
--- a/src/tools/miri/miri
+++ b/src/tools/miri/miri
@@ -2,5 +2,6 @@
 set -e
 # Instead of doing just `cargo run --manifest-path .. $@`, we invoke miri-script binary directly. Invoking `cargo run` goes through
 # rustup (that sets it's own environmental variables), which is undesirable.
-cargo build $CARGO_EXTRA_FLAGS -q --manifest-path "$(dirname "$0")"/miri-script/Cargo.toml
-"$(dirname "$0")"/miri-script/target/debug/miri-script "$@"
+MIRI_SCRIPT_TARGET_DIR="$(dirname "$0")"/miri-script/target
+cargo build $CARGO_EXTRA_FLAGS -q --target-dir "$MIRI_SCRIPT_TARGET_DIR" --manifest-path "$(dirname "$0")"/miri-script/Cargo.toml
+"$MIRI_SCRIPT_TARGET_DIR"/debug/miri-script "$@"
diff --git a/src/tools/miri/miri-script/src/util.rs b/src/tools/miri/miri-script/src/util.rs
index 64e780b61a7..c9bc55848df 100644
--- a/src/tools/miri/miri-script/src/util.rs
+++ b/src/tools/miri/miri-script/src/util.rs
@@ -73,7 +73,9 @@ impl MiriEnv {
             flags.push("-C link-args=-Wl,-rpath,");
             flags.push(libdir);
             // Enable rustc-specific lints (ignored without `-Zunstable-options`).
-            flags.push(" -Zunstable-options -Wrustc::internal -Wrust_2018_idioms -Wunused_lifetimes -Wsemicolon_in_expressions_from_macros");
+            flags.push(
+                " -Zunstable-options -Wrustc::internal -Wrust_2018_idioms -Wunused_lifetimes",
+            );
             // Add user-defined flags.
             if let Some(value) = std::env::var_os("RUSTFLAGS") {
                 flags.push(" ");
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index c60249f35e1..e82b7f84154 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-317d14a56cb8c748bf0e2f2afff89c2249ab4423
+604f185fae9a4b0edf7e28f616a0f53880f8f074
diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs
index 8fae5269229..a6961208ffb 100644
--- a/src/tools/miri/src/borrow_tracker/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/mod.rs
@@ -65,7 +65,7 @@ pub struct FrameState {
     /// incremental updates of the global list of protected tags stored in the
     /// `stacked_borrows::GlobalState` upon function return, and if we attempt to pop a protected
     /// tag, to identify which call is responsible for protecting the tag.
-    /// See `Stack::item_popped` for more explanation.
+    /// See `Stack::item_invalidated` for more explanation.
     /// Tree Borrows also needs to know which allocation these tags
     /// belong to so that it can perform a read through them immediately before
     /// the frame gets popped.
@@ -76,8 +76,10 @@ pub struct FrameState {
 }
 
 impl VisitProvenance for FrameState {
-    fn visit_provenance(&self, _visit: &mut VisitWith<'_>) {
-        // `protected_tags` are already recorded by `GlobalStateInner`.
+    fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
+        for (id, tag) in &self.protected_tags {
+            visit(Some(*id), Some(*tag));
+        }
     }
 }
 
@@ -98,7 +100,7 @@ pub struct GlobalStateInner {
     /// An item is protected if its tag is in this set, *and* it has the "protected" bit set.
     /// We add tags to this when they are created with a protector in `reborrow`, and
     /// we remove tags from this when the call which is protecting them returns, in
-    /// `GlobalStateInner::end_call`. See `Stack::item_popped` for more details.
+    /// `GlobalStateInner::end_call`. See `Stack::item_invalidated` for more details.
     protected_tags: FxHashMap<BorTag, ProtectorKind>,
     /// The pointer ids to trace
     tracked_pointer_tags: FxHashSet<BorTag>,
@@ -111,10 +113,8 @@ pub struct GlobalStateInner {
 }
 
 impl VisitProvenance for GlobalStateInner {
-    fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
-        for &tag in self.protected_tags.keys() {
-            visit(None, Some(tag));
-        }
+    fn visit_provenance(&self, _visit: &mut VisitWith<'_>) {
+        // All the provenance in protected_tags is also stored in FrameState, and visited there.
         // The only other candidate is base_ptr_tags, and that does not need visiting since we don't ever
         // GC the bottommost/root tag.
     }
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs
index b31f51e5a5c..b964b1f9ec2 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs
@@ -5,9 +5,7 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_span::{Span, SpanData};
 use rustc_target::abi::Size;
 
-use crate::borrow_tracker::{
-    AccessKind, GlobalStateInner, ProtectorKind,
-};
+use crate::borrow_tracker::{AccessKind, GlobalStateInner, ProtectorKind};
 use crate::*;
 
 /// Error reporting
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 345c71f75b3..eac315d0436 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
@@ -18,7 +18,8 @@ use rustc_target::abi::{Abi, Size};
 
 use crate::borrow_tracker::{
     stacked_borrows::diagnostics::{AllocHistory, DiagnosticCx, DiagnosticCxBuilder},
-    AccessKind, GlobalStateInner, ProtectorKind,};
+    AccessKind, GlobalStateInner, ProtectorKind,
+};
 use crate::*;
 
 use diagnostics::{RetagCause, RetagInfo};
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
index 84e4e0f2222..573d13bf4a5 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
@@ -2,9 +2,7 @@ use log::trace;
 
 use rustc_target::abi::{Abi, Size};
 
-use crate::borrow_tracker::{
-    AccessKind, GlobalState, GlobalStateInner, ProtectorKind,
-};
+use crate::borrow_tracker::{AccessKind, GlobalState, GlobalStateInner, ProtectorKind};
 use rustc_middle::{
     mir::{Mutability, RetagKind},
     ty::{
diff --git a/src/tools/miri/src/shims/unix/linux/mem.rs b/src/tools/miri/src/shims/unix/linux/mem.rs
index 026fd6ae5e7..d1b4416cb1d 100644
--- a/src/tools/miri/src/shims/unix/linux/mem.rs
+++ b/src/tools/miri/src/shims/unix/linux/mem.rs
@@ -38,7 +38,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         if flags & this.eval_libc_i32("MREMAP_MAYMOVE") == 0 {
             // We only support MREMAP_MAYMOVE, so not passing the flag is just a failure
             this.set_last_error(Scalar::from_i32(this.eval_libc_i32("EINVAL")))?;
-            return Ok(Scalar::from_maybe_pointer(Pointer::null(), this));
+            return Ok(this.eval_libc("MAP_FAILED"));
         }
 
         let old_address = Machine::ptr_from_addr_cast(this, old_address)?;
diff --git a/src/tools/miri/src/shims/unix/mem.rs b/src/tools/miri/src/shims/unix/mem.rs
index cf36d4b191c..5b84f047f49 100644
--- a/src/tools/miri/src/shims/unix/mem.rs
+++ b/src/tools/miri/src/shims/unix/mem.rs
@@ -48,11 +48,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         // First, we do some basic argument validation as required by mmap
         if (flags & (map_private | map_shared)).count_ones() != 1 {
             this.set_last_error(Scalar::from_i32(this.eval_libc_i32("EINVAL")))?;
-            return Ok(Scalar::from_maybe_pointer(Pointer::null(), this));
+            return Ok(this.eval_libc("MAP_FAILED"));
         }
         if length == 0 {
             this.set_last_error(Scalar::from_i32(this.eval_libc_i32("EINVAL")))?;
-            return Ok(Scalar::from_maybe_pointer(Pointer::null(), this));
+            return Ok(this.eval_libc("MAP_FAILED"));
         }
 
         // If a user tries to map a file, we want to loudly inform them that this is not going
@@ -72,7 +72,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         // Miri doesn't support MAP_FIXED or any any protections other than PROT_READ|PROT_WRITE.
         if flags & map_fixed != 0 || prot != prot_read | prot_write {
             this.set_last_error(Scalar::from_i32(this.eval_libc_i32("ENOTSUP")))?;
-            return Ok(Scalar::from_maybe_pointer(Pointer::null(), this));
+            return Ok(this.eval_libc("MAP_FAILED"));
         }
 
         // Miri does not support shared mappings, or any of the other extensions that for example
diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs
index 2ae269db412..1aaf820f460 100644
--- a/src/tools/miri/src/shims/x86/mod.rs
+++ b/src/tools/miri/src/shims/x86/mod.rs
@@ -1,3 +1,6 @@
+use rand::Rng as _;
+
+use rustc_apfloat::{ieee::Single, Float as _};
 use rustc_middle::{mir, ty};
 use rustc_span::Symbol;
 use rustc_target::abi::Size;
@@ -331,6 +334,210 @@ fn bin_op_simd_float_all<'tcx, F: rustc_apfloat::Float>(
     Ok(())
 }
 
+#[derive(Copy, Clone)]
+enum FloatUnaryOp {
+    /// sqrt(x)
+    ///
+    /// <https://www.felixcloutier.com/x86/sqrtss>
+    /// <https://www.felixcloutier.com/x86/sqrtps>
+    Sqrt,
+    /// Approximation of 1/x
+    ///
+    /// <https://www.felixcloutier.com/x86/rcpss>
+    /// <https://www.felixcloutier.com/x86/rcpps>
+    Rcp,
+    /// Approximation of 1/sqrt(x)
+    ///
+    /// <https://www.felixcloutier.com/x86/rsqrtss>
+    /// <https://www.felixcloutier.com/x86/rsqrtps>
+    Rsqrt,
+}
+
+/// Performs `which` scalar operation on `op` and returns the result.
+#[allow(clippy::arithmetic_side_effects)] // floating point operations without side effects
+fn unary_op_f32<'tcx>(
+    this: &mut crate::MiriInterpCx<'_, 'tcx>,
+    which: FloatUnaryOp,
+    op: &ImmTy<'tcx, Provenance>,
+) -> InterpResult<'tcx, Scalar<Provenance>> {
+    match which {
+        FloatUnaryOp::Sqrt => {
+            let op = op.to_scalar();
+            // FIXME using host floats
+            Ok(Scalar::from_u32(f32::from_bits(op.to_u32()?).sqrt().to_bits()))
+        }
+        FloatUnaryOp::Rcp => {
+            let op = op.to_scalar().to_f32()?;
+            let div = (Single::from_u128(1).value / op).value;
+            // Apply a relative error with a magnitude on the order of 2^-12 to simulate the
+            // inaccuracy of RCP.
+            let res = apply_random_float_error(this, div, -12);
+            Ok(Scalar::from_f32(res))
+        }
+        FloatUnaryOp::Rsqrt => {
+            let op = op.to_scalar().to_u32()?;
+            // FIXME using host floats
+            let sqrt = Single::from_bits(f32::from_bits(op).sqrt().to_bits().into());
+            let rsqrt = (Single::from_u128(1).value / sqrt).value;
+            // Apply a relative error with a magnitude on the order of 2^-12 to simulate the
+            // inaccuracy of RSQRT.
+            let res = apply_random_float_error(this, rsqrt, -12);
+            Ok(Scalar::from_f32(res))
+        }
+    }
+}
+
+/// Disturbes a floating-point result by a relative error on the order of (-2^scale, 2^scale).
+#[allow(clippy::arithmetic_side_effects)] // floating point arithmetic cannot panic
+fn apply_random_float_error<F: rustc_apfloat::Float>(
+    this: &mut crate::MiriInterpCx<'_, '_>,
+    val: F,
+    err_scale: i32,
+) -> F {
+    let rng = this.machine.rng.get_mut();
+    // generates rand(0, 2^64) * 2^(scale - 64) = rand(0, 1) * 2^scale
+    let err =
+        F::from_u128(rng.gen::<u64>().into()).value.scalbn(err_scale.checked_sub(64).unwrap());
+    // give it a random sign
+    let err = if rng.gen::<bool>() { -err } else { err };
+    // multiple the value with (1+err)
+    (val * (F::from_u128(1).value + err).value).value
+}
+
+/// Performs `which` operation on the first component of `op` and copies
+/// the other components. The result is stored in `dest`.
+fn unary_op_ss<'tcx>(
+    this: &mut crate::MiriInterpCx<'_, 'tcx>,
+    which: FloatUnaryOp,
+    op: &OpTy<'tcx, Provenance>,
+    dest: &PlaceTy<'tcx, Provenance>,
+) -> InterpResult<'tcx, ()> {
+    let (op, op_len) = this.operand_to_simd(op)?;
+    let (dest, dest_len) = this.place_to_simd(dest)?;
+
+    assert_eq!(dest_len, op_len);
+
+    let res0 = unary_op_f32(this, which, &this.read_immediate(&this.project_index(&op, 0)?)?)?;
+    this.write_scalar(res0, &this.project_index(&dest, 0)?)?;
+
+    for i in 1..dest_len {
+        this.copy_op(
+            &this.project_index(&op, i)?,
+            &this.project_index(&dest, i)?,
+            /*allow_transmute*/ false,
+        )?;
+    }
+
+    Ok(())
+}
+
+/// Performs `which` operation on each component of `op`, storing the
+/// result is stored in `dest`.
+fn unary_op_ps<'tcx>(
+    this: &mut crate::MiriInterpCx<'_, 'tcx>,
+    which: FloatUnaryOp,
+    op: &OpTy<'tcx, Provenance>,
+    dest: &PlaceTy<'tcx, Provenance>,
+) -> InterpResult<'tcx, ()> {
+    let (op, op_len) = this.operand_to_simd(op)?;
+    let (dest, dest_len) = this.place_to_simd(dest)?;
+
+    assert_eq!(dest_len, op_len);
+
+    for i in 0..dest_len {
+        let op = this.read_immediate(&this.project_index(&op, i)?)?;
+        let dest = this.project_index(&dest, i)?;
+
+        let res = unary_op_f32(this, which, &op)?;
+        this.write_scalar(res, &dest)?;
+    }
+
+    Ok(())
+}
+
+// Rounds the first element of `right` according to `rounding`
+// and copies the remaining elements from `left`.
+fn round_first<'tcx, F: rustc_apfloat::Float>(
+    this: &mut crate::MiriInterpCx<'_, 'tcx>,
+    left: &OpTy<'tcx, Provenance>,
+    right: &OpTy<'tcx, Provenance>,
+    rounding: &OpTy<'tcx, Provenance>,
+    dest: &PlaceTy<'tcx, Provenance>,
+) -> InterpResult<'tcx, ()> {
+    let (left, left_len) = this.operand_to_simd(left)?;
+    let (right, right_len) = this.operand_to_simd(right)?;
+    let (dest, dest_len) = this.place_to_simd(dest)?;
+
+    assert_eq!(dest_len, left_len);
+    assert_eq!(dest_len, right_len);
+
+    let rounding = rounding_from_imm(this.read_scalar(rounding)?.to_i32()?)?;
+
+    let op0: F = this.read_scalar(&this.project_index(&right, 0)?)?.to_float()?;
+    let res = op0.round_to_integral(rounding).value;
+    this.write_scalar(
+        Scalar::from_uint(res.to_bits(), Size::from_bits(F::BITS)),
+        &this.project_index(&dest, 0)?,
+    )?;
+
+    for i in 1..dest_len {
+        this.copy_op(
+            &this.project_index(&left, i)?,
+            &this.project_index(&dest, i)?,
+            /*allow_transmute*/ false,
+        )?;
+    }
+
+    Ok(())
+}
+
+// Rounds all elements of `op` according to `rounding`.
+fn round_all<'tcx, F: rustc_apfloat::Float>(
+    this: &mut crate::MiriInterpCx<'_, 'tcx>,
+    op: &OpTy<'tcx, Provenance>,
+    rounding: &OpTy<'tcx, Provenance>,
+    dest: &PlaceTy<'tcx, Provenance>,
+) -> InterpResult<'tcx, ()> {
+    let (op, op_len) = this.operand_to_simd(op)?;
+    let (dest, dest_len) = this.place_to_simd(dest)?;
+
+    assert_eq!(dest_len, op_len);
+
+    let rounding = rounding_from_imm(this.read_scalar(rounding)?.to_i32()?)?;
+
+    for i in 0..dest_len {
+        let op: F = this.read_scalar(&this.project_index(&op, i)?)?.to_float()?;
+        let res = op.round_to_integral(rounding).value;
+        this.write_scalar(
+            Scalar::from_uint(res.to_bits(), Size::from_bits(F::BITS)),
+            &this.project_index(&dest, i)?,
+        )?;
+    }
+
+    Ok(())
+}
+
+/// Gets equivalent `rustc_apfloat::Round` from rounding mode immediate of
+/// `round.{ss,sd,ps,pd}` intrinsics.
+fn rounding_from_imm<'tcx>(rounding: i32) -> InterpResult<'tcx, rustc_apfloat::Round> {
+    // The fourth bit of `rounding` only affects the SSE status
+    // register, which cannot be accessed from Miri (or from Rust,
+    // for that matter), so we can ignore it.
+    match rounding & !0b1000 {
+        // When the third bit is 0, the rounding mode is determined by the
+        // first two bits.
+        0b000 => Ok(rustc_apfloat::Round::NearestTiesToEven),
+        0b001 => Ok(rustc_apfloat::Round::TowardNegative),
+        0b010 => Ok(rustc_apfloat::Round::TowardPositive),
+        0b011 => Ok(rustc_apfloat::Round::TowardZero),
+        // When the third bit is 1, the rounding mode is determined by the
+        // SSE status register. Since we do not support modifying it from
+        // Miri (or Rust), we assume it to be at its default mode (round-to-nearest).
+        0b100..=0b111 => Ok(rustc_apfloat::Round::NearestTiesToEven),
+        rounding => throw_unsup_format!("unsupported rounding mode 0x{rounding:02x}"),
+    }
+}
+
 /// Converts each element of `op` from floating point to signed integer.
 ///
 /// When the input value is NaN or out of range, fall back to minimum value.
@@ -408,3 +615,84 @@ fn horizontal_bin_op<'tcx>(
 
     Ok(())
 }
+
+/// Conditionally multiplies the packed floating-point elements in
+/// `left` and `right` using the high 4 bits in `imm`, sums the calculated
+/// products (up to 4), and conditionally stores the sum in `dest` using
+/// the low 4 bits of `imm`.
+fn conditional_dot_product<'tcx>(
+    this: &mut crate::MiriInterpCx<'_, 'tcx>,
+    left: &OpTy<'tcx, Provenance>,
+    right: &OpTy<'tcx, Provenance>,
+    imm: &OpTy<'tcx, Provenance>,
+    dest: &PlaceTy<'tcx, Provenance>,
+) -> InterpResult<'tcx, ()> {
+    let (left, left_len) = this.operand_to_simd(left)?;
+    let (right, right_len) = this.operand_to_simd(right)?;
+    let (dest, dest_len) = this.place_to_simd(dest)?;
+
+    assert_eq!(left_len, right_len);
+    assert!(dest_len <= 4);
+
+    let imm = this.read_scalar(imm)?.to_u8()?;
+
+    let element_layout = left.layout.field(this, 0);
+
+    // Calculate dot product
+    // Elements are floating point numbers, but we can use `from_int`
+    // because the representation of 0.0 is all zero bits.
+    let mut sum = ImmTy::from_int(0u8, element_layout);
+    for i in 0..left_len {
+        if imm & (1 << i.checked_add(4).unwrap()) != 0 {
+            let left = this.read_immediate(&this.project_index(&left, i)?)?;
+            let right = this.read_immediate(&this.project_index(&right, i)?)?;
+
+            let mul = this.wrapping_binary_op(mir::BinOp::Mul, &left, &right)?;
+            sum = this.wrapping_binary_op(mir::BinOp::Add, &sum, &mul)?;
+        }
+    }
+
+    // Write to destination (conditioned to imm)
+    for i in 0..dest_len {
+        let dest = this.project_index(&dest, i)?;
+
+        if imm & (1 << i) != 0 {
+            this.write_immediate(*sum, &dest)?;
+        } else {
+            this.write_scalar(Scalar::from_int(0u8, element_layout.size), &dest)?;
+        }
+    }
+
+    Ok(())
+}
+
+/// Calculates two booleans.
+///
+/// The first is true when all the bits of `op & mask` are zero.
+/// The second is true when `(op & mask) == mask`
+fn test_bits_masked<'tcx>(
+    this: &crate::MiriInterpCx<'_, 'tcx>,
+    op: &OpTy<'tcx, Provenance>,
+    mask: &OpTy<'tcx, Provenance>,
+) -> InterpResult<'tcx, (bool, bool)> {
+    assert_eq!(op.layout, mask.layout);
+
+    let (op, op_len) = this.operand_to_simd(op)?;
+    let (mask, mask_len) = this.operand_to_simd(mask)?;
+
+    assert_eq!(op_len, mask_len);
+
+    let mut all_zero = true;
+    let mut masked_set = true;
+    for i in 0..op_len {
+        let op = this.project_index(&op, i)?;
+        let mask = this.project_index(&mask, i)?;
+
+        let op = this.read_scalar(&op)?.to_uint(op.layout.size)?;
+        let mask = this.read_scalar(&mask)?.to_uint(mask.layout.size)?;
+        all_zero &= (op & mask) == 0;
+        masked_set &= (op & mask) == mask;
+    }
+
+    Ok((all_zero, masked_set))
+}
diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs
index 6e06f62b34c..1e9afc1e9e0 100644
--- a/src/tools/miri/src/shims/x86/sse.rs
+++ b/src/tools/miri/src/shims/x86/sse.rs
@@ -1,11 +1,12 @@
-use rustc_apfloat::{ieee::Single, Float as _};
+use rustc_apfloat::ieee::Single;
 use rustc_middle::mir;
 use rustc_span::Symbol;
 use rustc_target::spec::abi::Abi;
 
-use rand::Rng as _;
-
-use super::{bin_op_simd_float_all, bin_op_simd_float_first, FloatBinOp};
+use super::{
+    bin_op_simd_float_all, bin_op_simd_float_first, unary_op_ps, unary_op_ss, FloatBinOp,
+    FloatUnaryOp,
+};
 use crate::*;
 use shims::foreign_items::EmulateForeignItemResult;
 
@@ -219,124 +220,3 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
         Ok(EmulateForeignItemResult::NeedsJumping)
     }
 }
-
-#[derive(Copy, Clone)]
-enum FloatUnaryOp {
-    /// sqrt(x)
-    ///
-    /// <https://www.felixcloutier.com/x86/sqrtss>
-    /// <https://www.felixcloutier.com/x86/sqrtps>
-    Sqrt,
-    /// Approximation of 1/x
-    ///
-    /// <https://www.felixcloutier.com/x86/rcpss>
-    /// <https://www.felixcloutier.com/x86/rcpps>
-    Rcp,
-    /// Approximation of 1/sqrt(x)
-    ///
-    /// <https://www.felixcloutier.com/x86/rsqrtss>
-    /// <https://www.felixcloutier.com/x86/rsqrtps>
-    Rsqrt,
-}
-
-/// Performs `which` scalar operation on `op` and returns the result.
-#[allow(clippy::arithmetic_side_effects)] // floating point operations without side effects
-fn unary_op_f32<'tcx>(
-    this: &mut crate::MiriInterpCx<'_, 'tcx>,
-    which: FloatUnaryOp,
-    op: &ImmTy<'tcx, Provenance>,
-) -> InterpResult<'tcx, Scalar<Provenance>> {
-    match which {
-        FloatUnaryOp::Sqrt => {
-            let op = op.to_scalar();
-            // FIXME using host floats
-            Ok(Scalar::from_u32(f32::from_bits(op.to_u32()?).sqrt().to_bits()))
-        }
-        FloatUnaryOp::Rcp => {
-            let op = op.to_scalar().to_f32()?;
-            let div = (Single::from_u128(1).value / op).value;
-            // Apply a relative error with a magnitude on the order of 2^-12 to simulate the
-            // inaccuracy of RCP.
-            let res = apply_random_float_error(this, div, -12);
-            Ok(Scalar::from_f32(res))
-        }
-        FloatUnaryOp::Rsqrt => {
-            let op = op.to_scalar().to_u32()?;
-            // FIXME using host floats
-            let sqrt = Single::from_bits(f32::from_bits(op).sqrt().to_bits().into());
-            let rsqrt = (Single::from_u128(1).value / sqrt).value;
-            // Apply a relative error with a magnitude on the order of 2^-12 to simulate the
-            // inaccuracy of RSQRT.
-            let res = apply_random_float_error(this, rsqrt, -12);
-            Ok(Scalar::from_f32(res))
-        }
-    }
-}
-
-/// Disturbes a floating-point result by a relative error on the order of (-2^scale, 2^scale).
-#[allow(clippy::arithmetic_side_effects)] // floating point arithmetic cannot panic
-fn apply_random_float_error<F: rustc_apfloat::Float>(
-    this: &mut crate::MiriInterpCx<'_, '_>,
-    val: F,
-    err_scale: i32,
-) -> F {
-    let rng = this.machine.rng.get_mut();
-    // generates rand(0, 2^64) * 2^(scale - 64) = rand(0, 1) * 2^scale
-    let err =
-        F::from_u128(rng.gen::<u64>().into()).value.scalbn(err_scale.checked_sub(64).unwrap());
-    // give it a random sign
-    let err = if rng.gen::<bool>() { -err } else { err };
-    // multiple the value with (1+err)
-    (val * (F::from_u128(1).value + err).value).value
-}
-
-/// Performs `which` operation on the first component of `op` and copies
-/// the other components. The result is stored in `dest`.
-fn unary_op_ss<'tcx>(
-    this: &mut crate::MiriInterpCx<'_, 'tcx>,
-    which: FloatUnaryOp,
-    op: &OpTy<'tcx, Provenance>,
-    dest: &PlaceTy<'tcx, Provenance>,
-) -> InterpResult<'tcx, ()> {
-    let (op, op_len) = this.operand_to_simd(op)?;
-    let (dest, dest_len) = this.place_to_simd(dest)?;
-
-    assert_eq!(dest_len, op_len);
-
-    let res0 = unary_op_f32(this, which, &this.read_immediate(&this.project_index(&op, 0)?)?)?;
-    this.write_scalar(res0, &this.project_index(&dest, 0)?)?;
-
-    for i in 1..dest_len {
-        this.copy_op(
-            &this.project_index(&op, i)?,
-            &this.project_index(&dest, i)?,
-            /*allow_transmute*/ false,
-        )?;
-    }
-
-    Ok(())
-}
-
-/// Performs `which` operation on each component of `op`, storing the
-/// result is stored in `dest`.
-fn unary_op_ps<'tcx>(
-    this: &mut crate::MiriInterpCx<'_, 'tcx>,
-    which: FloatUnaryOp,
-    op: &OpTy<'tcx, Provenance>,
-    dest: &PlaceTy<'tcx, Provenance>,
-) -> InterpResult<'tcx, ()> {
-    let (op, op_len) = this.operand_to_simd(op)?;
-    let (dest, dest_len) = this.place_to_simd(dest)?;
-
-    assert_eq!(dest_len, op_len);
-
-    for i in 0..dest_len {
-        let op = this.read_immediate(&this.project_index(&op, i)?)?;
-        let dest = this.project_index(&dest, i)?;
-
-        let res = unary_op_f32(this, which, &op)?;
-        this.write_scalar(res, &dest)?;
-    }
-
-    Ok(())
-}
diff --git a/src/tools/miri/src/shims/x86/sse41.rs b/src/tools/miri/src/shims/x86/sse41.rs
index b3d1056ab06..67bb63f0a3d 100644
--- a/src/tools/miri/src/shims/x86/sse41.rs
+++ b/src/tools/miri/src/shims/x86/sse41.rs
@@ -1,8 +1,7 @@
-use rustc_middle::mir;
 use rustc_span::Symbol;
-use rustc_target::abi::Size;
 use rustc_target::spec::abi::Abi;
 
+use super::{conditional_dot_product, round_all, round_first, test_bits_masked};
 use crate::*;
 use shims::foreign_items::EmulateForeignItemResult;
 
@@ -104,41 +103,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                 let [left, right, imm] =
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
 
-                let (left, left_len) = this.operand_to_simd(left)?;
-                let (right, right_len) = this.operand_to_simd(right)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
-
-                assert_eq!(left_len, right_len);
-                assert!(dest_len <= 4);
-
-                let imm = this.read_scalar(imm)?.to_u8()?;
-
-                let element_layout = left.layout.field(this, 0);
-
-                // Calculate dot product
-                // Elements are floating point numbers, but we can use `from_int`
-                // because the representation of 0.0 is all zero bits.
-                let mut sum = ImmTy::from_int(0u8, element_layout);
-                for i in 0..left_len {
-                    if imm & (1 << i.checked_add(4).unwrap()) != 0 {
-                        let left = this.read_immediate(&this.project_index(&left, i)?)?;
-                        let right = this.read_immediate(&this.project_index(&right, i)?)?;
-
-                        let mul = this.wrapping_binary_op(mir::BinOp::Mul, &left, &right)?;
-                        sum = this.wrapping_binary_op(mir::BinOp::Add, &sum, &mul)?;
-                    }
-                }
-
-                // Write to destination (conditioned to imm)
-                for i in 0..dest_len {
-                    let dest = this.project_index(&dest, i)?;
-
-                    if imm & (1 << i) != 0 {
-                        this.write_immediate(*sum, &dest)?;
-                    } else {
-                        this.write_scalar(Scalar::from_int(0u8, element_layout.size), &dest)?;
-                    }
-                }
+                conditional_dot_product(this, left, right, imm, dest)?;
             }
             // Used to implement the _mm_floor_ss, _mm_ceil_ss and _mm_round_ss
             // functions. Rounds the first element of `right` according to `rounding`
@@ -252,117 +217,23 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
             }
             // Used to implement the _mm_testz_si128, _mm_testc_si128
             // and _mm_testnzc_si128 functions.
-            // Tests `op & mask == 0`, `op & mask == mask` or
-            // `op & mask != 0 && op & mask != mask`
+            // Tests `(op & mask) == 0`, `(op & mask) == mask` or
+            // `(op & mask) != 0 && (op & mask) != mask`
             "ptestz" | "ptestc" | "ptestnzc" => {
                 let [op, mask] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
 
-                let (op, op_len) = this.operand_to_simd(op)?;
-                let (mask, mask_len) = this.operand_to_simd(mask)?;
-
-                assert_eq!(op_len, mask_len);
-
-                let f = match unprefixed_name {
-                    "ptestz" => |op, mask| op & mask == 0,
-                    "ptestc" => |op, mask| op & mask == mask,
-                    "ptestnzc" => |op, mask| op & mask != 0 && op & mask != mask,
+                let (all_zero, masked_set) = test_bits_masked(this, op, mask)?;
+                let res = match unprefixed_name {
+                    "ptestz" => all_zero,
+                    "ptestc" => masked_set,
+                    "ptestnzc" => !all_zero && !masked_set,
                     _ => unreachable!(),
                 };
 
-                let mut all_zero = true;
-                for i in 0..op_len {
-                    let op = this.read_scalar(&this.project_index(&op, i)?)?.to_u64()?;
-                    let mask = this.read_scalar(&this.project_index(&mask, i)?)?.to_u64()?;
-                    all_zero &= f(op, mask);
-                }
-
-                this.write_scalar(Scalar::from_i32(all_zero.into()), dest)?;
+                this.write_scalar(Scalar::from_i32(res.into()), dest)?;
             }
             _ => return Ok(EmulateForeignItemResult::NotSupported),
         }
         Ok(EmulateForeignItemResult::NeedsJumping)
     }
 }
-
-// Rounds the first element of `right` according to `rounding`
-// and copies the remaining elements from `left`.
-fn round_first<'tcx, F: rustc_apfloat::Float>(
-    this: &mut crate::MiriInterpCx<'_, 'tcx>,
-    left: &OpTy<'tcx, Provenance>,
-    right: &OpTy<'tcx, Provenance>,
-    rounding: &OpTy<'tcx, Provenance>,
-    dest: &PlaceTy<'tcx, Provenance>,
-) -> InterpResult<'tcx, ()> {
-    let (left, left_len) = this.operand_to_simd(left)?;
-    let (right, right_len) = this.operand_to_simd(right)?;
-    let (dest, dest_len) = this.place_to_simd(dest)?;
-
-    assert_eq!(dest_len, left_len);
-    assert_eq!(dest_len, right_len);
-
-    let rounding = rounding_from_imm(this.read_scalar(rounding)?.to_i32()?)?;
-
-    let op0: F = this.read_scalar(&this.project_index(&right, 0)?)?.to_float()?;
-    let res = op0.round_to_integral(rounding).value;
-    this.write_scalar(
-        Scalar::from_uint(res.to_bits(), Size::from_bits(F::BITS)),
-        &this.project_index(&dest, 0)?,
-    )?;
-
-    for i in 1..dest_len {
-        this.copy_op(
-            &this.project_index(&left, i)?,
-            &this.project_index(&dest, i)?,
-            /*allow_transmute*/ false,
-        )?;
-    }
-
-    Ok(())
-}
-
-// Rounds all elements of `op` according to `rounding`.
-fn round_all<'tcx, F: rustc_apfloat::Float>(
-    this: &mut crate::MiriInterpCx<'_, 'tcx>,
-    op: &OpTy<'tcx, Provenance>,
-    rounding: &OpTy<'tcx, Provenance>,
-    dest: &PlaceTy<'tcx, Provenance>,
-) -> InterpResult<'tcx, ()> {
-    let (op, op_len) = this.operand_to_simd(op)?;
-    let (dest, dest_len) = this.place_to_simd(dest)?;
-
-    assert_eq!(dest_len, op_len);
-
-    let rounding = rounding_from_imm(this.read_scalar(rounding)?.to_i32()?)?;
-
-    for i in 0..dest_len {
-        let op: F = this.read_scalar(&this.project_index(&op, i)?)?.to_float()?;
-        let res = op.round_to_integral(rounding).value;
-        this.write_scalar(
-            Scalar::from_uint(res.to_bits(), Size::from_bits(F::BITS)),
-            &this.project_index(&dest, i)?,
-        )?;
-    }
-
-    Ok(())
-}
-
-/// Gets equivalent `rustc_apfloat::Round` from rounding mode immediate of
-/// `round.{ss,sd,ps,pd}` intrinsics.
-fn rounding_from_imm<'tcx>(rounding: i32) -> InterpResult<'tcx, rustc_apfloat::Round> {
-    // The fourth bit of `rounding` only affects the SSE status
-    // register, which cannot be accessed from Miri (or from Rust,
-    // for that matter), so we can ignore it.
-    match rounding & !0b1000 {
-        // When the third bit is 0, the rounding mode is determined by the
-        // first two bits.
-        0b000 => Ok(rustc_apfloat::Round::NearestTiesToEven),
-        0b001 => Ok(rustc_apfloat::Round::TowardNegative),
-        0b010 => Ok(rustc_apfloat::Round::TowardPositive),
-        0b011 => Ok(rustc_apfloat::Round::TowardZero),
-        // When the third bit is 1, the rounding mode is determined by the
-        // SSE status register. Since we do not support modifying it from
-        // Miri (or Rust), we assume it to be at its default mode (round-to-nearest).
-        0b100..=0b111 => Ok(rustc_apfloat::Round::NearestTiesToEven),
-        rounding => throw_unsup_format!("unsupported rounding mode 0x{rounding:02x}"),
-    }
-}
diff --git a/src/tools/miri/test-cargo-miri/run-test.py b/src/tools/miri/test-cargo-miri/run-test.py
index db4341169ea..21479bc4d58 100755
--- a/src/tools/miri/test-cargo-miri/run-test.py
+++ b/src/tools/miri/test-cargo-miri/run-test.py
@@ -181,7 +181,7 @@ def test_cargo_miri_test():
     )
     del os.environ["CARGO_TARGET_DIR"] # this overrides `build.target-dir` passed by `--config`, so unset it
     test("`cargo miri test` (config-cli)",
-        cargo_miri("test") + ["--config=build.target-dir=\"config-cli\"", "-Zunstable-options"],
+        cargo_miri("test") + ["--config=build.target-dir=\"config-cli\""],
         default_ref, "test.stderr-empty.ref",
         env={'MIRIFLAGS': "-Zmiri-permissive-provenance"},
     )
diff --git a/src/tools/miri/tests/pass-dep/shims/mmap.rs b/src/tools/miri/tests/pass-dep/shims/mmap.rs
index 03ffc3b3898..fefbed80fd2 100644
--- a/src/tools/miri/tests/pass-dep/shims/mmap.rs
+++ b/src/tools/miri/tests/pass-dep/shims/mmap.rs
@@ -2,6 +2,7 @@
 //@compile-flags: -Zmiri-disable-isolation -Zmiri-permissive-provenance
 #![feature(strict_provenance)]
 
+use std::io::Error;
 use std::{ptr, slice};
 
 fn test_mmap() {
@@ -32,6 +33,67 @@ fn test_mmap() {
     let just_an_address = ptr::invalid_mut(ptr.addr());
     let res = unsafe { libc::munmap(just_an_address, page_size) };
     assert_eq!(res, 0i32);
+
+    // Test all of our error conditions
+    let ptr = unsafe {
+        libc::mmap(
+            ptr::null_mut(),
+            page_size,
+            libc::PROT_READ | libc::PROT_WRITE,
+            libc::MAP_PRIVATE | libc::MAP_SHARED, // Can't be both private and shared
+            -1,
+            0,
+        )
+    };
+    assert_eq!(ptr, libc::MAP_FAILED);
+    assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);
+
+    let ptr = unsafe {
+        libc::mmap(
+            ptr::null_mut(),
+            0, // Can't map no memory
+            libc::PROT_READ | libc::PROT_WRITE,
+            libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
+            -1,
+            0,
+        )
+    };
+    assert_eq!(ptr, libc::MAP_FAILED);
+    assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);
+
+    let ptr = unsafe {
+        libc::mmap(
+            ptr::invalid_mut(page_size * 64),
+            page_size,
+            libc::PROT_READ | libc::PROT_WRITE,
+            // We don't support MAP_FIXED
+            libc::MAP_PRIVATE | libc::MAP_ANONYMOUS | libc::MAP_FIXED,
+            -1,
+            0,
+        )
+    };
+    assert_eq!(ptr, libc::MAP_FAILED);
+    assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::ENOTSUP);
+
+    // We don't support protections other than read+write
+    for prot in [libc::PROT_NONE, libc::PROT_EXEC, libc::PROT_READ, libc::PROT_WRITE] {
+        let ptr = unsafe {
+            libc::mmap(
+                ptr::null_mut(),
+                page_size,
+                prot,
+                libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
+                -1,
+                0,
+            )
+        };
+        assert_eq!(ptr, libc::MAP_FAILED);
+        assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::ENOTSUP);
+    }
+
+    let res = unsafe { libc::munmap(ptr::invalid_mut(1), page_size) };
+    assert_eq!(res, -1);
+    assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);
 }
 
 #[cfg(target_os = "linux")]
@@ -61,6 +123,23 @@ fn test_mremap() {
 
     let res = unsafe { libc::munmap(ptr, page_size * 2) };
     assert_eq!(res, 0i32);
+
+    // Test all of our error conditions
+    // Not aligned
+    let ptr =
+        unsafe { libc::mremap(ptr::invalid_mut(1), page_size, page_size, libc::MREMAP_MAYMOVE) };
+    assert_eq!(ptr, libc::MAP_FAILED);
+    assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);
+
+    // Zero size
+    let ptr = unsafe { libc::mremap(ptr::null_mut(), page_size, 0, libc::MREMAP_MAYMOVE) };
+    assert_eq!(ptr, libc::MAP_FAILED);
+    assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);
+
+    // Not setting MREMAP_MAYMOVE
+    let ptr = unsafe { libc::mremap(ptr::null_mut(), page_size, page_size, 0) };
+    assert_eq!(ptr, libc::MAP_FAILED);
+    assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);
 }
 
 fn main() {
diff --git a/src/tools/miri/tests/pass/async-fn.rs b/src/tools/miri/tests/pass/async-fn.rs
index 1d5d9a27cc8..6c92735df0a 100644
--- a/src/tools/miri/tests/pass/async-fn.rs
+++ b/src/tools/miri/tests/pass/async-fn.rs
@@ -1,4 +1,5 @@
 #![feature(never_type)]
+#![feature(noop_waker)]
 
 use std::future::Future;
 
@@ -57,18 +58,25 @@ async fn hello_world() {
     read_exact(&mut reader, &mut marker).await.unwrap();
 }
 
-fn run_fut<T>(fut: impl Future<Output = T>) -> T {
-    use std::sync::Arc;
-    use std::task::{Context, Poll, Wake, Waker};
+// This example comes from https://github.com/rust-lang/rust/issues/115145
+async fn uninhabited_variant() {
+    async fn unreachable(_: Never) {}
 
-    struct MyWaker;
-    impl Wake for MyWaker {
-        fn wake(self: Arc<Self>) {
-            unimplemented!()
+    let c = async {};
+    match None::<Never> {
+        None => {
+            c.await;
+        }
+        Some(r) => {
+            unreachable(r).await;
         }
     }
+}
+
+fn run_fut<T>(fut: impl Future<Output = T>) -> T {
+    use std::task::{Context, Poll, Waker};
 
-    let waker = Waker::from(Arc::new(MyWaker));
+    let waker = Waker::noop();
     let mut context = Context::from_waker(&waker);
 
     let mut pinned = Box::pin(fut);
@@ -87,4 +95,5 @@ fn main() {
     assert_eq!(run_fut(includes_never(false, 4)), 16);
     assert_eq!(run_fut(partial_init(4)), 8);
     run_fut(hello_world());
+    run_fut(uninhabited_variant());
 }
diff --git a/src/tools/miri/tests/pass/coroutine.rs b/src/tools/miri/tests/pass/coroutine.rs
index 49bfa92a052..7e1f64df04d 100644
--- a/src/tools/miri/tests/pass/coroutine.rs
+++ b/src/tools/miri/tests/pass/coroutine.rs
@@ -220,7 +220,38 @@ fn smoke_resume_arg() {
     });
 }
 
+fn uninit_fields() {
+    // Test that uninhabited saved local doesn't make the entire variant uninhabited.
+    // (https://github.com/rust-lang/rust/issues/115145, https://github.com/rust-lang/rust/pull/118871)
+    fn conjure<T>() -> T {
+        loop {}
+    }
+
+    fn run<T>(x: bool, y: bool) {
+        let mut c = || {
+            if x {
+                let _a: T;
+                if y {
+                    _a = conjure::<T>();
+                }
+                yield ();
+            } else {
+                let _a: T;
+                if y {
+                    _a = conjure::<T>();
+                }
+                yield ();
+            }
+        };
+        assert!(matches!(Pin::new(&mut c).resume(()), CoroutineState::Yielded(())));
+        assert!(matches!(Pin::new(&mut c).resume(()), CoroutineState::Complete(())));
+    }
+
+    run::<!>(false, false);
+}
+
 fn main() {
     basic();
     smoke_resume_arg();
+    uninit_fields();
 }
diff --git a/src/tools/miri/tests/pass/dyn-star.rs b/src/tools/miri/tests/pass/dyn-star.rs
index 1fac16352a4..8e26c4850fa 100644
--- a/src/tools/miri/tests/pass/dyn-star.rs
+++ b/src/tools/miri/tests/pass/dyn-star.rs
@@ -1,6 +1,7 @@
 #![feature(dyn_star)]
 #![allow(incomplete_features)]
 #![feature(custom_inner_attributes)]
+#![feature(noop_waker)]
 // rustfmt destroys `dyn* Trait` syntax
 #![rustfmt::skip]
 
@@ -89,25 +90,10 @@ fn dispatch_on_pin_mut() {
     use std::pin::Pin;
     use std::task::*;
 
-    pub fn noop_waker() -> Waker {
-        let raw = RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE);
-
-        // SAFETY: the contracts for RawWaker and RawWakerVTable are upheld
-        unsafe { Waker::from_raw(raw) }
-    }
-
-    const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop);
-
-    unsafe fn noop_clone(_p: *const ()) -> RawWaker {
-        RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE)
-    }
-
-    unsafe fn noop(_p: *const ()) {}
-
     let mut fut = async_main();
 
     // Poll loop, just to test the future...
-    let waker = noop_waker();
+    let waker = Waker::noop();
     let ctx = &mut Context::from_waker(&waker);
 
     loop {
diff --git a/src/tools/miri/tests/pass/enum-nullable-const-null-with-fields.rs b/src/tools/miri/tests/pass/enum-nullable-const-null-with-fields.rs
index c42cd87f9a1..86f30f42b62 100644
--- a/src/tools/miri/tests/pass/enum-nullable-const-null-with-fields.rs
+++ b/src/tools/miri/tests/pass/enum-nullable-const-null-with-fields.rs
@@ -1,4 +1,3 @@
-
 static C: Result<(), Box<isize>> = Ok(());
 
 // This is because of yet another bad assertion (ICE) about the null side of a nullable enum.
diff --git a/src/tools/miri/tests/pass/future-self-referential.rs b/src/tools/miri/tests/pass/future-self-referential.rs
index 763eceeb6f0..38cb700fd58 100644
--- a/src/tools/miri/tests/pass/future-self-referential.rs
+++ b/src/tools/miri/tests/pass/future-self-referential.rs
@@ -1,5 +1,6 @@
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
+#![feature(noop_waker)]
 
 use std::future::*;
 use std::marker::PhantomPinned;
@@ -29,19 +30,6 @@ impl Future for Delay {
     }
 }
 
-fn mk_waker() -> Waker {
-    use std::sync::Arc;
-
-    struct MyWaker;
-    impl Wake for MyWaker {
-        fn wake(self: Arc<Self>) {
-            unimplemented!()
-        }
-    }
-
-    Waker::from(Arc::new(MyWaker))
-}
-
 async fn do_stuff() {
     (&mut Delay::new(1)).await;
 }
@@ -89,7 +77,7 @@ impl Future for DoStuff {
 }
 
 fn run_fut<T>(fut: impl Future<Output = T>) -> T {
-    let waker = mk_waker();
+    let waker = Waker::noop();
     let mut context = Context::from_waker(&waker);
 
     let mut pinned = pin!(fut);
@@ -102,7 +90,7 @@ fn run_fut<T>(fut: impl Future<Output = T>) -> T {
 }
 
 fn self_referential_box() {
-    let waker = mk_waker();
+    let waker = Waker::noop();
     let cx = &mut Context::from_waker(&waker);
 
     async fn my_fut() -> i32 {
diff --git a/src/tools/miri/tests/pass/intrinsics-x86-sse41.rs b/src/tools/miri/tests/pass/intrinsics-x86-sse41.rs
index 13856d29d3f..06607f3fd59 100644
--- a/src/tools/miri/tests/pass/intrinsics-x86-sse41.rs
+++ b/src/tools/miri/tests/pass/intrinsics-x86-sse41.rs
@@ -515,6 +515,11 @@ unsafe fn test_sse41() {
         let mask = _mm_set1_epi8(0b101);
         let r = _mm_testnzc_si128(a, mask);
         assert_eq!(r, 0);
+
+        let a = _mm_setr_epi32(0b100, 0, 0, 0b010);
+        let mask = _mm_setr_epi32(0b100, 0, 0, 0b110);
+        let r = _mm_testnzc_si128(a, mask);
+        assert_eq!(r, 1);
     }
     test_mm_testnzc_si128();
 }
diff --git a/src/tools/miri/tests/pass/issues/issue-miri-2068.rs b/src/tools/miri/tests/pass/issues/issue-miri-2068.rs
index fe4078f7710..f18c4a3a065 100644
--- a/src/tools/miri/tests/pass/issues/issue-miri-2068.rs
+++ b/src/tools/miri/tests/pass/issues/issue-miri-2068.rs
@@ -1,19 +1,13 @@
-use core::future::Future;
-use core::pin::Pin;
-use core::task::{Context, Poll};
+#![feature(noop_waker)]
 
-use std::sync::Arc;
-
-struct NopWaker;
-
-impl std::task::Wake for NopWaker {
-    fn wake(self: Arc<Self>) {}
-}
+use std::future::Future;
+use std::pin::Pin;
+use std::task::{Context, Poll, Waker};
 
 pub fn fuzzing_block_on<O, F: Future<Output = O>>(fut: F) -> O {
     let mut fut = std::pin::pin!(fut);
-    let waker = std::task::Waker::from(Arc::new(NopWaker));
-    let mut context = std::task::Context::from_waker(&waker);
+    let waker = Waker::noop();
+    let mut context = Context::from_waker(&waker);
     loop {
         match fut.as_mut().poll(&mut context) {
             Poll::Ready(v) => return v,
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
index 5990d66fbdd..9bea6ea5742 100644
--- a/src/tools/miri/tests/pass/move-data-across-await-point.rs
+++ b/src/tools/miri/tests/pass/move-data-across-await-point.rs
@@ -1,3 +1,4 @@
+#![feature(noop_waker)]
 use std::future::Future;
 use std::ptr;
 
@@ -53,17 +54,9 @@ fn data_moved() {
 }
 
 fn run_fut<T>(fut: impl Future<Output = T>) -> T {
-    use std::sync::Arc;
-    use std::task::{Context, Poll, Wake, Waker};
+    use std::task::{Context, Poll, Waker};
 
-    struct MyWaker;
-    impl Wake for MyWaker {
-        fn wake(self: Arc<Self>) {
-            unimplemented!()
-        }
-    }
-
-    let waker = Waker::from(Arc::new(MyWaker));
+    let waker = Waker::noop();
     let mut context = Context::from_waker(&waker);
 
     let mut pinned = Box::pin(fut);
diff --git a/src/tools/miri/tests/pass/protector-gc.rs b/src/tools/miri/tests/pass/protector-gc.rs
new file mode 100644
index 00000000000..4e422c323ea
--- /dev/null
+++ b/src/tools/miri/tests/pass/protector-gc.rs
@@ -0,0 +1,17 @@
+// When we pop a stack frame with weak protectors, we need to check if the protected pointer's
+// allocation is still live. If the provenance GC only knows about the BorTag that is protected,
+// we can ICE. This test checks that we don't.
+// See https://github.com/rust-lang/miri/issues/3228
+
+#[path = "../utils/mod.rs"]
+mod utils;
+
+#[allow(unused)]
+fn oof(mut b: Box<u8>) {
+    b = Box::new(0u8);
+    utils::run_provenance_gc();
+}
+
+fn main() {
+    oof(Box::new(0u8));
+}