about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/miri/README.md32
-rw-r--r--src/tools/miri/cargo-miri/src/phases.rs202
-rw-r--r--src/tools/miri/cargo-miri/src/util.rs36
-rw-r--r--src/tools/miri/miri-script/src/main.rs11
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/concurrency/sync.rs10
-rw-r--r--src/tools/miri/src/intrinsics/simd.rs6
-rw-r--r--src/tools/miri/src/shims/os_str.rs4
-rw-r--r--src/tools/miri/src/shims/unix/fs.rs4
-rw-r--r--src/tools/miri/src/shims/unix/linux/epoll.rs11
-rw-r--r--src/tools/miri/src/shims/unix/socket.rs201
-rw-r--r--src/tools/miri/src/shims/x86/avx.rs8
-rw-r--r--src/tools/miri/src/shims/x86/mod.rs6
-rw-r--r--src/tools/miri/src/shims/x86/sse42.rs500
-rw-r--r--src/tools/miri/tests/fail-dep/libc/socketpair_read_blocking.rs12
-rw-r--r--src/tools/miri/tests/fail-dep/libc/socketpair_read_blocking.stderr14
-rw-r--r--src/tools/miri/tests/fail-dep/libc/socketpair_write_blocking.rs16
-rw-r--r--src/tools/miri/tests/fail-dep/libc/socketpair_write_blocking.stderr14
-rw-r--r--src/tools/miri/tests/fail/validity/invalid_enum_cast.rs14
-rw-r--r--src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr4
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs124
-rw-r--r--src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse42.rs443
22 files changed, 1522 insertions, 152 deletions
diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md
index c437619a76e..4b4f2f83062 100644
--- a/src/tools/miri/README.md
+++ b/src/tools/miri/README.md
@@ -151,6 +151,21 @@ platform. For example `cargo miri test --target s390x-unknown-linux-gnu`
 will run your test suite on a big-endian target, which is useful for testing
 endian-sensitive code.
 
+### Testing multiple different executions
+
+Certain parts of the execution are picked randomly by Miri, such as the exact base address
+allocations are stored at and the interleaving of concurrently executing threads. Sometimes, it can
+be useful to explore multiple different execution, e.g. to make sure that your code does not depend
+on incidental "super-alignment" of new allocations and to test different thread interleavings.
+This can be done with the `--many-seeds` flag:
+
+```
+cargo miri test --many-seeds # tries the seeds in 0..64
+cargo miri test --many-seeds=0..16
+```
+
+The default of 64 different seeds is quite slow, so you probably want to specify a smaller range.
+
 ### Running Miri on CI
 
 When running Miri on CI, use the following snippet to install a nightly toolchain with the Miri
@@ -183,23 +198,6 @@ Here is an example job for GitHub Actions:
 The explicit `cargo miri setup` helps to keep the output of the actual test step
 clean.
 
-### Testing for alignment issues
-
-Miri can sometimes miss misaligned accesses since allocations can "happen to be"
-aligned just right. You can use `-Zmiri-symbolic-alignment-check` to definitely
-catch all such issues, but that flag will also cause false positives when code
-does manual pointer arithmetic to account for alignment. Another alternative is
-to call Miri with various values for `-Zmiri-seed`; that will alter the
-randomness that is used to determine allocation base addresses. The following
-snippet calls Miri in a loop with different values for the seed:
-
-```
-for SEED in $(seq 0 255); do
-  echo "Trying seed: $SEED"
-  MIRIFLAGS=-Zmiri-seed=$SEED cargo miri test || { echo "Failing seed: $SEED"; break; };
-done
-```
-
 ### Supported targets
 
 Miri does not support all targets supported by Rust. The good news, however, is
diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs
index e2fc2a0c277..3c36f606d84 100644
--- a/src/tools/miri/cargo-miri/src/phases.rs
+++ b/src/tools/miri/cargo-miri/src/phases.rs
@@ -1,10 +1,10 @@
 //! Implements the various phases of `cargo miri run/test`.
 
-use std::env;
 use std::fs::{self, File};
-use std::io::BufReader;
+use std::io::{BufReader, Write};
 use std::path::{Path, PathBuf};
 use std::process::Command;
+use std::{env, thread};
 
 use rustc_version::VersionMeta;
 
@@ -34,6 +34,8 @@ Examples:
 
 ";
 
+const DEFAULT_MANY_SEEDS: &str = "0..64";
+
 fn show_help() {
     println!("{CARGO_MIRI_HELP}");
 }
@@ -119,7 +121,7 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
     // <https://github.com/rust-lang/miri/pull/1540#issuecomment-693553191> describes an alternative
     // approach that uses `cargo check`, making that part easier but target and binary handling
     // harder.
-    let cargo_miri_path = std::env::current_exe()
+    let cargo_miri_path = env::current_exe()
         .expect("current executable path invalid")
         .into_os_string()
         .into_string()
@@ -163,14 +165,22 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
     let target_dir = get_target_dir(&metadata);
     cmd.arg("--target-dir").arg(target_dir);
 
+    // Store many-seeds argument.
+    let mut many_seeds = None;
     // *After* we set all the flags that need setting, forward everything else. Make sure to skip
-    // `--target-dir` (which would otherwise be set twice).
+    // `--target-dir` (which would otherwise be set twice) and `--many-seeds` (which is our flag, not cargo's).
     for arg in
         ArgSplitFlagValue::from_string_iter(&mut args, "--target-dir").filter_map(Result::err)
     {
-        cmd.arg(arg);
+        if arg == "--many-seeds" {
+            many_seeds = Some(DEFAULT_MANY_SEEDS.to_owned());
+        } else if let Some(val) = arg.strip_prefix("--many-seeds=") {
+            many_seeds = Some(val.to_owned());
+        } else {
+            cmd.arg(arg);
+        }
     }
-    // Forward all further arguments (not consumed by `ArgSplitFlagValue`) to cargo.
+    // Forward all further arguments after `--` (not consumed by `ArgSplitFlagValue`) to cargo.
     cmd.args(args);
 
     // Set `RUSTC_WRAPPER` to ourselves.  Cargo will prepend that binary to its usual invocation,
@@ -222,6 +232,9 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
     // Forward some crucial information to our own re-invocations.
     cmd.env("MIRI_SYSROOT", miri_sysroot);
     cmd.env("MIRI_LOCAL_CRATES", local_crates(&metadata));
+    if let Some(many_seeds) = many_seeds {
+        cmd.env("MIRI_MANY_SEEDS", many_seeds);
+    }
     if verbose > 0 {
         cmd.env("MIRI_VERBOSE", verbose.to_string()); // This makes the other phases verbose.
     }
@@ -309,7 +322,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
         }
     }
 
-    let verbose = std::env::var("MIRI_VERBOSE")
+    let verbose = env::var("MIRI_VERBOSE")
         .map_or(0, |verbose| verbose.parse().expect("verbosity flag must be an integer"));
     let target_crate = is_target_crate();
 
@@ -489,7 +502,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
         // This is a host crate.
         // When we're running `cargo-miri` from `x.py` we need to pass the sysroot explicitly
         // due to bootstrap complications.
-        if let Some(sysroot) = std::env::var_os("MIRI_HOST_SYSROOT") {
+        if let Some(sysroot) = env::var_os("MIRI_HOST_SYSROOT") {
             cmd.arg("--sysroot").arg(sysroot);
         }
 
@@ -532,7 +545,7 @@ pub enum RunnerPhase {
 }
 
 pub fn phase_runner(mut binary_args: impl Iterator<Item = String>, phase: RunnerPhase) {
-    let verbose = std::env::var("MIRI_VERBOSE")
+    let verbose = env::var("MIRI_VERBOSE")
         .map_or(0, |verbose| verbose.parse().expect("verbosity flag must be an integer"));
 
     let binary = binary_args.next().unwrap();
@@ -541,6 +554,7 @@ pub fn phase_runner(mut binary_args: impl Iterator<Item = String>, phase: Runner
             "file {:?} not found or `cargo-miri` invoked incorrectly; please only invoke this binary through `cargo miri`", binary
         ));
     let file = BufReader::new(file);
+    let binary_args = binary_args.collect::<Vec<_>>();
 
     let info = serde_json::from_reader(file).unwrap_or_else(|_| {
         show_error!("file {:?} contains outdated or invalid JSON; try `cargo clean`", binary)
@@ -555,84 +569,114 @@ pub fn phase_runner(mut binary_args: impl Iterator<Item = String>, phase: Runner
         }
     };
 
-    let mut cmd = miri();
-
-    // Set missing env vars. We prefer build-time env vars over run-time ones; see
-    // <https://github.com/rust-lang/miri/issues/1661> for the kind of issue that fixes.
-    for (name, val) in info.env {
-        // `CARGO_MAKEFLAGS` contains information about how to reach the jobserver, but by the time
-        // the program is being run, that jobserver no longer exists (cargo only runs the jobserver
-        // for the build portion of `cargo run`/`cargo test`). Hence we shouldn't forward this.
-        // Also see <https://github.com/rust-lang/rust/pull/113730>.
-        if name == "CARGO_MAKEFLAGS" {
-            continue;
-        }
-        if let Some(old_val) = env::var_os(&name) {
-            if old_val == val {
-                // This one did not actually change, no need to re-set it.
-                // (This keeps the `debug_cmd` below more manageable.)
+    let many_seeds = env::var("MIRI_MANY_SEEDS");
+    run_many_seeds(many_seeds.ok(), |seed| {
+        let mut cmd = miri();
+
+        // Set missing env vars. We prefer build-time env vars over run-time ones; see
+        // <https://github.com/rust-lang/miri/issues/1661> for the kind of issue that fixes.
+        for (name, val) in &info.env {
+            // `CARGO_MAKEFLAGS` contains information about how to reach the jobserver, but by the time
+            // the program is being run, that jobserver no longer exists (cargo only runs the jobserver
+            // for the build portion of `cargo run`/`cargo test`). Hence we shouldn't forward this.
+            // Also see <https://github.com/rust-lang/rust/pull/113730>.
+            if name == "CARGO_MAKEFLAGS" {
                 continue;
-            } else if verbose > 0 {
-                eprintln!(
-                    "[cargo-miri runner] Overwriting run-time env var {name:?}={old_val:?} with build-time value {val:?}"
-                );
             }
+            if let Some(old_val) = env::var_os(name) {
+                if *old_val == *val {
+                    // This one did not actually change, no need to re-set it.
+                    // (This keeps the `debug_cmd` below more manageable.)
+                    continue;
+                } else if verbose > 0 {
+                    eprintln!(
+                        "[cargo-miri runner] Overwriting run-time env var {name:?}={old_val:?} with build-time value {val:?}"
+                    );
+                }
+            }
+            cmd.env(name, val);
         }
-        cmd.env(name, val);
-    }
 
-    if phase != RunnerPhase::Rustdoc {
-        // Set the sysroot. Not necessary in rustdoc, where we already set the sysroot in
-        // `phase_rustdoc`. rustdoc will forward that flag when invoking rustc (i.e., us), so the
-        // flag is present in `info.args`.
-        cmd.arg("--sysroot").arg(env::var_os("MIRI_SYSROOT").unwrap());
-    }
-    // Forward rustc arguments.
-    // We need to patch "--extern" filenames because we forced a check-only
-    // build without cargo knowing about that: replace `.rlib` suffix by
-    // `.rmeta`.
-    // We also need to remove `--error-format` as cargo specifies that to be JSON,
-    // but when we run here, cargo does not interpret the JSON any more. `--json`
-    // then also needs to be dropped.
-    let mut args = info.args.into_iter();
-    while let Some(arg) = args.next() {
-        if arg == "--extern" {
-            forward_patched_extern_arg(&mut args, &mut cmd);
-        } else if let Some(suffix) = arg.strip_prefix("--error-format") {
-            assert!(suffix.starts_with('='));
-            // Drop this argument.
-        } else if let Some(suffix) = arg.strip_prefix("--json") {
-            assert!(suffix.starts_with('='));
-            // Drop this argument.
-        } else {
-            cmd.arg(arg);
+        if phase != RunnerPhase::Rustdoc {
+            // Set the sysroot. Not necessary in rustdoc, where we already set the sysroot in
+            // `phase_rustdoc`. rustdoc will forward that flag when invoking rustc (i.e., us), so the
+            // flag is present in `info.args`.
+            cmd.arg("--sysroot").arg(env::var_os("MIRI_SYSROOT").unwrap());
+        }
+        // Forward rustc arguments.
+        // We need to patch "--extern" filenames because we forced a check-only
+        // build without cargo knowing about that: replace `.rlib` suffix by
+        // `.rmeta`.
+        // We also need to remove `--error-format` as cargo specifies that to be JSON,
+        // but when we run here, cargo does not interpret the JSON any more. `--json`
+        // then also needs to be dropped.
+        let mut args = info.args.iter();
+        while let Some(arg) = args.next() {
+            if arg == "--extern" {
+                forward_patched_extern_arg(&mut (&mut args).cloned(), &mut cmd);
+            } else if let Some(suffix) = arg.strip_prefix("--error-format") {
+                assert!(suffix.starts_with('='));
+                // Drop this argument.
+            } else if let Some(suffix) = arg.strip_prefix("--json") {
+                assert!(suffix.starts_with('='));
+                // Drop this argument.
+            } else {
+                cmd.arg(arg);
+            }
+        }
+        // Respect `MIRIFLAGS`.
+        if let Ok(a) = env::var("MIRIFLAGS") {
+            let args = flagsplit(&a);
+            cmd.args(args);
+        }
+        // Set the current seed.
+        if let Some(seed) = seed {
+            eprintln!("Trying seed: {seed}");
+            cmd.arg(format!("-Zmiri-seed={seed}"));
         }
-    }
-    // Respect `MIRIFLAGS`.
-    if let Ok(a) = env::var("MIRIFLAGS") {
-        let args = flagsplit(&a);
-        cmd.args(args);
-    }
-
-    // Then pass binary arguments.
-    cmd.arg("--");
-    cmd.args(binary_args);
-
-    // Make sure we use the build-time working directory for interpreting Miri/rustc arguments.
-    // But then we need to switch to the run-time one, which we instruct Miri to do by setting `MIRI_CWD`.
-    cmd.current_dir(info.current_dir);
-    cmd.env("MIRI_CWD", env::current_dir().unwrap());
 
-    // Run it.
-    debug_cmd("[cargo-miri runner]", verbose, &cmd);
-    match phase {
-        RunnerPhase::Rustdoc => exec_with_pipe(cmd, &info.stdin, format!("{binary}.stdin")),
-        RunnerPhase::Cargo => exec(cmd),
-    }
+        // Then pass binary arguments.
+        cmd.arg("--");
+        cmd.args(&binary_args);
+
+        // Make sure we use the build-time working directory for interpreting Miri/rustc arguments.
+        // But then we need to switch to the run-time one, which we instruct Miri to do by setting `MIRI_CWD`.
+        cmd.current_dir(&info.current_dir);
+        cmd.env("MIRI_CWD", env::current_dir().unwrap());
+
+        // Run it.
+        debug_cmd("[cargo-miri runner]", verbose, &cmd);
+
+        match phase {
+            RunnerPhase::Rustdoc => {
+                cmd.stdin(std::process::Stdio::piped());
+                let mut child = cmd.spawn().expect("failed to spawn process");
+                let child_stdin = child.stdin.take().unwrap();
+                // Write stdin in a background thread, as it may block.
+                let exit_status = thread::scope(|s| {
+                    s.spawn(|| {
+                        let mut child_stdin = child_stdin;
+                        // Ignore failure, it is most likely due to the process having terminated.
+                        let _ = child_stdin.write_all(&info.stdin);
+                    });
+                    child.wait().expect("failed to run command")
+                });
+                if !exit_status.success() {
+                    std::process::exit(exit_status.code().unwrap_or(-1));
+                }
+            }
+            RunnerPhase::Cargo => {
+                let exit_status = cmd.status().expect("failed to run command");
+                if !exit_status.success() {
+                    std::process::exit(exit_status.code().unwrap_or(-1));
+                }
+            }
+        }
+    });
 }
 
 pub fn phase_rustdoc(mut args: impl Iterator<Item = String>) {
-    let verbose = std::env::var("MIRI_VERBOSE")
+    let verbose = env::var("MIRI_VERBOSE")
         .map_or(0, |verbose| verbose.parse().expect("verbosity flag must be an integer"));
 
     // phase_cargo_miri sets the RUSTDOC env var to ourselves, and puts a backup
@@ -681,7 +725,7 @@ pub fn phase_rustdoc(mut args: impl Iterator<Item = String>) {
     cmd.arg("--cfg").arg("miri");
 
     // Make rustdoc call us back.
-    let cargo_miri_path = std::env::current_exe().expect("current executable path invalid");
+    let cargo_miri_path = env::current_exe().expect("current executable path invalid");
     cmd.arg("--test-builder").arg(&cargo_miri_path); // invoked by forwarding most arguments
     cmd.arg("--runtool").arg(&cargo_miri_path); // invoked with just a single path argument
 
diff --git a/src/tools/miri/cargo-miri/src/util.rs b/src/tools/miri/cargo-miri/src/util.rs
index f36cff1f798..5f2794e2244 100644
--- a/src/tools/miri/cargo-miri/src/util.rs
+++ b/src/tools/miri/cargo-miri/src/util.rs
@@ -171,11 +171,16 @@ where
         drop(path); // We don't need the path, we can pipe the bytes directly
         cmd.stdin(std::process::Stdio::piped());
         let mut child = cmd.spawn().expect("failed to spawn process");
-        {
-            let stdin = child.stdin.as_mut().expect("failed to open stdin");
-            stdin.write_all(input).expect("failed to write out test source");
-        }
-        let exit_status = child.wait().expect("failed to run command");
+        let child_stdin = child.stdin.take().unwrap();
+        // Write stdin in a background thread, as it may block.
+        let exit_status = std::thread::scope(|s| {
+            s.spawn(|| {
+                let mut child_stdin = child_stdin;
+                // Ignore failure, it is most likely due to the process having terminated.
+                let _ = child_stdin.write_all(input);
+            });
+            child.wait().expect("failed to run command")
+        });
         std::process::exit(exit_status.code().unwrap_or(-1))
     }
 }
@@ -317,3 +322,24 @@ pub fn clean_target_dir(meta: &Metadata) {
 
     remove_dir_all_idem(&target_dir).unwrap_or_else(|err| show_error!("{}", err))
 }
+
+/// Run `f` according to the many-seeds argument. In single-seed mode, `f` will only
+/// be called once, with `None`.
+pub fn run_many_seeds(many_seeds: Option<String>, f: impl Fn(Option<u32>)) {
+    let Some(many_seeds) = many_seeds else {
+        return f(None);
+    };
+    let (from, to) = many_seeds
+        .split_once("..")
+        .unwrap_or_else(|| show_error!("invalid format for `--many-seeds`: expected `from..to`"));
+    let from: u32 = if from.is_empty() {
+        0
+    } else {
+        from.parse().unwrap_or_else(|_| show_error!("invalid `from` in `--many-seeds=from..to"))
+    };
+    let to: u32 =
+        to.parse().unwrap_or_else(|_| show_error!("invalid `to` in `--many-seeds=from..to"));
+    for seed in from..to {
+        f(Some(seed));
+    }
+}
diff --git a/src/tools/miri/miri-script/src/main.rs b/src/tools/miri/miri-script/src/main.rs
index d436ef0c5aa..c4f0d808d93 100644
--- a/src/tools/miri/miri-script/src/main.rs
+++ b/src/tools/miri/miri-script/src/main.rs
@@ -98,7 +98,7 @@ Build miri, set up a sysroot and then run the test suite.
 Build miri, set up a sysroot and then run the driver with the given <flags>.
 (Also respects MIRIFLAGS environment variable.)
 If `--many-seeds` is present, Miri is run many times in parallel with different seeds.
-The range defaults to `0..256`.
+The range defaults to `0..64`.
 
 ./miri fmt <flags>:
 Format all sources and tests. <flags> are passed to `rustfmt`.
@@ -180,17 +180,16 @@ fn main() -> Result<()> {
                     dep = true;
                 } else if args.get_long_flag("verbose")? || args.get_short_flag('v')? {
                     verbose = true;
-                } else if let Some(val) = args.get_long_opt_with_default("many-seeds", "0..256")? {
+                } else if let Some(val) = args.get_long_opt_with_default("many-seeds", "0..64")? {
                     let (from, to) = val.split_once("..").ok_or_else(|| {
-                        anyhow!("invalid format for `--many-seeds-range`: expected `from..to`")
+                        anyhow!("invalid format for `--many-seeds`: expected `from..to`")
                     })?;
                     let from: u32 = if from.is_empty() {
                         0
                     } else {
-                        from.parse().context("invalid `from` in `--many-seeds-range=from..to")?
+                        from.parse().context("invalid `from` in `--many-seeds=from..to")?
                     };
-                    let to: u32 =
-                        to.parse().context("invalid `to` in `--many-seeds-range=from..to")?;
+                    let to: u32 = to.parse().context("invalid `to` in `--many-seeds=from..to")?;
                     many_seeds = Some(from..to);
                 } else if let Some(val) = args.get_long_opt("target")? {
                     target = Some(val);
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 0f738653b14..e49680ba75a 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-565cadb514d35e7b851540edbc172af0f606014f
+f6b4b71ef10307201b52c17b0f9dcf9557cd90ba
diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs
index 76a045c4dc1..91865a2192c 100644
--- a/src/tools/miri/src/concurrency/sync.rs
+++ b/src/tools/miri/src/concurrency/sync.rs
@@ -45,7 +45,7 @@ macro_rules! declare_id {
                 // We use 0 as a sentinel value (see the comment above) and,
                 // therefore, need to shift by one when converting from an index
                 // into a vector.
-                let shifted_idx = u32::try_from(idx).unwrap().checked_add(1).unwrap();
+                let shifted_idx = u32::try_from(idx).unwrap().strict_add(1);
                 $name(std::num::NonZero::new(shifted_idx).unwrap())
             }
             fn index(self) -> usize {
@@ -350,7 +350,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         } else {
             mutex.owner = Some(thread);
         }
-        mutex.lock_count = mutex.lock_count.checked_add(1).unwrap();
+        mutex.lock_count = mutex.lock_count.strict_add(1);
         if let Some(data_race) = &this.machine.data_race {
             data_race.acquire_clock(&mutex.clock, &this.machine.threads);
         }
@@ -370,9 +370,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 return Ok(None);
             }
             let old_lock_count = mutex.lock_count;
-            mutex.lock_count = old_lock_count
-                .checked_sub(1)
-                .expect("invariant violation: lock_count == 0 iff the thread is unlocked");
+            mutex.lock_count = old_lock_count.strict_sub(1);
             if mutex.lock_count == 0 {
                 mutex.owner = None;
                 // The mutex is completely unlocked. Try transferring ownership
@@ -450,7 +448,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         trace!("rwlock_reader_lock: {:?} now also held (one more time) by {:?}", id, thread);
         let rwlock = &mut this.machine.sync.rwlocks[id];
         let count = rwlock.readers.entry(thread).or_insert(0);
-        *count = count.checked_add(1).expect("the reader counter overflowed");
+        *count = count.strict_add(1);
         if let Some(data_race) = &this.machine.data_race {
             data_race.acquire_clock(&rwlock.clock_unlocked, &this.machine.threads);
         }
diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs
index c3b34f0c0c6..a5afd029b65 100644
--- a/src/tools/miri/src/intrinsics/simd.rs
+++ b/src/tools/miri/src/intrinsics/simd.rs
@@ -643,10 +643,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 assert_eq!(index_len as u64, dest_len);
 
                 for i in 0..dest_len {
-                    let src_index: u64 = index[usize::try_from(i).unwrap()]
-                        .unwrap_leaf()
-                        .to_u32()
-                        .into();
+                    let src_index: u64 =
+                        index[usize::try_from(i).unwrap()].unwrap_leaf().to_u32().into();
                     let dest = this.project_index(&dest, i)?;
 
                     let val = if src_index < left_len {
diff --git a/src/tools/miri/src/shims/os_str.rs b/src/tools/miri/src/shims/os_str.rs
index 68eca5a3a0f..533992e35ab 100644
--- a/src/tools/miri/src/shims/os_str.rs
+++ b/src/tools/miri/src/shims/os_str.rs
@@ -142,7 +142,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         os_str: &OsStr,
         memkind: MemoryKind,
     ) -> InterpResult<'tcx, Pointer> {
-        let size = u64::try_from(os_str.len()).unwrap().checked_add(1).unwrap(); // Make space for `0` terminator.
+        let size = u64::try_from(os_str.len()).unwrap().strict_add(1); // Make space for `0` terminator.
         let this = self.eval_context_mut();
 
         let arg_type = Ty::new_array(this.tcx.tcx, this.tcx.types.u8, size);
@@ -158,7 +158,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         os_str: &OsStr,
         memkind: MemoryKind,
     ) -> InterpResult<'tcx, Pointer> {
-        let size = u64::try_from(os_str.len()).unwrap().checked_add(1).unwrap(); // Make space for `0x0000` terminator.
+        let size = u64::try_from(os_str.len()).unwrap().strict_add(1); // Make space for `0x0000` terminator.
         let this = self.eval_context_mut();
 
         let arg_type = Ty::new_array(this.tcx.tcx, this.tcx.types.u16, size);
diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs
index c8805f054ec..262e71756c6 100644
--- a/src/tools/miri/src/shims/unix/fs.rs
+++ b/src/tools/miri/src/shims/unix/fs.rs
@@ -893,7 +893,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
                 let dirent64_layout = this.libc_ty_layout("dirent64");
                 let d_name_offset = dirent64_layout.fields.offset(4 /* d_name */).bytes();
-                let size = d_name_offset.checked_add(name_len).unwrap();
+                let size = d_name_offset.strict_add(name_len);
 
                 let entry = this.allocate_ptr(
                     Size::from_bytes(size),
@@ -994,7 +994,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     name_place.ptr(),
                     name_place.layout.size.bytes(),
                 )?;
-                let file_name_len = file_name_buf_len.checked_sub(1).unwrap();
+                let file_name_len = file_name_buf_len.strict_sub(1);
                 if !name_fits {
                     throw_unsup_format!(
                         "a directory entry had a name too large to fit in libc::dirent"
diff --git a/src/tools/miri/src/shims/unix/linux/epoll.rs b/src/tools/miri/src/shims/unix/linux/epoll.rs
index aa4dc982870..a5661460e95 100644
--- a/src/tools/miri/src/shims/unix/linux/epoll.rs
+++ b/src/tools/miri/src/shims/unix/linux/epoll.rs
@@ -57,10 +57,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let flags = this.read_scalar(flags)?.to_i32()?;
 
         let epoll_cloexec = this.eval_libc_i32("EPOLL_CLOEXEC");
-        if flags == epoll_cloexec {
-            // Miri does not support exec, so this flag has no effect.
-        } else if flags != 0 {
-            throw_unsup_format!("epoll_create1 flags {flags} are not implemented");
+
+        // Miri does not support exec, so EPOLL_CLOEXEC flag has no effect.
+        if flags != epoll_cloexec && flags != 0 {
+            throw_unsup_format!(
+                "epoll_create1: flag {:#x} is unsupported, only 0 or EPOLL_CLOEXEC are allowed",
+                flags
+            );
         }
 
         let fd = this.machine.fds.insert_fd(FileDescriptor::new(Epoll::default()));
diff --git a/src/tools/miri/src/shims/unix/socket.rs b/src/tools/miri/src/shims/unix/socket.rs
index 97bf6348f0b..c639ea2f846 100644
--- a/src/tools/miri/src/shims/unix/socket.rs
+++ b/src/tools/miri/src/shims/unix/socket.rs
@@ -1,15 +1,38 @@
+use std::cell::RefCell;
+use std::collections::VecDeque;
 use std::io;
+use std::io::{Error, ErrorKind, Read};
+use std::rc::{Rc, Weak};
 
 use crate::shims::unix::*;
-use crate::*;
+use crate::{concurrency::VClock, *};
 
 use self::fd::FileDescriptor;
 
+/// The maximum capacity of the socketpair buffer in bytes.
+/// This number is arbitrary as the value can always
+/// be configured in the real system.
+const MAX_SOCKETPAIR_BUFFER_CAPACITY: usize = 212992;
+
 /// Pair of connected sockets.
-///
-/// We currently don't allow sending any data through this pair, so this can be just a dummy.
 #[derive(Debug)]
-struct SocketPair;
+struct SocketPair {
+    // By making the write link weak, a `write` can detect when all readers are
+    // gone, and trigger EPIPE as appropriate.
+    writebuf: Weak<RefCell<Buffer>>,
+    readbuf: Rc<RefCell<Buffer>>,
+    is_nonblock: bool,
+}
+
+#[derive(Debug)]
+struct Buffer {
+    buf: VecDeque<u8>,
+    clock: VClock,
+    /// Indicates if there is at least one active writer to this buffer.
+    /// If all writers of this buffer are dropped, buf_has_writer becomes false and we
+    /// indicate EOF instead of blocking.
+    buf_has_writer: bool,
+}
 
 impl FileDescription for SocketPair {
     fn name(&self) -> &'static str {
@@ -20,17 +43,102 @@ impl FileDescription for SocketPair {
         self: Box<Self>,
         _communicate_allowed: bool,
     ) -> InterpResult<'tcx, io::Result<()>> {
+        // This is used to signal socketfd of other side that there is no writer to its readbuf.
+        // If the upgrade fails, there is no need to update as all read ends have been dropped.
+        if let Some(writebuf) = self.writebuf.upgrade() {
+            writebuf.borrow_mut().buf_has_writer = false;
+        };
         Ok(Ok(()))
     }
+
+    fn read<'tcx>(
+        &mut self,
+        _communicate_allowed: bool,
+        bytes: &mut [u8],
+        ecx: &mut MiriInterpCx<'tcx>,
+    ) -> InterpResult<'tcx, io::Result<usize>> {
+        let request_byte_size = bytes.len();
+        let mut readbuf = self.readbuf.borrow_mut();
+
+        // Always succeed on read size 0.
+        if request_byte_size == 0 {
+            return Ok(Ok(0));
+        }
+
+        if readbuf.buf.is_empty() {
+            if !readbuf.buf_has_writer {
+                // Socketpair with no writer and empty buffer.
+                // 0 bytes successfully read indicates end-of-file.
+                return Ok(Ok(0));
+            } else {
+                if self.is_nonblock {
+                    // Non-blocking socketpair with writer and empty buffer.
+                    // https://linux.die.net/man/2/read
+                    // EAGAIN or EWOULDBLOCK can be returned for socket,
+                    // POSIX.1-2001 allows either error to be returned for this case.
+                    // Since there is no ErrorKind for EAGAIN, WouldBlock is used.
+                    return Ok(Err(Error::from(ErrorKind::WouldBlock)));
+                } else {
+                    // Blocking socketpair with writer and empty buffer.
+                    // FIXME: blocking is currently not supported
+                    throw_unsup_format!("socketpair read: blocking isn't supported yet");
+                }
+            }
+        }
+
+        // Synchronize with all previous writes to this buffer.
+        // FIXME: this over-synchronizes; a more precise approach would be to
+        // only sync with the writes whose data we will read.
+        ecx.acquire_clock(&readbuf.clock);
+        // Do full read / partial read based on the space available.
+        // Conveniently, `read` exists on `VecDeque` and has exactly the desired behavior.
+        let actual_read_size = readbuf.buf.read(bytes).unwrap();
+        return Ok(Ok(actual_read_size));
+    }
+
+    fn write<'tcx>(
+        &mut self,
+        _communicate_allowed: bool,
+        bytes: &[u8],
+        ecx: &mut MiriInterpCx<'tcx>,
+    ) -> InterpResult<'tcx, io::Result<usize>> {
+        let write_size = bytes.len();
+        // Always succeed on write size 0.
+        // ("If count is zero and fd refers to a file other than a regular file, the results are not specified.")
+        if write_size == 0 {
+            return Ok(Ok(0));
+        }
+
+        let Some(writebuf) = self.writebuf.upgrade() else {
+            // If the upgrade from Weak to Rc fails, it indicates that all read ends have been
+            // closed.
+            return Ok(Err(Error::from(ErrorKind::BrokenPipe)));
+        };
+        let mut writebuf = writebuf.borrow_mut();
+        let data_size = writebuf.buf.len();
+        let available_space = MAX_SOCKETPAIR_BUFFER_CAPACITY.checked_sub(data_size).unwrap();
+        if available_space == 0 {
+            if self.is_nonblock {
+                // Non-blocking socketpair with a full buffer.
+                return Ok(Err(Error::from(ErrorKind::WouldBlock)));
+            } else {
+                // Blocking socketpair with a full buffer.
+                throw_unsup_format!("socketpair write: blocking isn't supported yet");
+            }
+        }
+        // Remember this clock so `read` can synchronize with us.
+        if let Some(clock) = &ecx.release_clock() {
+            writebuf.clock.join(clock);
+        }
+        // Do full write / partial write based on the space available.
+        let actual_write_size = write_size.min(available_space);
+        writebuf.buf.extend(&bytes[..actual_write_size]);
+        return Ok(Ok(actual_write_size));
+    }
 }
 
 impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
 pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
-    /// Currently this function this function is a stub. Eventually we need to
-    /// properly implement an FD type for sockets and have this function create
-    /// two sockets and associated FDs such that writing to one will produce
-    /// data that can be read from the other.
-    ///
     /// For more information on the arguments see the socketpair manpage:
     /// <https://linux.die.net/man/2/socketpair>
     fn socketpair(
@@ -42,17 +150,80 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     ) -> InterpResult<'tcx, Scalar> {
         let this = self.eval_context_mut();
 
-        let _domain = this.read_scalar(domain)?.to_i32()?;
-        let _type_ = this.read_scalar(type_)?.to_i32()?;
-        let _protocol = this.read_scalar(protocol)?.to_i32()?;
+        let domain = this.read_scalar(domain)?.to_i32()?;
+        let mut type_ = this.read_scalar(type_)?.to_i32()?;
+        let protocol = this.read_scalar(protocol)?.to_i32()?;
         let sv = this.deref_pointer(sv)?;
 
-        // FIXME: fail on unsupported inputs
+        let mut is_sock_nonblock = false;
+
+        // Parse and remove the type flags that we support. If type != 0 after removing,
+        // unsupported flags are used.
+        if type_ & this.eval_libc_i32("SOCK_STREAM") == this.eval_libc_i32("SOCK_STREAM") {
+            type_ &= !(this.eval_libc_i32("SOCK_STREAM"));
+        }
+
+        // SOCK_NONBLOCK only exists on Linux.
+        if this.tcx.sess.target.os == "linux" {
+            if type_ & this.eval_libc_i32("SOCK_NONBLOCK") == this.eval_libc_i32("SOCK_NONBLOCK") {
+                is_sock_nonblock = true;
+                type_ &= !(this.eval_libc_i32("SOCK_NONBLOCK"));
+            }
+            if type_ & this.eval_libc_i32("SOCK_CLOEXEC") == this.eval_libc_i32("SOCK_CLOEXEC") {
+                type_ &= !(this.eval_libc_i32("SOCK_CLOEXEC"));
+            }
+        }
+
+        // Fail on unsupported input.
+        // AF_UNIX and AF_LOCAL are synonyms, so we accept both in case
+        // their values differ.
+        if domain != this.eval_libc_i32("AF_UNIX") && domain != this.eval_libc_i32("AF_LOCAL") {
+            throw_unsup_format!(
+                "socketpair: domain {:#x} is unsupported, only AF_UNIX \
+                                 and AF_LOCAL are allowed",
+                domain
+            );
+        } else if type_ != 0 {
+            throw_unsup_format!(
+                "socketpair: type {:#x} is unsupported, only SOCK_STREAM, \
+                                 SOCK_CLOEXEC and SOCK_NONBLOCK are allowed",
+                type_
+            );
+        } else if protocol != 0 {
+            throw_unsup_format!(
+                "socketpair: socket protocol {protocol} is unsupported, \
+                                 only 0 is allowed",
+            );
+        }
+
+        let buffer1 = Rc::new(RefCell::new(Buffer {
+            buf: VecDeque::new(),
+            clock: VClock::default(),
+            buf_has_writer: true,
+        }));
+
+        let buffer2 = Rc::new(RefCell::new(Buffer {
+            buf: VecDeque::new(),
+            clock: VClock::default(),
+            buf_has_writer: true,
+        }));
+
+        let socketpair_0 = SocketPair {
+            writebuf: Rc::downgrade(&buffer1),
+            readbuf: Rc::clone(&buffer2),
+            is_nonblock: is_sock_nonblock,
+        };
+
+        let socketpair_1 = SocketPair {
+            writebuf: Rc::downgrade(&buffer2),
+            readbuf: Rc::clone(&buffer1),
+            is_nonblock: is_sock_nonblock,
+        };
 
         let fds = &mut this.machine.fds;
-        let sv0 = fds.insert_fd(FileDescriptor::new(SocketPair));
+        let sv0 = fds.insert_fd(FileDescriptor::new(socketpair_0));
         let sv0 = Scalar::from_int(sv0, sv.layout.size);
-        let sv1 = fds.insert_fd(FileDescriptor::new(SocketPair));
+        let sv1 = fds.insert_fd(FileDescriptor::new(socketpair_1));
         let sv1 = Scalar::from_int(sv1, sv.layout.size);
 
         this.write_scalar(sv0, &sv)?;
diff --git a/src/tools/miri/src/shims/x86/avx.rs b/src/tools/miri/src/shims/x86/avx.rs
index 07d737e0663..0d2977b7b6f 100644
--- a/src/tools/miri/src/shims/x86/avx.rs
+++ b/src/tools/miri/src/shims/x86/avx.rs
@@ -176,8 +176,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     // of 4.
                     let chunk_base = i & !0b11;
                     let src_i = u64::from(this.read_scalar(&control)?.to_u32()? & 0b11)
-                        .checked_add(chunk_base)
-                        .unwrap();
+                        .strict_add(chunk_base);
 
                     this.copy_op(
                         &this.project_index(&data, src_i)?,
@@ -210,9 +209,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     // second instead of the first, ask Intel). To read the value from the current
                     // chunk, add the destination index truncated to a multiple of 2.
                     let chunk_base = i & !1;
-                    let src_i = ((this.read_scalar(&control)?.to_u64()? >> 1) & 1)
-                        .checked_add(chunk_base)
-                        .unwrap();
+                    let src_i =
+                        ((this.read_scalar(&control)?.to_u64()? >> 1) & 1).strict_add(chunk_base);
 
                     this.copy_op(
                         &this.project_index(&data, src_i)?,
diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs
index f2d120df21c..b71aec02166 100644
--- a/src/tools/miri/src/shims/x86/mod.rs
+++ b/src/tools/miri/src/shims/x86/mod.rs
@@ -18,6 +18,7 @@ mod sse;
 mod sse2;
 mod sse3;
 mod sse41;
+mod sse42;
 mod ssse3;
 
 impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
@@ -137,6 +138,11 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     this, link_name, abi, args, dest,
                 );
             }
+            name if name.starts_with("sse42.") => {
+                return sse42::EvalContextExt::emulate_x86_sse42_intrinsic(
+                    this, link_name, abi, args, dest,
+                );
+            }
             name if name.starts_with("aesni.") => {
                 return aesni::EvalContextExt::emulate_x86_aesni_intrinsic(
                     this, link_name, abi, args, dest,
diff --git a/src/tools/miri/src/shims/x86/sse42.rs b/src/tools/miri/src/shims/x86/sse42.rs
new file mode 100644
index 00000000000..4e50d5e5dcf
--- /dev/null
+++ b/src/tools/miri/src/shims/x86/sse42.rs
@@ -0,0 +1,500 @@
+use rustc_middle::mir;
+use rustc_middle::ty::layout::LayoutOf as _;
+use rustc_middle::ty::Ty;
+use rustc_span::Symbol;
+use rustc_target::abi::Size;
+use rustc_target::spec::abi::Abi;
+
+use crate::*;
+
+/// A bitmask constant for scrutinizing the immediate byte provided
+/// to the string comparison intrinsics. It distinuishes between
+/// 16-bit integers and 8-bit integers. See [`compare_strings`]
+/// for more details about the immediate byte.
+const USE_WORDS: u8 = 1;
+
+/// A bitmask constant for scrutinizing the immediate byte provided
+/// to the string comparison intrinsics. It distinuishes between
+/// signed integers and unsigned integers. See [`compare_strings`]
+/// for more details about the immediate byte.
+const USE_SIGNED: u8 = 2;
+
+/// The main worker for the string comparison intrinsics, where the given
+/// strings are analyzed according to the given immediate byte.
+///
+/// # Arguments
+///
+/// * `str1` - The first string argument. It is always a length 16 array of bytes
+///   or a length 8 array of two-byte words.
+/// * `str2` - The second string argument. It is always a length 16 array of bytes
+///   or a length 8 array of two-byte words.
+/// * `len` is the length values of the supplied strings. It is distinct from the operand length
+///   in that it describes how much of `str1` and `str2` will be used for the calculation and may
+///   be smaller than the array length of `str1` and `str2`. The string length is counted in bytes
+///   if using byte operands and in two-byte words when using two-byte word operands.
+///   If the value is `None`, the length of a string is determined by the first
+///   null value inside the string.
+/// * `imm` is the immediate byte argument supplied to the intrinsic. The byte influences
+///   the operation as follows:
+///
+///   ```text
+///   0babccddef
+///     || | |||- Use of bytes vs use of two-byte words inside the operation.
+///     || | ||
+///     || | ||- Use of signed values versus use of unsigned values.
+///     || | |
+///     || | |- The comparison operation performed. A total of four operations are available.
+///     || |    * Equal any: Checks which characters of `str2` are inside `str1`.
+///     || |    * String ranges: Check if characters in `str2` are inside the provided character ranges.
+///     || |      Adjacent characters in `str1` constitute one range.
+///     || |    * String comparison: Mark positions where `str1` and `str2` have the same character.
+///     || |    * Substring search: Mark positions where `str1` is a substring in `str2`.
+///     || |
+///     || |- Result Polarity. The result bits may be subjected to a bitwise complement
+///     ||    if these bits are set.
+///     ||
+///     ||- Output selection. This bit has two meanings depending on the instruction.
+///     |   If the instruction is generating a mask, it distinguishes between a bit mask
+///     |   and a byte mask. Otherwise it distinguishes between the most significand bit
+///     |   and the least significand bit when generating an index.
+///     |
+///     |- This bit is ignored. It is expected that this bit is set to zero, but it is
+///        not a requirement.
+///   ```
+///
+/// # Returns
+///
+/// A result mask. The bit at index `i` inside the mask is set if 'str2' starting at `i`
+/// fulfills the test as defined inside the immediate byte.
+/// The mask may be negated if negation flags inside the immediate byte are set.
+///
+/// For more information, see the Intel Software Developer's Manual, Vol. 2b, Chapter 4.1.
+#[allow(clippy::arithmetic_side_effects)]
+fn compare_strings<'tcx>(
+    this: &mut MiriInterpCx<'tcx>,
+    str1: &OpTy<'tcx>,
+    str2: &OpTy<'tcx>,
+    len: Option<(u64, u64)>,
+    imm: u8,
+) -> InterpResult<'tcx, i32> {
+    let default_len = default_len::<u64>(imm);
+    let (len1, len2) = if let Some(t) = len {
+        t
+    } else {
+        let len1 = implicit_len(this, str1, imm)?.unwrap_or(default_len);
+        let len2 = implicit_len(this, str2, imm)?.unwrap_or(default_len);
+        (len1, len2)
+    };
+
+    let mut result = 0;
+    match (imm >> 2) & 3 {
+        0 => {
+            // Equal any: Checks which characters of `str2` are inside `str1`.
+            for i in 0..len2 {
+                let ch2 = this.read_immediate(&this.project_index(str2, i)?)?;
+
+                for j in 0..len1 {
+                    let ch1 = this.read_immediate(&this.project_index(str1, j)?)?;
+
+                    let eq = this.binary_op(mir::BinOp::Eq, &ch1, &ch2)?;
+                    if eq.to_scalar().to_bool()? {
+                        result |= 1 << i;
+                        break;
+                    }
+                }
+            }
+        }
+        1 => {
+            // String ranges: Check if characters in `str2` are inside the provided character ranges.
+            // Adjacent characters in `str1` constitute one range.
+            let len1 = len1 - (len1 & 1);
+            let get_ch = |ch: Scalar| -> InterpResult<'tcx, i32> {
+                let result = match (imm & USE_WORDS != 0, imm & USE_SIGNED != 0) {
+                    (true, true) => i32::from(ch.to_i16()?),
+                    (true, false) => i32::from(ch.to_u16()?),
+                    (false, true) => i32::from(ch.to_i8()?),
+                    (false, false) => i32::from(ch.to_u8()?),
+                };
+                Ok(result)
+            };
+
+            for i in 0..len2 {
+                for j in (0..len1).step_by(2) {
+                    let ch2 = get_ch(this.read_scalar(&this.project_index(str2, i)?)?)?;
+                    let ch1_1 = get_ch(this.read_scalar(&this.project_index(str1, j)?)?)?;
+                    let ch1_2 = get_ch(this.read_scalar(&this.project_index(str1, j + 1)?)?)?;
+
+                    if ch1_1 <= ch2 && ch2 <= ch1_2 {
+                        result |= 1 << i;
+                    }
+                }
+            }
+        }
+        2 => {
+            // String comparison: Mark positions where `str1` and `str2` have the same character.
+            result = (1 << default_len) - 1;
+            result ^= (1 << len1.max(len2)) - 1;
+
+            for i in 0..len1.min(len2) {
+                let ch1 = this.read_immediate(&this.project_index(str1, i)?)?;
+                let ch2 = this.read_immediate(&this.project_index(str2, i)?)?;
+                let eq = this.binary_op(mir::BinOp::Eq, &ch1, &ch2)?;
+                result |= i32::from(eq.to_scalar().to_bool()?) << i;
+            }
+        }
+        3 => {
+            // Substring search: Mark positions where `str1` is a substring in `str2`.
+            if len1 == 0 {
+                result = (1 << default_len) - 1;
+            } else if len1 <= len2 {
+                for i in 0..len2 {
+                    if len1 > len2 - i {
+                        break;
+                    }
+
+                    result |= 1 << i;
+
+                    for j in 0..len1 {
+                        let k = i + j;
+
+                        if k >= default_len {
+                            break;
+                        } else {
+                            let ch1 = this.read_immediate(&this.project_index(str1, j)?)?;
+                            let ch2 = this.read_immediate(&this.project_index(str2, k)?)?;
+                            let ne = this.binary_op(mir::BinOp::Ne, &ch1, &ch2)?;
+
+                            if ne.to_scalar().to_bool()? {
+                                result &= !(1 << i);
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        _ => unreachable!(),
+    }
+
+    // Polarity: Possibly perform a bitwise complement on the result.
+    match (imm >> 4) & 3 {
+        3 => result ^= (1 << len1) - 1,
+        1 => result ^= (1 << default_len) - 1,
+        _ => (),
+    }
+
+    Ok(result)
+}
+
+/// Obtain the arguments of the intrinsic based on its name.
+/// The result is a tuple with the following values:
+/// * The first string argument.
+/// * The second string argument.
+/// * The string length values, if the intrinsic requires them.
+/// * The immediate instruction byte.
+///
+/// The string arguments will be transmuted into arrays of bytes
+/// or two-byte words, depending on the value of the immediate byte.
+/// Originally, they are [__m128i](https://doc.rust-lang.org/stable/core/arch/x86_64/struct.__m128i.html) values
+/// corresponding to the x86 128-bit integer SIMD type.
+fn deconstruct_args<'tcx>(
+    unprefixed_name: &str,
+    this: &mut MiriInterpCx<'tcx>,
+    link_name: Symbol,
+    abi: Abi,
+    args: &[OpTy<'tcx>],
+) -> InterpResult<'tcx, (OpTy<'tcx>, OpTy<'tcx>, Option<(u64, u64)>, u8)> {
+    let array_layout_fn = |this: &mut MiriInterpCx<'tcx>, imm: u8| {
+        if imm & USE_WORDS != 0 {
+            this.layout_of(Ty::new_array(this.tcx.tcx, this.tcx.types.u16, 8))
+        } else {
+            this.layout_of(Ty::new_array(this.tcx.tcx, this.tcx.types.u8, 16))
+        }
+    };
+
+    // The fourth letter of each string comparison intrinsic is either 'e' for "explicit" or 'i' for "implicit".
+    // The distinction will correspond to the intrinsics type signature. In this constext, "explicit" and "implicit"
+    // refer to the way the string length is determined. The length is either passed explicitly in the "explicit"
+    // case or determined by a null terminator in the "implicit" case.
+    let is_explicit = match unprefixed_name.as_bytes().get(4) {
+        Some(&b'e') => true,
+        Some(&b'i') => false,
+        _ => unreachable!(),
+    };
+
+    if is_explicit {
+        let [str1, len1, str2, len2, imm] =
+            this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+        let imm = this.read_scalar(imm)?.to_u8()?;
+
+        let default_len = default_len::<u32>(imm);
+        let len1 = u64::from(this.read_scalar(len1)?.to_u32()?.min(default_len));
+        let len2 = u64::from(this.read_scalar(len2)?.to_u32()?.min(default_len));
+
+        let array_layout = array_layout_fn(this, imm)?;
+        let str1 = str1.transmute(array_layout, this)?;
+        let str2 = str2.transmute(array_layout, this)?;
+
+        Ok((str1, str2, Some((len1, len2)), imm))
+    } else {
+        let [str1, str2, imm] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+        let imm = this.read_scalar(imm)?.to_u8()?;
+
+        let array_layout = array_layout_fn(this, imm)?;
+        let str1 = str1.transmute(array_layout, this)?;
+        let str2 = str2.transmute(array_layout, this)?;
+
+        Ok((str1, str2, None, imm))
+    }
+}
+
+/// Calculate the c-style string length for a given string `str`.
+/// The string is either a length 16 array of bytes a length 8 array of two-byte words.
+fn implicit_len<'tcx>(
+    this: &mut MiriInterpCx<'tcx>,
+    str: &OpTy<'tcx>,
+    imm: u8,
+) -> InterpResult<'tcx, Option<u64>> {
+    let mut result = None;
+    let zero = ImmTy::from_int(0, str.layout.field(this, 0));
+
+    for i in 0..default_len::<u64>(imm) {
+        let ch = this.read_immediate(&this.project_index(str, i)?)?;
+        let is_zero = this.binary_op(mir::BinOp::Eq, &ch, &zero)?;
+        if is_zero.to_scalar().to_bool()? {
+            result = Some(i);
+            break;
+        }
+    }
+    Ok(result)
+}
+
+#[inline]
+fn default_len<T: From<u8>>(imm: u8) -> T {
+    if imm & USE_WORDS != 0 { T::from(8u8) } else { T::from(16u8) }
+}
+
+impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
+pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
+    fn emulate_x86_sse42_intrinsic(
+        &mut self,
+        link_name: Symbol,
+        abi: Abi,
+        args: &[OpTy<'tcx>],
+        dest: &MPlaceTy<'tcx>,
+    ) -> InterpResult<'tcx, EmulateItemResult> {
+        let this = self.eval_context_mut();
+        this.expect_target_feature_for_intrinsic(link_name, "sse4.2")?;
+        // Prefix should have already been checked.
+        let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.sse42.").unwrap();
+
+        match unprefixed_name {
+            // Used to implement the `_mm_cmpestrm` and the `_mm_cmpistrm` functions.
+            // These functions compare the input strings and return the resulting mask.
+            // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=1044,922
+            "pcmpistrm128" | "pcmpestrm128" => {
+                let (str1, str2, len, imm) =
+                    deconstruct_args(unprefixed_name, this, link_name, abi, args)?;
+                let mask = compare_strings(this, &str1, &str2, len, imm)?;
+
+                // The sixth bit inside the immediate byte distiguishes
+                // between a bit mask or a byte mask when generating a mask.
+                if imm & 0b100_0000 != 0 {
+                    let (array_layout, size) = if imm & USE_WORDS != 0 {
+                        (this.layout_of(Ty::new_array(this.tcx.tcx, this.tcx.types.u16, 8))?, 2)
+                    } else {
+                        (this.layout_of(Ty::new_array(this.tcx.tcx, this.tcx.types.u8, 16))?, 1)
+                    };
+                    let size = Size::from_bytes(size);
+                    let dest = dest.transmute(array_layout, this)?;
+
+                    for i in 0..default_len::<u64>(imm) {
+                        let result = helpers::bool_to_simd_element(mask & (1 << i) != 0, size);
+                        this.write_scalar(result, &this.project_index(&dest, i)?)?;
+                    }
+                } else {
+                    let layout = this.layout_of(this.tcx.types.i128)?;
+                    let dest = dest.transmute(layout, this)?;
+                    this.write_scalar(Scalar::from_i128(i128::from(mask)), &dest)?;
+                }
+            }
+
+            // Used to implement the `_mm_cmpestra` and the `_mm_cmpistra` functions.
+            // These functions compare the input strings and return `1` if the end of the second
+            // input string is not reached and the resulting mask is zero, and `0` otherwise.
+            // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=919,1041
+            "pcmpistria128" | "pcmpestria128" => {
+                let (str1, str2, len, imm) =
+                    deconstruct_args(unprefixed_name, this, link_name, abi, args)?;
+                let result = if compare_strings(this, &str1, &str2, len, imm)? != 0 {
+                    false
+                } else if let Some((_, len)) = len {
+                    len >= default_len::<u64>(imm)
+                } else {
+                    implicit_len(this, &str1, imm)?.is_some()
+                };
+
+                this.write_scalar(Scalar::from_i32(i32::from(result)), dest)?;
+            }
+
+            // Used to implement the `_mm_cmpestri` and the `_mm_cmpistri` functions.
+            // These functions compare the input strings and return the bit index
+            // for most significant or least significant bit of the resulting mask.
+            // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=921,1043
+            "pcmpistri128" | "pcmpestri128" => {
+                let (str1, str2, len, imm) =
+                    deconstruct_args(unprefixed_name, this, link_name, abi, args)?;
+                let mask = compare_strings(this, &str1, &str2, len, imm)?;
+
+                let len = default_len::<u32>(imm);
+                // The sixth bit inside the immediate byte distiguishes between the least
+                // significant bit and the most significant bit when generating an index.
+                let result = if imm & 0b100_0000 != 0 {
+                    // most significant bit
+                    31u32.wrapping_sub(mask.leading_zeros()).min(len)
+                } else {
+                    // least significant bit
+                    mask.trailing_zeros().min(len)
+                };
+                this.write_scalar(Scalar::from_i32(i32::try_from(result).unwrap()), dest)?;
+            }
+
+            // Used to implement the `_mm_cmpestro` and the `_mm_cmpistro` functions.
+            // These functions compare the input strings and return the lowest bit of the
+            // resulting mask.
+            // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=923,1045
+            "pcmpistrio128" | "pcmpestrio128" => {
+                let (str1, str2, len, imm) =
+                    deconstruct_args(unprefixed_name, this, link_name, abi, args)?;
+                let mask = compare_strings(this, &str1, &str2, len, imm)?;
+                this.write_scalar(Scalar::from_i32(mask & 1), dest)?;
+            }
+
+            // Used to implement the `_mm_cmpestrc` and the `_mm_cmpistrc` functions.
+            // These functions compare the input strings and return `1` if the resulting
+            // mask was non-zero, and `0` otherwise.
+            // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=920,1042
+            "pcmpistric128" | "pcmpestric128" => {
+                let (str1, str2, len, imm) =
+                    deconstruct_args(unprefixed_name, this, link_name, abi, args)?;
+                let mask = compare_strings(this, &str1, &str2, len, imm)?;
+                this.write_scalar(Scalar::from_i32(i32::from(mask != 0)), dest)?;
+            }
+
+            // Used to implement the `_mm_cmpistrz` and the `_mm_cmpistrs` functions.
+            // These functions return `1` if the string end has been reached and `0` otherwise.
+            // Since these functions define the string length implicitly, it is equal to a
+            // search for a null terminator (see `deconstruct_args` for more details).
+            // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=924,925
+            "pcmpistriz128" | "pcmpistris128" => {
+                let [str1, str2, imm] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let imm = this.read_scalar(imm)?.to_u8()?;
+
+                let str = if unprefixed_name == "pcmpistris128" { str1 } else { str2 };
+                let array_layout = if imm & USE_WORDS != 0 {
+                    this.layout_of(Ty::new_array(this.tcx.tcx, this.tcx.types.u16, 8))?
+                } else {
+                    this.layout_of(Ty::new_array(this.tcx.tcx, this.tcx.types.u8, 16))?
+                };
+                let str = str.transmute(array_layout, this)?;
+                let result = implicit_len(this, &str, imm)?.is_some();
+
+                this.write_scalar(Scalar::from_i32(i32::from(result)), dest)?;
+            }
+
+            // Used to implement the `_mm_cmpestrz` and the `_mm_cmpestrs` functions.
+            // These functions return 1 if the explicitly passed string length is smaller
+            // than 16 for byte-sized operands or 8 for word-sized operands.
+            // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=1046,1047
+            "pcmpestriz128" | "pcmpestris128" => {
+                let [_, len1, _, len2, imm] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let len = if unprefixed_name == "pcmpestris128" { len1 } else { len2 };
+                let len = this.read_scalar(len)?.to_i32()?;
+                let imm = this.read_scalar(imm)?.to_u8()?;
+                this.write_scalar(
+                    Scalar::from_i32(i32::from(len < default_len::<i32>(imm))),
+                    dest,
+                )?;
+            }
+
+            // Used to implement the `_mm_crc32_u{8, 16, 32, 64}` functions.
+            // These functions calculate a 32-bit CRC using `0x11EDC6F41`
+            // as the polynomial, also known as CRC32C.
+            // https://datatracker.ietf.org/doc/html/rfc3720#section-12.1
+            "crc32.32.8" | "crc32.32.16" | "crc32.32.32" | "crc32.64.64" => {
+                let bit_size = match unprefixed_name {
+                    "crc32.32.8" => 8,
+                    "crc32.32.16" => 16,
+                    "crc32.32.32" => 32,
+                    "crc32.64.64" => 64,
+                    _ => unreachable!(),
+                };
+
+                if bit_size == 64 && this.tcx.sess.target.arch != "x86_64" {
+                    return Ok(EmulateItemResult::NotSupported);
+                }
+
+                let [left, right] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let left = this.read_scalar(left)?;
+                let right = this.read_scalar(right)?;
+
+                let crc = if bit_size == 64 {
+                    // The 64-bit version will only consider the lower 32 bits,
+                    // while the upper 32 bits get discarded.
+                    #[allow(clippy::cast_possible_truncation)]
+                    u128::from((left.to_u64()? as u32).reverse_bits())
+                } else {
+                    u128::from(left.to_u32()?.reverse_bits())
+                };
+                let v = match bit_size {
+                    8 => u128::from(right.to_u8()?.reverse_bits()),
+                    16 => u128::from(right.to_u16()?.reverse_bits()),
+                    32 => u128::from(right.to_u32()?.reverse_bits()),
+                    64 => u128::from(right.to_u64()?.reverse_bits()),
+                    _ => unreachable!(),
+                };
+
+                // Perform polynomial division modulo 2.
+                // The algorithm for the division is an adapted version of the
+                // schoolbook division algorithm used for normal integer or polynomial
+                // division. In this context, the quotient is not calculated, since
+                // only the remainder is needed.
+                //
+                // The algorithm works as follows:
+                // 1. Pull down digits until division can be performed. In the context of division
+                //    modulo 2 it means locating the most significant digit of the dividend and shifting
+                //    the divisor such that the position of the divisors most significand digit and the
+                //    dividends most significand digit match.
+                // 2. Perform a division and determine the remainder. Since it is arithmetic modulo 2,
+                //    this operation is a simple bitwise exclusive or.
+                // 3. Repeat steps 1. and 2. until the full remainder is calculated. This is the case
+                //    once the degree of the remainder polynomial is smaller than the degree of the
+                //    divisor polynomial. In other words, the number of leading zeros of the remainder
+                //    is larger than the number of leading zeros of the divisor. It is important to
+                //    note that standard arithmetic comparison is not applicable here:
+                //    0b10011 / 0b11111 = 0b01100 is a valid division, even though the dividend is
+                //    smaller than the divisor.
+                let mut dividend = (crc << bit_size) ^ (v << 32);
+                const POLYNOMIAL: u128 = 0x11EDC6F41;
+                while dividend.leading_zeros() <= POLYNOMIAL.leading_zeros() {
+                    dividend ^=
+                        (POLYNOMIAL << POLYNOMIAL.leading_zeros()) >> dividend.leading_zeros();
+                }
+
+                let result = u32::try_from(dividend).unwrap().reverse_bits();
+                let result = if bit_size == 64 {
+                    Scalar::from_u64(u64::from(result))
+                } else {
+                    Scalar::from_u32(result)
+                };
+
+                this.write_scalar(result, dest)?;
+            }
+            _ => return Ok(EmulateItemResult::NotSupported),
+        }
+        Ok(EmulateItemResult::NeedsReturn)
+    }
+}
diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_read_blocking.rs b/src/tools/miri/tests/fail-dep/libc/socketpair_read_blocking.rs
new file mode 100644
index 00000000000..c28a6d966fe
--- /dev/null
+++ b/src/tools/miri/tests/fail-dep/libc/socketpair_read_blocking.rs
@@ -0,0 +1,12 @@
+//@ignore-target-windows: no libc socketpair on Windows
+
+// This is temporarily here because blocking on fd is not supported yet.
+// When blocking is eventually supported, this will be moved to pass-dep/libc/libc-socketpair
+
+fn main() {
+    let mut fds = [-1, -1];
+    let _ = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
+    // The read below will be blocked because the buffer is empty.
+    let mut buf: [u8; 3] = [0; 3];
+    let _res = unsafe { libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; //~ERROR: blocking isn't supported
+}
diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_read_blocking.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair_read_blocking.stderr
new file mode 100644
index 00000000000..b5ed72d9f1b
--- /dev/null
+++ b/src/tools/miri/tests/fail-dep/libc/socketpair_read_blocking.stderr
@@ -0,0 +1,14 @@
+error: unsupported operation: socketpair read: blocking isn't supported yet
+  --> $DIR/socketpair_read_blocking.rs:LL:CC
+   |
+LL |     let _res = unsafe { libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) };
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ socketpair read: blocking isn't supported yet
+   |
+   = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support
+   = note: BACKTRACE:
+   = note: inside `main` at $DIR/socketpair_read_blocking.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_write_blocking.rs b/src/tools/miri/tests/fail-dep/libc/socketpair_write_blocking.rs
new file mode 100644
index 00000000000..e2fbc0ae4b4
--- /dev/null
+++ b/src/tools/miri/tests/fail-dep/libc/socketpair_write_blocking.rs
@@ -0,0 +1,16 @@
+//@ignore-target-windows: no libc socketpair on Windows
+// This is temporarily here because blocking on fd is not supported yet.
+// When blocking is eventually supported, this will be moved to pass-dep/libc/libc-socketpair
+fn main() {
+    let mut fds = [-1, -1];
+    let _ = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
+    // Write size > buffer capacity
+    // Used up all the space in the buffer.
+    let arr1: [u8; 212992] = [1; 212992];
+    let _ = unsafe { libc::write(fds[0], arr1.as_ptr() as *const libc::c_void, 212992) };
+    let data = "abc".as_bytes().as_ptr();
+    // The write below will be blocked as the buffer is full.
+    let _ = unsafe { libc::write(fds[0], data as *const libc::c_void, 3) }; //~ERROR: blocking isn't supported
+    let mut buf: [u8; 3] = [0; 3];
+    let _res = unsafe { libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) };
+}
diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_write_blocking.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair_write_blocking.stderr
new file mode 100644
index 00000000000..7b3a0d27636
--- /dev/null
+++ b/src/tools/miri/tests/fail-dep/libc/socketpair_write_blocking.stderr
@@ -0,0 +1,14 @@
+error: unsupported operation: socketpair write: blocking isn't supported yet
+  --> $DIR/socketpair_write_blocking.rs:LL:CC
+   |
+LL |     let _ = unsafe { libc::write(fds[0], data as *const libc::c_void, 3) };
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ socketpair write: blocking isn't supported yet
+   |
+   = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support
+   = note: BACKTRACE:
+   = note: inside `main` at $DIR/socketpair_write_blocking.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/miri/tests/fail/validity/invalid_enum_cast.rs b/src/tools/miri/tests/fail/validity/invalid_enum_cast.rs
index faf5fb699a6..ed451a435b9 100644
--- a/src/tools/miri/tests/fail/validity/invalid_enum_cast.rs
+++ b/src/tools/miri/tests/fail/validity/invalid_enum_cast.rs
@@ -3,11 +3,17 @@
 
 #[derive(Copy, Clone)]
 #[allow(unused)]
-enum E {A, B, C }
+enum E {
+    A,
+    B,
+    C,
+}
 
-fn cast(ptr: *const E) { unsafe {
-    let _val = *ptr as u32; //~ERROR: enum value has invalid tag
-}}
+fn cast(ptr: *const E) {
+    unsafe {
+        let _val = *ptr as u32; //~ERROR: enum value has invalid tag
+    }
+}
 
 pub fn main() {
     let v = u32::MAX;
diff --git a/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr b/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr
index d8988876045..30afb5e8087 100644
--- a/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr
+++ b/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr
@@ -1,8 +1,8 @@
 error: Undefined Behavior: enum value has invalid tag: 0xff
   --> $DIR/invalid_enum_cast.rs:LL:CC
    |
-LL |     let _val = *ptr as u32;
-   |                ^^^^^^^^^^^ enum value has invalid tag: 0xff
+LL |         let _val = *ptr as u32;
+   |                    ^^^^^^^^^^^ enum value has invalid tag: 0xff
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs b/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs
new file mode 100644
index 00000000000..324c0127ee9
--- /dev/null
+++ b/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs
@@ -0,0 +1,124 @@
+//@ignore-target-windows: No libc socketpair on Windows
+// test_race depends on a deterministic schedule.
+//@compile-flags: -Zmiri-preemption-rate=0
+use std::thread;
+fn main() {
+    test_socketpair();
+    test_socketpair_threaded();
+    test_race();
+}
+
+fn test_socketpair() {
+    let mut fds = [-1, -1];
+    let mut res =
+        unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
+    assert_eq!(res, 0);
+
+    // Read size == data available in buffer.
+    let data = "abcde".as_bytes().as_ptr();
+    res = unsafe { libc::write(fds[0], data as *const libc::c_void, 5).try_into().unwrap() };
+    assert_eq!(res, 5);
+    let mut buf: [u8; 5] = [0; 5];
+    res = unsafe {
+        libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t).try_into().unwrap()
+    };
+    assert_eq!(res, 5);
+    assert_eq!(buf, "abcde".as_bytes());
+
+    // Read size > data available in buffer.
+    let data = "abc".as_bytes().as_ptr();
+    res = unsafe { libc::write(fds[0], data as *const libc::c_void, 3).try_into().unwrap() };
+    assert_eq!(res, 3);
+    let mut buf2: [u8; 5] = [0; 5];
+    res = unsafe {
+        libc::read(fds[1], buf2.as_mut_ptr().cast(), buf2.len() as libc::size_t).try_into().unwrap()
+    };
+    assert_eq!(res, 3);
+    assert_eq!(&buf2[0..3], "abc".as_bytes());
+
+    // Test read and write from another direction.
+    // Read size == data available in buffer.
+    let data = "12345".as_bytes().as_ptr();
+    res = unsafe { libc::write(fds[1], data as *const libc::c_void, 5).try_into().unwrap() };
+    assert_eq!(res, 5);
+    let mut buf3: [u8; 5] = [0; 5];
+    res = unsafe {
+        libc::read(fds[0], buf3.as_mut_ptr().cast(), buf3.len() as libc::size_t).try_into().unwrap()
+    };
+    assert_eq!(res, 5);
+    assert_eq!(buf3, "12345".as_bytes());
+
+    // Read size > data available in buffer.
+    let data = "123".as_bytes().as_ptr();
+    res = unsafe { libc::write(fds[1], data as *const libc::c_void, 3).try_into().unwrap() };
+    assert_eq!(res, 3);
+    let mut buf4: [u8; 5] = [0; 5];
+    res = unsafe {
+        libc::read(fds[0], buf4.as_mut_ptr().cast(), buf4.len() as libc::size_t).try_into().unwrap()
+    };
+    assert_eq!(res, 3);
+    assert_eq!(&buf4[0..3], "123".as_bytes());
+}
+
+fn test_socketpair_threaded() {
+    let mut fds = [-1, -1];
+    let mut res =
+        unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
+    assert_eq!(res, 0);
+
+    let data = "abcde".as_bytes().as_ptr();
+    res = unsafe { libc::write(fds[0], data as *const libc::c_void, 5).try_into().unwrap() };
+    assert_eq!(res, 5);
+    let thread1 = thread::spawn(move || {
+        let mut buf: [u8; 5] = [0; 5];
+        let res: i64 = unsafe {
+            libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t)
+                .try_into()
+                .unwrap()
+        };
+        assert_eq!(res, 5);
+        assert_eq!(buf, "abcde".as_bytes());
+    });
+    thread1.join().unwrap();
+
+    // Read and write from different direction
+    let thread2 = thread::spawn(move || {
+        let data = "12345".as_bytes().as_ptr();
+        let res: i64 =
+            unsafe { libc::write(fds[0], data as *const libc::c_void, 5).try_into().unwrap() };
+        assert_eq!(res, 5);
+    });
+    thread2.join().unwrap();
+    let mut buf: [u8; 5] = [0; 5];
+    res = unsafe {
+        libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t).try_into().unwrap()
+    };
+    assert_eq!(res, 5);
+    assert_eq!(buf, "12345".as_bytes());
+}
+fn test_race() {
+    static mut VAL: u8 = 0;
+    let mut fds = [-1, -1];
+    let mut res =
+        unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
+    assert_eq!(res, 0);
+    let thread1 = thread::spawn(move || {
+        let mut buf: [u8; 1] = [0; 1];
+        // write() from the main thread will occur before the read() here
+        // because preemption is disabled and the main thread yields after write().
+        let res: i32 = unsafe {
+            libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t)
+                .try_into()
+                .unwrap()
+        };
+        assert_eq!(res, 1);
+        assert_eq!(buf, "a".as_bytes());
+        unsafe { assert_eq!(VAL, 1) };
+    });
+    unsafe { VAL = 1 };
+    let data = "a".as_bytes().as_ptr();
+    res = unsafe { libc::write(fds[0], data as *const libc::c_void, 1).try_into().unwrap() };
+    assert_eq!(res, 1);
+    thread::yield_now();
+    thread1.join().unwrap();
+}
diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse42.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse42.rs
new file mode 100644
index 00000000000..3ac53ea8b93
--- /dev/null
+++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse42.rs
@@ -0,0 +1,443 @@
+// Ignore everything except x86 and x86_64
+// Any new targets that are added to CI should be ignored here.
+// (We cannot use `cfg`-based tricks here since the `target-feature` flags below only work on x86.)
+//@ignore-target-aarch64
+//@ignore-target-arm
+//@ignore-target-avr
+//@ignore-target-s390x
+//@ignore-target-thumbv7em
+//@ignore-target-wasm32
+//@compile-flags: -C target-feature=+sse4.2
+
+#[cfg(target_arch = "x86")]
+use std::arch::x86::*;
+#[cfg(target_arch = "x86_64")]
+use std::arch::x86_64::*;
+use std::mem::transmute;
+
+fn main() {
+    assert!(is_x86_feature_detected!("sse4.2"));
+
+    unsafe {
+        test_sse42();
+    }
+}
+
+#[target_feature(enable = "sse4.2")]
+unsafe fn test_sse42() {
+    // Mostly copied from library/stdarch/crates/core_arch/src/x86/sse42.rs
+
+    test_crc();
+    test_cmp();
+    test_str();
+}
+
+#[target_feature(enable = "sse4.2")]
+unsafe fn test_crc() {
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_mm_crc32_u8() {
+        let crc = 0x2aa1e72b;
+        let v = 0x2a;
+        let i = _mm_crc32_u8(crc, v);
+        assert_eq!(i, 0xf24122e4);
+
+        let crc = 0x61343ec4;
+        let v = 0xef;
+        let i = _mm_crc32_u8(crc, v);
+        assert_eq!(i, 0xb95511db);
+
+        let crc = 0xbadeafe;
+        let v = 0xc0;
+        let i = _mm_crc32_u8(crc, v);
+        assert_eq!(i, 0x9c905b7c);
+    }
+    test_mm_crc32_u8();
+
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_mm_crc32_u16() {
+        let crc = 0x8ecec3b5;
+        let v = 0x22b;
+        let i = _mm_crc32_u16(crc, v);
+        assert_eq!(i, 0x13bb2fb);
+
+        let crc = 0x150bc664;
+        let v = 0xa6c0;
+        let i = _mm_crc32_u16(crc, v);
+        assert_eq!(i, 0xab04fe4e);
+
+        let crc = 0xbadeafe;
+        let v = 0xc0fe;
+        let i = _mm_crc32_u16(crc, v);
+        assert_eq!(i, 0x4b5fad4b);
+    }
+    test_mm_crc32_u16();
+
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_mm_crc32_u32() {
+        let crc = 0xae2912c8;
+        let v = 0x845fed;
+        let i = _mm_crc32_u32(crc, v);
+        assert_eq!(i, 0xffae2ed1);
+
+        let crc = 0x1a198fe3;
+        let v = 0x885585c2;
+        let i = _mm_crc32_u32(crc, v);
+        assert_eq!(i, 0x22443a7b);
+
+        let crc = 0xbadeafe;
+        let v = 0xc0febeef;
+        let i = _mm_crc32_u32(crc, v);
+        assert_eq!(i, 0xb309502f);
+    }
+    test_mm_crc32_u32();
+
+    #[cfg(target_arch = "x86_64")]
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_mm_crc32_u64() {
+        let crc = 0x7819dccd3e824;
+        let v = 0x2a22b845fed;
+        let i = _mm_crc32_u64(crc, v);
+        assert_eq!(i, 0xbb6cdc6c);
+
+        let crc = 0x6dd960387fe13819;
+        let v = 0x1a7ea8fb571746b0;
+        let i = _mm_crc32_u64(crc, v);
+        assert_eq!(i, 0x315b4f6);
+
+        let crc = 0xbadeafe;
+        let v = 0xc0febeefdadafefe;
+        let i = _mm_crc32_u64(crc, v);
+        assert_eq!(i, 0x5b44f54f);
+    }
+    #[cfg(not(target_arch = "x86_64"))]
+    unsafe fn test_mm_crc32_u64() {}
+    test_mm_crc32_u64();
+}
+
+#[target_feature(enable = "sse4.2")]
+unsafe fn test_cmp() {
+    let a = _mm_set_epi64x(0x2a, 0);
+    let b = _mm_set1_epi64x(0x00);
+    let i = _mm_cmpgt_epi64(a, b);
+    assert_eq_m128i(i, _mm_set_epi64x(0xffffffffffffffffu64 as i64, 0x00));
+}
+
+#[target_feature(enable = "sse4.2")]
+unsafe fn test_str() {
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn str_to_m128i(s: &[u8]) -> __m128i {
+        assert!(s.len() <= 16);
+        let slice = &mut [0u8; 16];
+        std::ptr::copy_nonoverlapping(s.as_ptr(), slice.as_mut_ptr(), s.len());
+        _mm_loadu_si128(slice.as_ptr() as *const _)
+    }
+
+    // Test the `_mm_cmpistrm` intrinsic.
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_mm_cmpistrm() {
+        let a = str_to_m128i(b"Hello! Good-Bye!");
+        let b = str_to_m128i(b"hello! good-bye!");
+        let i = _mm_cmpistrm::<_SIDD_UNIT_MASK>(a, b);
+        #[rustfmt::skip]
+        let res = _mm_setr_epi8(
+            0x00, !0, !0, !0, !0, !0, !0, 0x00,
+            !0, !0, !0, !0, 0x00, !0, !0, !0,
+        );
+        assert_eq_m128i(i, res);
+    }
+    test_mm_cmpistrm();
+
+    // Test the `_mm_cmpistri` intrinsic.
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_mm_cmpistri() {
+        let a = str_to_m128i(b"Hello");
+        let b = str_to_m128i(b"   Hello        ");
+        let i = _mm_cmpistri::<_SIDD_CMP_EQUAL_ORDERED>(a, b);
+        assert_eq!(3, i);
+    }
+    test_mm_cmpistri();
+
+    // Test the `_mm_cmpistrz` intrinsic.
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_mm_cmpistrz() {
+        let a = str_to_m128i(b"");
+        let b = str_to_m128i(b"Hello");
+        let i = _mm_cmpistrz::<_SIDD_CMP_EQUAL_ORDERED>(a, b);
+        assert_eq!(1, i);
+    }
+    test_mm_cmpistrz();
+
+    // Test the `_mm_cmpistrc` intrinsic.
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_mm_cmpistrc() {
+        let a = str_to_m128i(b"                ");
+        let b = str_to_m128i(b"       !        ");
+        let i = _mm_cmpistrc::<_SIDD_UNIT_MASK>(a, b);
+        assert_eq!(1, i);
+    }
+    test_mm_cmpistrc();
+
+    // Test the `_mm_cmpistrs` intrinsic.
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_mm_cmpistrs() {
+        let a = str_to_m128i(b"Hello");
+        let b = str_to_m128i(b"");
+        let i = _mm_cmpistrs::<_SIDD_CMP_EQUAL_ORDERED>(a, b);
+        assert_eq!(1, i);
+    }
+    test_mm_cmpistrs();
+
+    // Test the `_mm_cmpistro` intrinsic.
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_mm_cmpistro() {
+        #[rustfmt::skip]
+        let a_bytes = _mm_setr_epi8(
+            0x00, 0x47, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c,
+            0x00, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        );
+        #[rustfmt::skip]
+        let b_bytes = _mm_setr_epi8(
+            0x00, 0x48, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c,
+            0x00, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        );
+        let a = a_bytes;
+        let b = b_bytes;
+        let i = _mm_cmpistro::<{ _SIDD_UWORD_OPS | _SIDD_UNIT_MASK }>(a, b);
+        assert_eq!(0, i);
+    }
+    test_mm_cmpistro();
+
+    // Test the `_mm_cmpistra` intrinsic.
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_mm_cmpistra() {
+        let a = str_to_m128i(b"");
+        let b = str_to_m128i(b"Hello!!!!!!!!!!!");
+        let i = _mm_cmpistra::<_SIDD_UNIT_MASK>(a, b);
+        assert_eq!(1, i);
+    }
+    test_mm_cmpistra();
+
+    // Test the `_mm_cmpestrm` intrinsic.
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_mm_cmpestrm() {
+        let a = str_to_m128i(b"Hello!");
+        let b = str_to_m128i(b"Hello.");
+        let i = _mm_cmpestrm::<_SIDD_UNIT_MASK>(a, 5, b, 5);
+        #[rustfmt::skip]
+        let r = _mm_setr_epi8(
+            !0, !0, !0, !0, !0, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        );
+        assert_eq_m128i(i, r);
+    }
+    test_mm_cmpestrm();
+
+    // Test the `_mm_cmpestri` intrinsic.
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_mm_cmpestri() {
+        let a = str_to_m128i(b"bar - garbage");
+        let b = str_to_m128i(b"foobar");
+        let i = _mm_cmpestri::<_SIDD_CMP_EQUAL_ORDERED>(a, 3, b, 6);
+        assert_eq!(3, i);
+    }
+    test_mm_cmpestri();
+
+    // Test the `_mm_cmpestrz` intrinsic.
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_mm_cmpestrz() {
+        let a = str_to_m128i(b"");
+        let b = str_to_m128i(b"Hello");
+        let i = _mm_cmpestrz::<_SIDD_CMP_EQUAL_ORDERED>(a, 16, b, 6);
+        assert_eq!(1, i);
+    }
+    test_mm_cmpestrz();
+
+    // Test the `_mm_cmpestrs` intrinsic.
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_mm_cmpestrc() {
+        let va = str_to_m128i(b"!!!!!!!!");
+        let vb = str_to_m128i(b"        ");
+        let i = _mm_cmpestrc::<_SIDD_UNIT_MASK>(va, 7, vb, 7);
+        assert_eq!(0, i);
+    }
+    test_mm_cmpestrc();
+
+    // Test the `_mm_cmpestrs` intrinsic.
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_mm_cmpestrs() {
+        #[rustfmt::skip]
+        let a_bytes = _mm_setr_epi8(
+            0x00, 0x48, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c,
+            0x00, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        );
+        let a = a_bytes;
+        let b = _mm_set1_epi8(0x00);
+        let i = _mm_cmpestrs::<_SIDD_UWORD_OPS>(a, 8, b, 0);
+        assert_eq!(0, i);
+    }
+    test_mm_cmpestrs();
+
+    // Test the `_mm_cmpestro` intrinsic.
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_mm_cmpestro() {
+        let a = str_to_m128i(b"Hello");
+        let b = str_to_m128i(b"World");
+        let i = _mm_cmpestro::<_SIDD_UBYTE_OPS>(a, 5, b, 5);
+        assert_eq!(0, i);
+    }
+    test_mm_cmpestro();
+
+    // Test the `_mm_cmpestra` intrinsic.
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_mm_cmpestra() {
+        let a = str_to_m128i(b"Cannot match a");
+        let b = str_to_m128i(b"Null after 14");
+        let i = _mm_cmpestra::<{ _SIDD_CMP_EQUAL_EACH | _SIDD_UNIT_MASK }>(a, 14, b, 16);
+        assert_eq!(1, i);
+    }
+    test_mm_cmpestra();
+
+    // Additional tests not inside the standard library.
+
+    // Test the subset functionality of the intrinsic.
+    unsafe fn test_subset() {
+        let a = str_to_m128i(b"ABCDEFG");
+        let b = str_to_m128i(b"ABC UVW XYZ EFG");
+
+        let i = _mm_cmpistrm::<{ _SIDD_CMP_EQUAL_ANY | _SIDD_UNIT_MASK }>(a, b);
+        #[rustfmt::skip]
+        let res = _mm_setr_epi8(
+            !0, !0, !0, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, !0, !0, !0, 0x00,
+        );
+        assert_eq_m128i(i, res);
+    }
+    test_subset();
+
+    // Properly test index generation.
+    unsafe fn test_index() {
+        let a = str_to_m128i(b"Hello");
+        let b = str_to_m128i(b"Hello Hello H");
+
+        let i = _mm_cmpistri::<{ _SIDD_CMP_EQUAL_EACH | _SIDD_LEAST_SIGNIFICANT }>(a, b);
+        assert_eq!(i, 0);
+
+        let i = _mm_cmpistri::<{ _SIDD_CMP_EQUAL_EACH | _SIDD_MOST_SIGNIFICANT }>(a, b);
+        assert_eq!(i, 15);
+
+        let a = str_to_m128i(b"Hello");
+        let b = str_to_m128i(b"                ");
+        let i = _mm_cmpistri::<{ _SIDD_CMP_EQUAL_EACH | _SIDD_MOST_SIGNIFICANT }>(a, b);
+        assert_eq!(i, 16);
+    }
+    test_index();
+
+    // Properly test the substring functionality of the intrinsics.
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_substring() {
+        let a = str_to_m128i(b"Hello");
+        let b = str_to_m128i(b"Hello Hello H");
+
+        let i = _mm_cmpistrm::<{ _SIDD_CMP_EQUAL_ORDERED | _SIDD_UNIT_MASK }>(a, b);
+        #[rustfmt::skip]
+        let res = _mm_setr_epi8(
+            !0, 0x00, 0x00, 0x00, 0x00, 0x00, !0, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        );
+        assert_eq_m128i(i, res);
+    }
+    test_substring();
+
+    // Test the range functionality of the intrinsics.
+    // Will also test signed values and word-sized values.
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_ranges() {
+        let a = _mm_setr_epi16(0, 1, 7, 8, 0, 0, -100, 100);
+        let b = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8);
+
+        let i =
+            _mm_cmpestrm::<{ _SIDD_SWORD_OPS | _SIDD_CMP_RANGES | _SIDD_UNIT_MASK }>(a, 2, b, 8);
+        let res = _mm_setr_epi16(!0, 0, 0, 0, 0, 0, 0, 0);
+        assert_eq_m128i(i, res);
+
+        let i =
+            _mm_cmpestrm::<{ _SIDD_SWORD_OPS | _SIDD_CMP_RANGES | _SIDD_UNIT_MASK }>(a, 3, b, 8);
+        let res = _mm_setr_epi16(!0, 0, 0, 0, 0, 0, 0, 0);
+        assert_eq_m128i(i, res);
+
+        let i =
+            _mm_cmpestrm::<{ _SIDD_SWORD_OPS | _SIDD_CMP_RANGES | _SIDD_UNIT_MASK }>(a, 4, b, 8);
+        let res = _mm_setr_epi16(!0, 0, 0, 0, 0, 0, !0, !0);
+        assert_eq_m128i(i, res);
+
+        let i =
+            _mm_cmpestrm::<{ _SIDD_SWORD_OPS | _SIDD_CMP_RANGES | _SIDD_UNIT_MASK }>(a, 6, b, 8);
+        let res = _mm_setr_epi16(!0, 0, 0, 0, 0, 0, !0, !0);
+        assert_eq_m128i(i, res);
+
+        let i =
+            _mm_cmpestrm::<{ _SIDD_SWORD_OPS | _SIDD_CMP_RANGES | _SIDD_UNIT_MASK }>(a, 8, b, 8);
+        let res = _mm_setr_epi16(!0, !0, !0, !0, !0, !0, !0, !0);
+        assert_eq_m128i(i, res);
+    }
+    test_ranges();
+
+    // Confirm that the polarity bits work as indended.
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_polarity() {
+        let a = str_to_m128i(b"Hello!");
+        let b = str_to_m128i(b"hello?");
+
+        let i = _mm_cmpistrm::<
+            { (_SIDD_MASKED_NEGATIVE_POLARITY ^ _SIDD_NEGATIVE_POLARITY) | _SIDD_UNIT_MASK },
+        >(a, b);
+        #[rustfmt::skip]
+        let res = _mm_setr_epi8(
+            0x00, !0, !0, !0, !0, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        );
+        assert_eq_m128i(i, res);
+
+        let i = _mm_cmpistrm::<{ _SIDD_MASKED_NEGATIVE_POLARITY | _SIDD_UNIT_MASK }>(a, b);
+        #[rustfmt::skip]
+        let res = _mm_setr_epi8(
+            !0, 0x00, 0x00, 0x00, 0x00, !0, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        );
+        assert_eq_m128i(i, res);
+
+        let i = _mm_cmpistrm::<{ _SIDD_NEGATIVE_POLARITY | _SIDD_UNIT_MASK }>(a, b);
+        #[rustfmt::skip]
+        let res = _mm_setr_epi8(
+            !0, 0x00, 0x00, 0x00, 0x00, !0, !0, !0,
+            !0, !0, !0, !0, !0, !0, !0, !0,
+        );
+        assert_eq_m128i(i, res);
+    }
+    test_polarity();
+
+    // Test the code path in which the intrinsic is supposed to
+    // return a bit mask instead of a byte mask.
+    #[target_feature(enable = "sse4.2")]
+    unsafe fn test_bitmask() {
+        let a = str_to_m128i(b"Hello! Good-Bye!");
+        let b = str_to_m128i(b"hello! good-bye!");
+
+        let i = _mm_cmpistrm::<0>(a, b);
+        #[rustfmt::skip]
+        let res = _mm_setr_epi32(0b11101111_01111110, 0, 0, 0);
+        assert_eq_m128i(i, res);
+
+        let i = _mm_cmpistrm::<_SIDD_MASKED_NEGATIVE_POLARITY>(a, b);
+        #[rustfmt::skip]
+        let res = _mm_setr_epi32(0b00010000_10000001, 0, 0, 0);
+        assert_eq_m128i(i, res);
+    }
+    test_bitmask();
+}
+
+#[track_caller]
+#[target_feature(enable = "sse2")]
+pub unsafe fn assert_eq_m128i(a: __m128i, b: __m128i) {
+    assert_eq!(transmute::<_, [u64; 2]>(a), transmute::<_, [u64; 2]>(b))
+}