From abdfe4a79af1367fa0873329ba44dfddeb2d6387 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sat, 18 Nov 2023 08:02:06 +0100
Subject: [PATCH 01/22] miri script: fix RUSTC_GIT error message

---
 src/tools/miri/miri-script/src/commands.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/miri/miri-script/src/commands.rs b/src/tools/miri/miri-script/src/commands.rs
index c24035ae086..e4789c696b3 100644
--- a/src/tools/miri/miri-script/src/commands.rs
+++ b/src/tools/miri/miri-script/src/commands.rs
@@ -286,7 +286,7 @@ impl Command {
                 "This will pull a copy of the rust-lang/rust history into this Miri checkout, growing it by about 1GB."
             );
             print!(
-                "To avoid that, abort now and set the `--rustc-git` flag to an existing rustc checkout. Proceed? [y/N] "
+                "To avoid that, abort now and set the `RUSTC_GIT` environment variable to an existing rustc checkout. Proceed? [y/N] "
             );
             std::io::stdout().flush()?;
             let mut answer = String::new();

From eba8d293022706412c290ebe2d4c4ad85b550689 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sat, 18 Nov 2023 15:55:58 +0100
Subject: [PATCH 02/22] cargo-miri: when verbose, print where the sysroot is
 being built

---
 src/tools/miri/cargo-miri/src/setup.rs | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/src/tools/miri/cargo-miri/src/setup.rs b/src/tools/miri/cargo-miri/src/setup.rs
index d921741d5de..8ae5b8c3e82 100644
--- a/src/tools/miri/cargo-miri/src/setup.rs
+++ b/src/tools/miri/cargo-miri/src/setup.rs
@@ -2,6 +2,7 @@
 
 use std::env;
 use std::ffi::OsStr;
+use std::fmt::Write;
 use std::path::PathBuf;
 use std::process::{self, Command};
 
@@ -140,12 +141,20 @@ pub fn setup(
     // Do the build.
     if print_sysroot {
         // Be silent.
-    } else if only_setup {
-        // We want to be explicit.
-        eprintln!("Preparing a sysroot for Miri (target: {target})...");
     } else {
-        // We want to be quiet, but still let the user know that something is happening.
-        eprint!("Preparing a sysroot for Miri (target: {target})... ");
+        let mut msg = String::new();
+        write!(msg, "Preparing a sysroot for Miri (target: {target})").unwrap();
+        if verbose > 0 {
+            write!(msg, " in {}", sysroot_dir.display()).unwrap();
+        }
+        write!(msg, "...").unwrap();
+        if only_setup {
+            // We want to be explicit.
+            eprintln!("{msg}");
+        } else {
+            // We want to be quiet, but still let the user know that something is happening.
+            eprint!("{msg} ");
+        }
     }
     SysrootBuilder::new(&sysroot_dir, target)
         .build_mode(BuildMode::Check)

From cee4c575f224d12e8b4d5258b2006e9109b42035 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= <eduardosm-dev@e64.io>
Date: Sun, 19 Nov 2023 19:18:52 +0100
Subject: [PATCH 03/22] Improve wording of `intrinsics-x86-*.rs` header

---
 src/tools/miri/tests/pass/intrinsics-x86-aes-vaes.rs   | 2 +-
 src/tools/miri/tests/pass/intrinsics-x86-avx512.rs     | 2 +-
 src/tools/miri/tests/pass/intrinsics-x86-sse3-ssse3.rs | 2 +-
 src/tools/miri/tests/pass/intrinsics-x86-sse41.rs      | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/tools/miri/tests/pass/intrinsics-x86-aes-vaes.rs b/src/tools/miri/tests/pass/intrinsics-x86-aes-vaes.rs
index 090b1db0af0..55d1bacdf45 100644
--- a/src/tools/miri/tests/pass/intrinsics-x86-aes-vaes.rs
+++ b/src/tools/miri/tests/pass/intrinsics-x86-aes-vaes.rs
@@ -1,5 +1,5 @@
 // Ignore everything except x86 and x86_64
-// Any additional target are added to CI should be ignored here
+// 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
diff --git a/src/tools/miri/tests/pass/intrinsics-x86-avx512.rs b/src/tools/miri/tests/pass/intrinsics-x86-avx512.rs
index c38158dc797..394412a2354 100644
--- a/src/tools/miri/tests/pass/intrinsics-x86-avx512.rs
+++ b/src/tools/miri/tests/pass/intrinsics-x86-avx512.rs
@@ -1,5 +1,5 @@
 // Ignore everything except x86 and x86_64
-// Any additional target are added to CI should be ignored here
+// 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
diff --git a/src/tools/miri/tests/pass/intrinsics-x86-sse3-ssse3.rs b/src/tools/miri/tests/pass/intrinsics-x86-sse3-ssse3.rs
index 0805d9bc300..7566be4431b 100644
--- a/src/tools/miri/tests/pass/intrinsics-x86-sse3-ssse3.rs
+++ b/src/tools/miri/tests/pass/intrinsics-x86-sse3-ssse3.rs
@@ -1,5 +1,5 @@
 // Ignore everything except x86 and x86_64
-// Any additional target are added to CI should be ignored here
+// 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
diff --git a/src/tools/miri/tests/pass/intrinsics-x86-sse41.rs b/src/tools/miri/tests/pass/intrinsics-x86-sse41.rs
index 8c565a2d6e0..13856d29d3f 100644
--- a/src/tools/miri/tests/pass/intrinsics-x86-sse41.rs
+++ b/src/tools/miri/tests/pass/intrinsics-x86-sse41.rs
@@ -1,5 +1,5 @@
 // Ignore everything except x86 and x86_64
-// Any additional target are added to CI should be ignored here
+// 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

From 991e53a59766f05d5aaacf74c9b57a36f7d36265 Mon Sep 17 00:00:00 2001
From: David Carlier <devnexen@gmail.com>
Date: Sat, 18 Nov 2023 19:50:20 +0000
Subject: [PATCH 04/22] libc-misc test freebsd fixes attempt

---
 src/tools/miri/ci.sh                          |  2 +-
 src/tools/miri/src/shims/time.rs              |  4 +-
 .../miri/src/shims/unix/foreign_items.rs      | 10 ++++
 src/tools/miri/src/shims/unix/fs.rs           |  9 +---
 .../src/shims/unix/macos/foreign_items.rs     |  7 ---
 .../pass-dep/shims/libc-fs-with-isolation.rs  |  1 +
 .../miri/tests/pass-dep/shims/libc-fs.rs      | 43 +++++++++++++++
 .../miri/tests/pass-dep/shims/libc-misc.rs    | 52 +------------------
 8 files changed, 59 insertions(+), 69 deletions(-)

diff --git a/src/tools/miri/ci.sh b/src/tools/miri/ci.sh
index 7808c9acf93..378d7744cf2 100755
--- a/src/tools/miri/ci.sh
+++ b/src/tools/miri/ci.sh
@@ -108,7 +108,7 @@ case $HOST_TARGET in
     MIRI_TEST_TARGET=aarch64-unknown-linux-gnu run_tests
     MIRI_TEST_TARGET=aarch64-apple-darwin run_tests
     MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests
-    MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthread-threadname libc-getentropy libc-getrandom libc-misc atomic env align
+    MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthread-threadname libc-getentropy libc-getrandom libc-misc libc-fs atomic env align
     MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal hello integer vec panic/panic
     MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings wasm
     MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings wasm
diff --git a/src/tools/miri/src/shims/time.rs b/src/tools/miri/src/shims/time.rs
index 4918698c6b2..611b8bc8ccc 100644
--- a/src/tools/miri/src/shims/time.rs
+++ b/src/tools/miri/src/shims/time.rs
@@ -31,8 +31,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         let mut relative_clocks;
 
         match this.tcx.sess.target.os.as_ref() {
-            "linux" => {
-                // Linux has two main kinds of clocks. REALTIME clocks return the actual time since the
+            "linux" | "freebsd" => {
+                // Linux and FreeBSD have two main kinds of clocks. REALTIME clocks return the actual time since the
                 // Unix epoch, including effects which may cause time to move backwards such as NTP.
                 // Linux further distinguishes regular and "coarse" clocks, but the "coarse" version
                 // is just specified to be "faster and less precise", so we implement both the same way.
diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs
index d155623eb7b..7bc26788b26 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -163,6 +163,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             "ftruncate64" => {
                 let [fd, length] =
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let fd = this.read_scalar(fd)?.to_i32()?;
+                let length = this.read_scalar(length)?.to_i64()?;
+                let result = this.ftruncate64(fd, length)?;
+                this.write_scalar(result, dest)?;
+            }
+            "ftruncate" => {
+                let [fd, length] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let fd = this.read_scalar(fd)?.to_i32()?;
+                let length = this.read_target_isize(length)?;
                 let result = this.ftruncate64(fd, length)?;
                 this.write_scalar(result, dest)?;
             }
diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs
index 062623a7f6a..721fa161232 100644
--- a/src/tools/miri/src/shims/unix/fs.rs
+++ b/src/tools/miri/src/shims/unix/fs.rs
@@ -1504,16 +1504,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         }
     }
 
-    fn ftruncate64(
-        &mut self,
-        fd_op: &OpTy<'tcx, Provenance>,
-        length_op: &OpTy<'tcx, Provenance>,
-    ) -> InterpResult<'tcx, Scalar<Provenance>> {
+    fn ftruncate64(&mut self, fd: i32, length: i64) -> InterpResult<'tcx, Scalar<Provenance>> {
         let this = self.eval_context_mut();
 
-        let fd = this.read_scalar(fd_op)?.to_i32()?;
-        let length = this.read_scalar(length_op)?.to_i64()?;
-
         // Reject if isolation is enabled.
         if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
             this.reject_in_isolation("`ftruncate64`", reject_with)?;
diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs
index e8f35e7ba57..07e19cadd6e 100644
--- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs
@@ -72,13 +72,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let result = this.lseek64(fd, offset, whence)?;
                 this.write_scalar(result, dest)?;
             }
-            "ftruncate" => {
-                let [fd, length] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
-                // macOS is 64bit-only, so this is ftruncate64
-                let result = this.ftruncate64(fd, length)?;
-                this.write_scalar(result, dest)?;
-            }
             "realpath$DARWIN_EXTSN" => {
                 let [path, resolved_path] =
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
diff --git a/src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.rs b/src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.rs
index 5185db0b0e2..adfece58661 100644
--- a/src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.rs
+++ b/src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.rs
@@ -1,4 +1,5 @@
 //@ignore-target-windows: no libc on Windows
+//@ignore-target-freebsd: FIXME needs foreign function `stat@FBSD_1.0`
 //@compile-flags: -Zmiri-isolation-error=warn-nobacktrace
 //@normalize-stderr-test: "(stat(x)?)" -> "$$STAT"
 
diff --git a/src/tools/miri/tests/pass-dep/shims/libc-fs.rs b/src/tools/miri/tests/pass-dep/shims/libc-fs.rs
index 767a4fdbede..697970a0885 100644
--- a/src/tools/miri/tests/pass-dep/shims/libc-fs.rs
+++ b/src/tools/miri/tests/pass-dep/shims/libc-fs.rs
@@ -23,6 +23,7 @@ fn main() {
     test_file_open_unix_extra_third_arg();
     #[cfg(target_os = "linux")]
     test_o_tmpfile_flag();
+    test_posix_mkstemp();
 }
 
 /// Prepare: compute filename and make sure the file does not exist.
@@ -151,3 +152,45 @@ fn test_o_tmpfile_flag() {
             .raw_os_error(),
     );
 }
+
+fn test_posix_mkstemp() {
+    use std::ffi::OsStr;
+    use std::os::unix::io::FromRawFd;
+    use std::path::Path;
+
+    let valid_template = "fooXXXXXX";
+    // C needs to own this as `mkstemp(3)` says:
+    // "Since it will be modified, `template` must not be a string constant, but
+    // should be declared as a character array."
+    // There seems to be no `as_mut_ptr` on `CString` so we need to use `into_raw`.
+    let ptr = CString::new(valid_template).unwrap().into_raw();
+    let fd = unsafe { libc::mkstemp(ptr) };
+    // Take ownership back in Rust to not leak memory.
+    let slice = unsafe { CString::from_raw(ptr) };
+    assert!(fd > 0);
+    let osstr = OsStr::from_bytes(slice.to_bytes());
+    let path: &Path = osstr.as_ref();
+    let name = path.file_name().unwrap().to_string_lossy();
+    assert!(name.ne("fooXXXXXX"));
+    assert!(name.starts_with("foo"));
+    assert_eq!(name.len(), 9);
+    assert_eq!(
+        name.chars().skip(3).filter(char::is_ascii_alphanumeric).collect::<Vec<char>>().len(),
+        6
+    );
+    let file = unsafe { File::from_raw_fd(fd) };
+    assert!(file.set_len(0).is_ok());
+
+    let invalid_templates = vec!["foo", "barXX", "XXXXXXbaz", "whatXXXXXXever", "X"];
+    for t in invalid_templates {
+        let ptr = CString::new(t).unwrap().into_raw();
+        let fd = unsafe { libc::mkstemp(ptr) };
+        let _ = unsafe { CString::from_raw(ptr) };
+        // "On error, -1 is returned, and errno is set to
+        // indicate the error"
+        assert_eq!(fd, -1);
+        let e = std::io::Error::last_os_error();
+        assert_eq!(e.raw_os_error(), Some(libc::EINVAL));
+        assert_eq!(e.kind(), std::io::ErrorKind::InvalidInput);
+    }
+}
diff --git a/src/tools/miri/tests/pass-dep/shims/libc-misc.rs b/src/tools/miri/tests/pass-dep/shims/libc-misc.rs
index de1acb13cbe..abb384b0a85 100644
--- a/src/tools/miri/tests/pass-dep/shims/libc-misc.rs
+++ b/src/tools/miri/tests/pass-dep/shims/libc-misc.rs
@@ -172,14 +172,13 @@ fn test_thread_local_errno() {
 }
 
 /// Tests whether clock support exists at all
-#[cfg(not(target_os = "freebsd"))]
 fn test_clocks() {
     let mut tp = std::mem::MaybeUninit::<libc::timespec>::uninit();
     let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME, tp.as_mut_ptr()) };
     assert_eq!(is_error, 0);
     let is_error = unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC, tp.as_mut_ptr()) };
     assert_eq!(is_error, 0);
-    #[cfg(target_os = "linux")]
+    #[cfg(any(target_os = "linux", target_os = "freebsd"))]
     {
         let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME_COARSE, tp.as_mut_ptr()) };
         assert_eq!(is_error, 0);
@@ -238,51 +237,6 @@ fn test_isatty() {
     }
 }
 
-#[cfg(not(target_os = "freebsd"))]
-fn test_posix_mkstemp() {
-    use std::ffi::CString;
-    use std::ffi::OsStr;
-    use std::os::unix::ffi::OsStrExt;
-    use std::os::unix::io::FromRawFd;
-    use std::path::Path;
-
-    let valid_template = "fooXXXXXX";
-    // C needs to own this as `mkstemp(3)` says:
-    // "Since it will be modified, `template` must not be a string constant, but
-    // should be declared as a character array."
-    // There seems to be no `as_mut_ptr` on `CString` so we need to use `into_raw`.
-    let ptr = CString::new(valid_template).unwrap().into_raw();
-    let fd = unsafe { libc::mkstemp(ptr) };
-    // Take ownership back in Rust to not leak memory.
-    let slice = unsafe { CString::from_raw(ptr) };
-    assert!(fd > 0);
-    let osstr = OsStr::from_bytes(slice.to_bytes());
-    let path: &Path = osstr.as_ref();
-    let name = path.file_name().unwrap().to_string_lossy();
-    assert!(name.ne("fooXXXXXX"));
-    assert!(name.starts_with("foo"));
-    assert_eq!(name.len(), 9);
-    assert_eq!(
-        name.chars().skip(3).filter(char::is_ascii_alphanumeric).collect::<Vec<char>>().len(),
-        6
-    );
-    let file = unsafe { File::from_raw_fd(fd) };
-    assert!(file.set_len(0).is_ok());
-
-    let invalid_templates = vec!["foo", "barXX", "XXXXXXbaz", "whatXXXXXXever", "X"];
-    for t in invalid_templates {
-        let ptr = CString::new(t).unwrap().into_raw();
-        let fd = unsafe { libc::mkstemp(ptr) };
-        let _ = unsafe { CString::from_raw(ptr) };
-        // "On error, -1 is returned, and errno is set to
-        // indicate the error"
-        assert_eq!(fd, -1);
-        let e = std::io::Error::last_os_error();
-        assert_eq!(e.raw_os_error(), Some(libc::EINVAL));
-        assert_eq!(e.kind(), std::io::ErrorKind::InvalidInput);
-    }
-}
-
 fn test_memcpy() {
     unsafe {
         let src = [1i8, 2, 3];
@@ -406,9 +360,6 @@ fn test_reallocarray() {
 fn main() {
     test_posix_gettimeofday();
 
-    #[cfg(not(target_os = "freebsd"))] // FIXME we should support this on FreeBSD as well
-    test_posix_mkstemp();
-
     test_posix_realpath_alloc();
     test_posix_realpath_noalloc();
     test_posix_realpath_errors();
@@ -417,7 +368,6 @@ fn main() {
 
     test_isatty();
 
-    #[cfg(not(target_os = "freebsd"))] // FIXME we should support this on FreeBSD as well
     test_clocks();
 
     test_dlsym();

From 81303e7ea5209dbfbdf359b9311681d4151c4c5a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= <eduardosm-dev@e64.io>
Date: Sat, 18 Nov 2023 19:39:51 +0100
Subject: [PATCH 05/22] Implement all 16 AVX compare operators

`_mm_cmp_{ss,ps,sd,pd}` functions are AVX functions that use `llvm.x86.sse{,2}` prefixed intrinsics, so they were "accidentally" partially implemented when SSE and SSE2 intrinsics were implemented.

The 16 AVX compare operators are now implemented and tested.
---
 src/tools/miri/src/shims/x86/mod.rs           | 120 +++++++------
 src/tools/miri/src/shims/x86/sse.rs           |  22 ++-
 src/tools/miri/src/shims/x86/sse2.rs          |  20 ++-
 .../miri/tests/pass/intrinsics-x86-avx.rs     | 162 ++++++++++++++++++
 4 files changed, 257 insertions(+), 67 deletions(-)
 create mode 100644 src/tools/miri/tests/pass/intrinsics-x86-avx.rs

diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs
index d88a3127ecc..2a2171134d4 100644
--- a/src/tools/miri/src/shims/x86/mod.rs
+++ b/src/tools/miri/src/shims/x86/mod.rs
@@ -119,53 +119,32 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
     }
 }
 
-/// Floating point comparison operation
-///
-/// <https://www.felixcloutier.com/x86/cmpss>
-/// <https://www.felixcloutier.com/x86/cmpps>
-/// <https://www.felixcloutier.com/x86/cmpsd>
-/// <https://www.felixcloutier.com/x86/cmppd>
-#[derive(Copy, Clone)]
-enum FloatCmpOp {
-    Eq,
-    Lt,
-    Le,
-    Unord,
-    Neq,
-    /// Not less-than
-    Nlt,
-    /// Not less-or-equal
-    Nle,
-    /// Ordered, i.e. neither of them is NaN
-    Ord,
-}
-
-impl FloatCmpOp {
-    /// Convert from the `imm` argument used to specify the comparison
-    /// operation in intrinsics such as `llvm.x86.sse.cmp.ss`.
-    fn from_intrinsic_imm(imm: i8, intrinsic: &str) -> InterpResult<'_, Self> {
-        match imm {
-            0 => Ok(Self::Eq),
-            1 => Ok(Self::Lt),
-            2 => Ok(Self::Le),
-            3 => Ok(Self::Unord),
-            4 => Ok(Self::Neq),
-            5 => Ok(Self::Nlt),
-            6 => Ok(Self::Nle),
-            7 => Ok(Self::Ord),
-            imm => {
-                throw_unsup_format!("invalid `imm` parameter of {intrinsic}: {imm}");
-            }
-        }
-    }
-}
-
 #[derive(Copy, Clone)]
 enum FloatBinOp {
     /// Arithmetic operation
     Arith(mir::BinOp),
     /// Comparison
-    Cmp(FloatCmpOp),
+    ///
+    /// The semantics of this operator is a case distinction: we compare the two operands,
+    /// and then we return one of the four booleans `gt`, `lt`, `eq`, `unord` depending on
+    /// which class they fall into.
+    ///
+    /// AVX supports all 16 combinations, SSE only a subset
+    ///
+    /// <https://www.felixcloutier.com/x86/cmpss>
+    /// <https://www.felixcloutier.com/x86/cmpps>
+    /// <https://www.felixcloutier.com/x86/cmpsd>
+    /// <https://www.felixcloutier.com/x86/cmppd>
+    Cmp {
+        /// Result when lhs < rhs
+        gt: bool,
+        /// Result when lhs > rhs
+        lt: bool,
+        /// Result when lhs == rhs
+        eq: bool,
+        /// Result when lhs is NaN or rhs is NaN
+        unord: bool,
+    },
     /// Minimum value (with SSE semantics)
     ///
     /// <https://www.felixcloutier.com/x86/minss>
@@ -182,6 +161,44 @@ enum FloatBinOp {
     Max,
 }
 
+impl FloatBinOp {
+    /// Convert from the `imm` argument used to specify the comparison
+    /// operation in intrinsics such as `llvm.x86.sse.cmp.ss`.
+    fn cmp_from_imm(imm: i8, intrinsic: &str) -> InterpResult<'_, Self> {
+        // Only bits 0..=4 are used, remaining should be zero.
+        if imm & !0b1_1111 != 0 {
+            throw_unsup_format!("invalid `imm` parameter of {intrinsic}: 0x{imm:x}");
+        }
+        // Bit 4 specifies whether the operation is quiet or signaling, which
+        // we do not care in Miri.
+        // Bits 0..=2 specifies the operation.
+        // `gt` indicates the result to be returned when the LHS is strictly
+        // greater than the RHS, and so on.
+        let (gt, lt, eq, unord) = match imm & 0b111 {
+            // Equal
+            0x0 => (false, false, true, false),
+            // Less-than
+            0x1 => (false, true, false, false),
+            // Less-or-equal
+            0x2 => (false, true, true, false),
+            // Unordered (either is NaN)
+            0x3 => (false, false, false, true),
+            // Not equal
+            0x4 => (true, true, false, true),
+            // Not less-than
+            0x5 => (true, false, true, true),
+            // Not less-or-equal
+            0x6 => (true, false, false, true),
+            // Ordered (neither is NaN)
+            0x7 => (true, true, true, false),
+            _ => unreachable!(),
+        };
+        // When bit 3 is 1 (only possible in AVX), unord is toggled.
+        let unord = unord ^ (imm & 0b1000 != 0);
+        Ok(Self::Cmp { gt, lt, eq, unord })
+    }
+}
+
 /// Performs `which` scalar operation on `left` and `right` and returns
 /// the result.
 fn bin_op_float<'tcx, F: rustc_apfloat::Float>(
@@ -195,20 +212,15 @@ fn bin_op_float<'tcx, F: rustc_apfloat::Float>(
             let res = this.wrapping_binary_op(which, left, right)?;
             Ok(res.to_scalar())
         }
-        FloatBinOp::Cmp(which) => {
+        FloatBinOp::Cmp { gt, lt, eq, unord } => {
             let left = left.to_scalar().to_float::<F>()?;
             let right = right.to_scalar().to_float::<F>()?;
-            // FIXME: Make sure that these operations match the semantics
-            // of cmpps/cmpss/cmppd/cmpsd
-            let res = match which {
-                FloatCmpOp::Eq => left == right,
-                FloatCmpOp::Lt => left < right,
-                FloatCmpOp::Le => left <= right,
-                FloatCmpOp::Unord => left.is_nan() || right.is_nan(),
-                FloatCmpOp::Neq => left != right,
-                FloatCmpOp::Nlt => !(left < right),
-                FloatCmpOp::Nle => !(left <= right),
-                FloatCmpOp::Ord => !left.is_nan() && !right.is_nan(),
+
+            let res = match left.partial_cmp(&right) {
+                None => unord,
+                Some(std::cmp::Ordering::Less) => lt,
+                Some(std::cmp::Ordering::Equal) => eq,
+                Some(std::cmp::Ordering::Greater) => gt,
             };
             Ok(bool_to_simd_element(res, Size::from_bits(F::BITS)))
         }
diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs
index 831228b7a26..e15023c3c21 100644
--- a/src/tools/miri/src/shims/x86/sse.rs
+++ b/src/tools/miri/src/shims/x86/sse.rs
@@ -5,7 +5,7 @@ use rustc_target::spec::abi::Abi;
 
 use rand::Rng as _;
 
-use super::{bin_op_simd_float_all, bin_op_simd_float_first, FloatBinOp, FloatCmpOp};
+use super::{bin_op_simd_float_all, bin_op_simd_float_first, FloatBinOp};
 use crate::*;
 use shims::foreign_items::EmulateForeignItemResult;
 
@@ -95,33 +95,41 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
 
                 unary_op_ps(this, which, op, dest)?;
             }
-            // Used to implement the _mm_cmp_ss function.
+            // Used to implement the _mm_cmp*_ss functions.
             // Performs a comparison operation on the first component of `left`
             // and `right`, returning 0 if false or `u32::MAX` if true. The remaining
             // components are copied from `left`.
+            // _mm_cmp_ss is actually an AVX function where the operation is specified
+            // by a const parameter.
+            // _mm_cmp{eq,lt,le,gt,ge,neq,nlt,nle,ngt,nge,ord,unord}_ss are SSE functions
+            // with hard-coded operations.
             "cmp.ss" => {
                 let [left, right, imm] =
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
 
-                let which = FloatBinOp::Cmp(FloatCmpOp::from_intrinsic_imm(
+                let which = FloatBinOp::cmp_from_imm(
                     this.read_scalar(imm)?.to_i8()?,
                     "llvm.x86.sse.cmp.ss",
-                )?);
+                )?;
 
                 bin_op_simd_float_first::<Single>(this, which, left, right, dest)?;
             }
-            // Used to implement the _mm_cmp_ps function.
+            // Used to implement the _mm_cmp*_ps functions.
             // Performs a comparison operation on each component of `left`
             // and `right`. For each component, returns 0 if false or u32::MAX
             // if true.
+            // _mm_cmp_ps is actually an AVX function where the operation is specified
+            // by a const parameter.
+            // _mm_cmp{eq,lt,le,gt,ge,neq,nlt,nle,ngt,nge,ord,unord}_ps are SSE functions
+            // with hard-coded operations.
             "cmp.ps" => {
                 let [left, right, imm] =
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
 
-                let which = FloatBinOp::Cmp(FloatCmpOp::from_intrinsic_imm(
+                let which = FloatBinOp::cmp_from_imm(
                     this.read_scalar(imm)?.to_i8()?,
                     "llvm.x86.sse.cmp.ps",
-                )?);
+                )?;
 
                 bin_op_simd_float_all::<Single>(this, which, left, right, dest)?;
             }
diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs
index 3f2b9f5f0ad..55520771cf6 100644
--- a/src/tools/miri/src/shims/x86/sse2.rs
+++ b/src/tools/miri/src/shims/x86/sse2.rs
@@ -4,7 +4,7 @@ use rustc_middle::ty::Ty;
 use rustc_span::Symbol;
 use rustc_target::spec::abi::Abi;
 
-use super::{bin_op_simd_float_all, bin_op_simd_float_first, FloatBinOp, FloatCmpOp};
+use super::{bin_op_simd_float_all, bin_op_simd_float_first, FloatBinOp};
 use crate::*;
 use shims::foreign_items::EmulateForeignItemResult;
 
@@ -461,18 +461,22 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                     this.write_scalar(res, &dest)?;
                 }
             }
-            // Used to implement the _mm_cmp*_sd function.
+            // Used to implement the _mm_cmp*_sd functions.
             // Performs a comparison operation on the first component of `left`
             // and `right`, returning 0 if false or `u64::MAX` if true. The remaining
             // components are copied from `left`.
+            // _mm_cmp_sd is actually an AVX function where the operation is specified
+            // by a const parameter.
+            // _mm_cmp{eq,lt,le,gt,ge,neq,nlt,nle,ngt,nge,ord,unord}_sd are SSE2 functions
+            // with hard-coded operations.
             "cmp.sd" => {
                 let [left, right, imm] =
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
 
-                let which = FloatBinOp::Cmp(FloatCmpOp::from_intrinsic_imm(
+                let which = FloatBinOp::cmp_from_imm(
                     this.read_scalar(imm)?.to_i8()?,
                     "llvm.x86.sse2.cmp.sd",
-                )?);
+                )?;
 
                 bin_op_simd_float_first::<Double>(this, which, left, right, dest)?;
             }
@@ -480,14 +484,18 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
             // Performs a comparison operation on each component of `left`
             // and `right`. For each component, returns 0 if false or `u64::MAX`
             // if true.
+            // _mm_cmp_pd is actually an AVX function where the operation is specified
+            // by a const parameter.
+            // _mm_cmp{eq,lt,le,gt,ge,neq,nlt,nle,ngt,nge,ord,unord}_pd are SSE2 functions
+            // with hard-coded operations.
             "cmp.pd" => {
                 let [left, right, imm] =
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
 
-                let which = FloatBinOp::Cmp(FloatCmpOp::from_intrinsic_imm(
+                let which = FloatBinOp::cmp_from_imm(
                     this.read_scalar(imm)?.to_i8()?,
                     "llvm.x86.sse2.cmp.pd",
-                )?);
+                )?;
 
                 bin_op_simd_float_all::<Double>(this, which, left, right, dest)?;
             }
diff --git a/src/tools/miri/tests/pass/intrinsics-x86-avx.rs b/src/tools/miri/tests/pass/intrinsics-x86-avx.rs
new file mode 100644
index 00000000000..933e3d4153a
--- /dev/null
+++ b/src/tools/miri/tests/pass/intrinsics-x86-avx.rs
@@ -0,0 +1,162 @@
+// 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=+avx
+
+#[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!("avx"));
+
+    unsafe {
+        test_avx();
+    }
+}
+
+#[target_feature(enable = "avx")]
+unsafe fn test_avx() {
+    fn expected_cmp<F: PartialOrd>(imm: i32, lhs: F, rhs: F, if_t: F, if_f: F) -> F {
+        let res = match imm {
+            _CMP_EQ_OQ => lhs == rhs,
+            _CMP_LT_OS => lhs < rhs,
+            _CMP_LE_OS => lhs <= rhs,
+            _CMP_UNORD_Q => lhs.partial_cmp(&rhs).is_none(),
+            _CMP_NEQ_UQ => lhs != rhs,
+            _CMP_NLT_UQ => !(lhs < rhs),
+            _CMP_NLE_UQ => !(lhs <= rhs),
+            _CMP_ORD_Q => lhs.partial_cmp(&rhs).is_some(),
+            _CMP_EQ_UQ => lhs == rhs || lhs.partial_cmp(&rhs).is_none(),
+            _CMP_NGE_US => !(lhs >= rhs),
+            _CMP_NGT_US => !(lhs > rhs),
+            _CMP_FALSE_OQ => false,
+            _CMP_NEQ_OQ => lhs != rhs && lhs.partial_cmp(&rhs).is_some(),
+            _CMP_GE_OS => lhs >= rhs,
+            _CMP_GT_OS => lhs > rhs,
+            _CMP_TRUE_US => true,
+            _ => unreachable!(),
+        };
+        if res { if_t } else { if_f }
+    }
+    fn expected_cmp_f32(imm: i32, lhs: f32, rhs: f32) -> f32 {
+        expected_cmp(imm, lhs, rhs, f32::from_bits(u32::MAX), 0.0)
+    }
+    fn expected_cmp_f64(imm: i32, lhs: f64, rhs: f64) -> f64 {
+        expected_cmp(imm, lhs, rhs, f64::from_bits(u64::MAX), 0.0)
+    }
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm_cmp_ss<const IMM: i32>() {
+        let values = [
+            (1.0, 1.0),
+            (0.0, 1.0),
+            (1.0, 0.0),
+            (f32::NAN, 0.0),
+            (0.0, f32::NAN),
+            (f32::NAN, f32::NAN),
+        ];
+
+        for (lhs, rhs) in values {
+            let a = _mm_setr_ps(lhs, 2.0, 3.0, 4.0);
+            let b = _mm_setr_ps(rhs, 5.0, 6.0, 7.0);
+            let r: [u32; 4] = transmute(_mm_cmp_ss::<IMM>(a, b));
+            let e: [u32; 4] =
+                transmute(_mm_setr_ps(expected_cmp_f32(IMM, lhs, rhs), 2.0, 3.0, 4.0));
+            assert_eq!(r, e);
+        }
+    }
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm_cmp_ps<const IMM: i32>() {
+        let values = [
+            (1.0, 1.0),
+            (0.0, 1.0),
+            (1.0, 0.0),
+            (f32::NAN, 0.0),
+            (0.0, f32::NAN),
+            (f32::NAN, f32::NAN),
+        ];
+
+        for (lhs, rhs) in values {
+            let a = _mm_set1_ps(lhs);
+            let b = _mm_set1_ps(rhs);
+            let r: [u32; 4] = transmute(_mm_cmp_ps::<IMM>(a, b));
+            let e: [u32; 4] = transmute(_mm_set1_ps(expected_cmp_f32(IMM, lhs, rhs)));
+            assert_eq!(r, e);
+        }
+    }
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm_cmp_sd<const IMM: i32>() {
+        let values = [
+            (1.0, 1.0),
+            (0.0, 1.0),
+            (1.0, 0.0),
+            (f64::NAN, 0.0),
+            (0.0, f64::NAN),
+            (f64::NAN, f64::NAN),
+        ];
+
+        for (lhs, rhs) in values {
+            let a = _mm_setr_pd(lhs, 2.0);
+            let b = _mm_setr_pd(rhs, 3.0);
+            let r: [u64; 2] = transmute(_mm_cmp_sd::<IMM>(a, b));
+            let e: [u64; 2] = transmute(_mm_setr_pd(expected_cmp_f64(IMM, lhs, rhs), 2.0));
+            assert_eq!(r, e);
+        }
+    }
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_mm_cmp_pd<const IMM: i32>() {
+        let values = [
+            (1.0, 1.0),
+            (0.0, 1.0),
+            (1.0, 0.0),
+            (f64::NAN, 0.0),
+            (0.0, f64::NAN),
+            (f64::NAN, f64::NAN),
+        ];
+
+        for (lhs, rhs) in values {
+            let a = _mm_set1_pd(lhs);
+            let b = _mm_set1_pd(rhs);
+            let r: [u64; 2] = transmute(_mm_cmp_pd::<IMM>(a, b));
+            let e: [u64; 2] = transmute(_mm_set1_pd(expected_cmp_f64(IMM, lhs, rhs)));
+            assert_eq!(r, e);
+        }
+    }
+
+    #[target_feature(enable = "avx")]
+    unsafe fn test_cmp<const IMM: i32>() {
+        test_mm_cmp_ss::<IMM>();
+        test_mm_cmp_ps::<IMM>();
+        test_mm_cmp_sd::<IMM>();
+        test_mm_cmp_pd::<IMM>();
+    }
+
+    test_cmp::<_CMP_EQ_OQ>();
+    test_cmp::<_CMP_LT_OS>();
+    test_cmp::<_CMP_LE_OS>();
+    test_cmp::<_CMP_UNORD_Q>();
+    test_cmp::<_CMP_NEQ_UQ>();
+    test_cmp::<_CMP_NLT_UQ>();
+    test_cmp::<_CMP_NLE_UQ>();
+    test_cmp::<_CMP_ORD_Q>();
+    test_cmp::<_CMP_EQ_UQ>();
+    test_cmp::<_CMP_NGE_US>();
+    test_cmp::<_CMP_NGT_US>();
+    test_cmp::<_CMP_FALSE_OQ>();
+    test_cmp::<_CMP_NEQ_OQ>();
+    test_cmp::<_CMP_GE_OS>();
+    test_cmp::<_CMP_GT_OS>();
+    test_cmp::<_CMP_TRUE_US>();
+}

From 9007cc484bdff639d3c8ab1304e6dd4257589f82 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 21 Nov 2023 18:23:22 +0100
Subject: [PATCH 06/22] Preparing for merge from rustc

---
 src/tools/miri/rust-version | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 2a19781775b..00a41008d3b 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-820f06b21f8373060ff7b515715b8440a6a6c197
+0ff861096449f47956521b40e5e4e88caa7fe27c

From f1b944d1a2364f4baf4d1d9ce421fc4126adc6f5 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 21 Nov 2023 18:24:57 +0100
Subject: [PATCH 07/22] fmt

---
 src/tools/miri/src/lib.rs           | 2 +-
 src/tools/miri/src/provenance_gc.rs | 9 ++-------
 src/tools/miri/tests/utils/mod.rs   | 4 +---
 3 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index 119ec555b2e..70e9c443e90 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -125,7 +125,7 @@ pub use crate::machine::{
 };
 pub use crate::mono_hash_map::MonoHashMap;
 pub use crate::operator::EvalContextExt as _;
-pub use crate::provenance_gc::{EvalContextExt as _, VisitProvenance, VisitWith, LiveAllocs};
+pub use crate::provenance_gc::{EvalContextExt as _, LiveAllocs, VisitProvenance, VisitWith};
 pub use crate::range_map::RangeMap;
 
 /// Insert rustc arguments at the beginning of the argument list that Miri wants to be
diff --git a/src/tools/miri/src/provenance_gc.rs b/src/tools/miri/src/provenance_gc.rs
index eac4aad27a0..4456e641b00 100644
--- a/src/tools/miri/src/provenance_gc.rs
+++ b/src/tools/miri/src/provenance_gc.rs
@@ -157,15 +157,13 @@ pub struct LiveAllocs<'a, 'mir, 'tcx> {
 
 impl LiveAllocs<'_, '_, '_> {
     pub fn is_live(&self, id: AllocId) -> bool {
-        self.collected.contains(&id) ||
-        self.ecx.is_alloc_live(id)
+        self.collected.contains(&id) || self.ecx.is_alloc_live(id)
     }
 }
 
 impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
 pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
     fn run_provenance_gc(&mut self) {
-
         // We collect all tags from various parts of the interpreter, but also
         let this = self.eval_context_mut();
 
@@ -196,10 +194,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
 
     fn remove_unreachable_allocs(&mut self, allocs: FxHashSet<AllocId>) {
         let this = self.eval_context_ref();
-        let allocs = LiveAllocs {
-            ecx: this,
-            collected: allocs,
-        };
+        let allocs = LiveAllocs { ecx: this, collected: allocs };
         this.machine.allocation_spans.borrow_mut().retain(|id, _| allocs.is_live(*id));
         this.machine.intptrcast.borrow_mut().remove_unreachable_allocs(&allocs);
         if let Some(borrow_tracker) = &this.machine.borrow_tracker {
diff --git a/src/tools/miri/tests/utils/mod.rs b/src/tools/miri/tests/utils/mod.rs
index 6386162e095..3b817667f13 100644
--- a/src/tools/miri/tests/utils/mod.rs
+++ b/src/tools/miri/tests/utils/mod.rs
@@ -12,7 +12,5 @@ pub use miri_extern::*;
 
 pub fn run_provenance_gc() {
     // SAFETY: No preconditions. The GC is fine to run at any time.
-    unsafe {
-        miri_run_provenance_gc()
-    }
+    unsafe { miri_run_provenance_gc() }
 }

From 09358a05c37abd9a9a6b31a9c53d2378f8ab9d6b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= <eduardosm-dev@e64.io>
Date: Mon, 20 Nov 2023 19:29:02 +0100
Subject: [PATCH 08/22] Check that target features required by LLVM intrinsics
 are enabled

---
 src/tools/miri/src/helpers.rs                 | 18 ++++++++
 src/tools/miri/src/shims/foreign_items.rs     |  2 +
 src/tools/miri/src/shims/x86/aesni.rs         |  1 +
 src/tools/miri/src/shims/x86/mod.rs           | 13 ++++--
 src/tools/miri/src/shims/x86/sse.rs           | 13 +++---
 src/tools/miri/src/shims/x86/sse2.rs          | 13 +++---
 src/tools/miri/src/shims/x86/sse3.rs          |  1 +
 src/tools/miri/src/shims/x86/sse41.rs         |  1 +
 src/tools/miri/src/shims/x86/ssse3.rs         |  1 +
 .../fail/shims/intrinsic_target_feature.rs    | 42 +++++++++++++++++++
 .../shims/intrinsic_target_feature.stderr     | 15 +++++++
 11 files changed, 101 insertions(+), 19 deletions(-)
 create mode 100644 src/tools/miri/tests/fail/shims/intrinsic_target_feature.rs
 create mode 100644 src/tools/miri/tests/fail/shims/intrinsic_target_feature.stderr

diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index 965cd534d1e..22f6e99f545 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -1063,6 +1063,24 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             _ => span_bug!(this.cur_span(), "unexpected type: {ty:?}"),
         }
     }
+
+    /// Checks that target feature `target_feature` is enabled.
+    ///
+    /// If not enabled, emits an UB error that states that the feature is
+    /// required by `intrinsic`.
+    fn expect_target_feature_for_intrinsic(
+        &self,
+        intrinsic: Symbol,
+        target_feature: &str,
+    ) -> InterpResult<'tcx, ()> {
+        let this = self.eval_context_ref();
+        if !this.tcx.sess.unstable_target_features.contains(&Symbol::intern(target_feature)) {
+            throw_ub_format!(
+                "attempted to call intrinsic `{intrinsic}` that requires missing target feature {target_feature}"
+            );
+        }
+        Ok(())
+    }
 }
 
 impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index 2d5df303745..746f874275d 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -1008,9 +1008,11 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             "llvm.arm.hint" if this.tcx.sess.target.arch == "arm" => {
                 let [arg] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
                 let arg = this.read_scalar(arg)?.to_i32()?;
+                // Note that different arguments might have different target feature requirements.
                 match arg {
                     // YIELD
                     1 => {
+                        this.expect_target_feature_for_intrinsic(link_name, "v6")?;
                         this.yield_active_thread();
                     }
                     _ => {
diff --git a/src/tools/miri/src/shims/x86/aesni.rs b/src/tools/miri/src/shims/x86/aesni.rs
index aef930595b2..fb0b7015127 100644
--- a/src/tools/miri/src/shims/x86/aesni.rs
+++ b/src/tools/miri/src/shims/x86/aesni.rs
@@ -18,6 +18,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
         dest: &PlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateForeignItemResult> {
         let this = self.eval_context_mut();
+        this.expect_target_feature_for_intrinsic(link_name, "aes")?;
         // Prefix should have already been checked.
         let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.aesni.").unwrap();
 
diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs
index 2a2171134d4..78590b08933 100644
--- a/src/tools/miri/src/shims/x86/mod.rs
+++ b/src/tools/miri/src/shims/x86/mod.rs
@@ -164,7 +164,11 @@ enum FloatBinOp {
 impl FloatBinOp {
     /// Convert from the `imm` argument used to specify the comparison
     /// operation in intrinsics such as `llvm.x86.sse.cmp.ss`.
-    fn cmp_from_imm(imm: i8, intrinsic: &str) -> InterpResult<'_, Self> {
+    fn cmp_from_imm<'tcx>(
+        this: &crate::MiriInterpCx<'_, 'tcx>,
+        imm: i8,
+        intrinsic: Symbol,
+    ) -> InterpResult<'tcx, Self> {
         // Only bits 0..=4 are used, remaining should be zero.
         if imm & !0b1_1111 != 0 {
             throw_unsup_format!("invalid `imm` parameter of {intrinsic}: 0x{imm:x}");
@@ -174,7 +178,7 @@ impl FloatBinOp {
         // Bits 0..=2 specifies the operation.
         // `gt` indicates the result to be returned when the LHS is strictly
         // greater than the RHS, and so on.
-        let (gt, lt, eq, unord) = match imm & 0b111 {
+        let (gt, lt, eq, mut unord) = match imm & 0b111 {
             // Equal
             0x0 => (false, false, true, false),
             // Less-than
@@ -194,7 +198,10 @@ impl FloatBinOp {
             _ => unreachable!(),
         };
         // When bit 3 is 1 (only possible in AVX), unord is toggled.
-        let unord = unord ^ (imm & 0b1000 != 0);
+        if imm & 0b1000 != 0 {
+            this.expect_target_feature_for_intrinsic(intrinsic, "avx")?;
+            unord = !unord;
+        }
         Ok(Self::Cmp { gt, lt, eq, unord })
     }
 }
diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs
index e15023c3c21..8cdb3402f0c 100644
--- a/src/tools/miri/src/shims/x86/sse.rs
+++ b/src/tools/miri/src/shims/x86/sse.rs
@@ -21,6 +21,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
         dest: &PlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateForeignItemResult> {
         let this = self.eval_context_mut();
+        this.expect_target_feature_for_intrinsic(link_name, "sse")?;
         // Prefix should have already been checked.
         let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.sse.").unwrap();
         // All these intrinsics operate on 128-bit (f32x4) SIMD vectors unless stated otherwise.
@@ -107,10 +108,8 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                 let [left, right, imm] =
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
 
-                let which = FloatBinOp::cmp_from_imm(
-                    this.read_scalar(imm)?.to_i8()?,
-                    "llvm.x86.sse.cmp.ss",
-                )?;
+                let which =
+                    FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
 
                 bin_op_simd_float_first::<Single>(this, which, left, right, dest)?;
             }
@@ -126,10 +125,8 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                 let [left, right, imm] =
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
 
-                let which = FloatBinOp::cmp_from_imm(
-                    this.read_scalar(imm)?.to_i8()?,
-                    "llvm.x86.sse.cmp.ps",
-                )?;
+                let which =
+                    FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
 
                 bin_op_simd_float_all::<Single>(this, which, left, right, dest)?;
             }
diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs
index 55520771cf6..01496b319f1 100644
--- a/src/tools/miri/src/shims/x86/sse2.rs
+++ b/src/tools/miri/src/shims/x86/sse2.rs
@@ -20,6 +20,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
         dest: &PlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateForeignItemResult> {
         let this = self.eval_context_mut();
+        this.expect_target_feature_for_intrinsic(link_name, "sse2")?;
         // Prefix should have already been checked.
         let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.sse2.").unwrap();
 
@@ -473,10 +474,8 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                 let [left, right, imm] =
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
 
-                let which = FloatBinOp::cmp_from_imm(
-                    this.read_scalar(imm)?.to_i8()?,
-                    "llvm.x86.sse2.cmp.sd",
-                )?;
+                let which =
+                    FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
 
                 bin_op_simd_float_first::<Double>(this, which, left, right, dest)?;
             }
@@ -492,10 +491,8 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                 let [left, right, imm] =
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
 
-                let which = FloatBinOp::cmp_from_imm(
-                    this.read_scalar(imm)?.to_i8()?,
-                    "llvm.x86.sse2.cmp.pd",
-                )?;
+                let which =
+                    FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
 
                 bin_op_simd_float_all::<Double>(this, which, left, right, dest)?;
             }
diff --git a/src/tools/miri/src/shims/x86/sse3.rs b/src/tools/miri/src/shims/x86/sse3.rs
index 270da36f0e3..99a7a4f2f88 100644
--- a/src/tools/miri/src/shims/x86/sse3.rs
+++ b/src/tools/miri/src/shims/x86/sse3.rs
@@ -18,6 +18,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
         dest: &PlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateForeignItemResult> {
         let this = self.eval_context_mut();
+        this.expect_target_feature_for_intrinsic(link_name, "sse3")?;
         // Prefix should have already been checked.
         let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.sse3.").unwrap();
 
diff --git a/src/tools/miri/src/shims/x86/sse41.rs b/src/tools/miri/src/shims/x86/sse41.rs
index 523f3bfc26f..d9bccecb497 100644
--- a/src/tools/miri/src/shims/x86/sse41.rs
+++ b/src/tools/miri/src/shims/x86/sse41.rs
@@ -18,6 +18,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
         dest: &PlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateForeignItemResult> {
         let this = self.eval_context_mut();
+        this.expect_target_feature_for_intrinsic(link_name, "sse4.1")?;
         // Prefix should have already been checked.
         let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.sse41.").unwrap();
 
diff --git a/src/tools/miri/src/shims/x86/ssse3.rs b/src/tools/miri/src/shims/x86/ssse3.rs
index dbc2b947b33..724150fd2fe 100644
--- a/src/tools/miri/src/shims/x86/ssse3.rs
+++ b/src/tools/miri/src/shims/x86/ssse3.rs
@@ -18,6 +18,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
         dest: &PlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateForeignItemResult> {
         let this = self.eval_context_mut();
+        this.expect_target_feature_for_intrinsic(link_name, "ssse3")?;
         // Prefix should have already been checked.
         let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.ssse3.").unwrap();
 
diff --git a/src/tools/miri/tests/fail/shims/intrinsic_target_feature.rs b/src/tools/miri/tests/fail/shims/intrinsic_target_feature.rs
new file mode 100644
index 00000000000..9263ad381d1
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/intrinsic_target_feature.rs
@@ -0,0 +1,42 @@
+// 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 output would be
+// different for non-x86 targets.
+//@ignore-target-aarch64
+//@ignore-target-arm
+//@ignore-target-avr
+//@ignore-target-s390x
+//@ignore-target-thumbv7em
+//@ignore-target-wasm32
+// Explicitly disable SSE4.1 because it is enabled by default on macOS
+//@compile-flags: -C target-feature=-sse4.1
+
+#![feature(link_llvm_intrinsics, simd_ffi)]
+
+#[cfg(target_arch = "x86")]
+use std::arch::x86::*;
+#[cfg(target_arch = "x86_64")]
+use std::arch::x86_64::*;
+
+fn main() {
+    assert!(is_x86_feature_detected!("sse"));
+    assert!(!is_x86_feature_detected!("sse4.1"));
+
+    unsafe {
+        // Pass, since SSE is enabled
+        addss(_mm_setzero_ps(), _mm_setzero_ps());
+
+        // Fail, since SSE4.1 is not enabled
+        dpps(_mm_setzero_ps(), _mm_setzero_ps(), 0);
+        //~^ ERROR: Undefined Behavior: attempted to call intrinsic `llvm.x86.sse41.dpps` that requires missing target feature sse4.1
+    }
+}
+
+#[allow(improper_ctypes)]
+extern "C" {
+    #[link_name = "llvm.x86.sse.add.ss"]
+    fn addss(a: __m128, b: __m128) -> __m128;
+
+    #[link_name = "llvm.x86.sse41.dpps"]
+    fn dpps(a: __m128, b: __m128, imm8: u8) -> __m128;
+}
diff --git a/src/tools/miri/tests/fail/shims/intrinsic_target_feature.stderr b/src/tools/miri/tests/fail/shims/intrinsic_target_feature.stderr
new file mode 100644
index 00000000000..c034261338a
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/intrinsic_target_feature.stderr
@@ -0,0 +1,15 @@
+error: Undefined Behavior: attempted to call intrinsic `llvm.x86.sse41.dpps` that requires missing target feature sse4.1
+  --> $DIR/intrinsic_target_feature.rs:LL:CC
+   |
+LL |         dpps(_mm_setzero_ps(), _mm_setzero_ps(), 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to call intrinsic `llvm.x86.sse41.dpps` that requires missing target feature sse4.1
+   |
+   = 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
+   = note: BACKTRACE:
+   = note: inside `main` at $DIR/intrinsic_target_feature.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+

From 804afa4a94f4e9a502531c19c9a150eb1d33f4f6 Mon Sep 17 00:00:00 2001
From: The Miri Conjob Bot <miri@cron.bot>
Date: Thu, 23 Nov 2023 04:55:03 +0000
Subject: [PATCH 09/22] Preparing for merge from rustc

---
 src/tools/miri/rust-version | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 00a41008d3b..ee27d8ed9a8 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-0ff861096449f47956521b40e5e4e88caa7fe27c
+360bafad68cfea2682cf016070e533c45a00150f

From 4896c953e18869c57c10cea3aceb81d56537e504 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Thu, 23 Nov 2023 08:14:50 +0100
Subject: [PATCH 10/22] detect and test for data races between setenv and
 getenv

---
 src/tools/miri/src/helpers.rs                 | 15 ++----
 src/tools/miri/src/shims/env.rs               | 53 ++++++++++++-------
 src/tools/miri/src/shims/foreign_items.rs     |  3 +-
 .../src/shims/unix/android/foreign_items.rs   |  2 +-
 .../fail-dep/shims/env-set_var-data-race.rs   | 17 ++++++
 .../shims/env-set_var-data-race.stderr        | 20 +++++++
 .../pass-dep/shims/env-cleanup-data-race.rs   |  5 +-
 7 files changed, 79 insertions(+), 36 deletions(-)
 create mode 100644 src/tools/miri/tests/fail-dep/shims/env-set_var-data-race.rs
 create mode 100644 src/tools/miri/tests/fail-dep/shims/env-set_var-data-race.stderr

diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index 965cd534d1e..f3890fc1dcb 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -565,10 +565,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     /// is part of the UNIX family. It panics showing a message with the `name` of the foreign function
     /// if this is not the case.
     fn assert_target_os_is_unix(&self, name: &str) {
-        assert!(
-            target_os_is_unix(self.eval_context_ref().tcx.sess.target.os.as_ref()),
-            "`{name}` is only available for supported UNIX family targets",
-        );
+        assert!(self.target_os_is_unix(), "`{name}` is only available for unix targets",);
+    }
+
+    fn target_os_is_unix(&self) -> bool {
+        self.eval_context_ref().tcx.sess.target.families.iter().any(|f| f == "unix")
     }
 
     /// Get last error variable as a place, lazily allocating thread-local storage for it if
@@ -1143,12 +1144,6 @@ pub fn get_local_crates(tcx: TyCtxt<'_>) -> Vec<CrateNum> {
     local_crates
 }
 
-/// Helper function used inside the shims of foreign functions to check that
-/// `target_os` is a supported UNIX OS.
-pub fn target_os_is_unix(target_os: &str) -> bool {
-    matches!(target_os, "linux" | "macos" | "freebsd" | "android")
-}
-
 pub(crate) fn bool_to_simd_element(b: bool, size: Size) -> Scalar<Provenance> {
     // SIMD uses all-1 as pattern for "true". In two's complement,
     // -1 has all its bits set to one and `from_int` will truncate or
diff --git a/src/tools/miri/src/shims/env.rs b/src/tools/miri/src/shims/env.rs
index 42438985907..9e19f720211 100644
--- a/src/tools/miri/src/shims/env.rs
+++ b/src/tools/miri/src/shims/env.rs
@@ -9,7 +9,6 @@ use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::Ty;
 use rustc_target::abi::Size;
 
-use crate::helpers::target_os_is_unix;
 use crate::*;
 
 /// Check whether an operation that writes to a target buffer was successful.
@@ -53,16 +52,15 @@ impl<'tcx> EnvVars<'tcx> {
         ecx: &mut InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>,
         config: &MiriConfig,
     ) -> InterpResult<'tcx> {
-        let target_os = ecx.tcx.sess.target.os.as_ref();
-
+        // Initialize the `env_vars` map.
         // Skip the loop entirely if we don't want to forward anything.
         if ecx.machine.communicate() || !config.forwarded_env_vars.is_empty() {
             for (name, value) in &config.env {
                 let forward = ecx.machine.communicate()
                     || config.forwarded_env_vars.iter().any(|v| **v == *name);
                 if forward {
-                    let var_ptr = match target_os {
-                        target if target_os_is_unix(target) =>
+                    let var_ptr = match ecx.tcx.sess.target.os.as_ref() {
+                        _ if ecx.target_os_is_unix() =>
                             alloc_env_var_as_c_str(name.as_ref(), value.as_ref(), ecx)?,
                         "windows" => alloc_env_var_as_wide_str(name.as_ref(), value.as_ref(), ecx)?,
                         unsupported =>
@@ -75,7 +73,17 @@ impl<'tcx> EnvVars<'tcx> {
                 }
             }
         }
-        ecx.update_environ()
+
+        // Initialize the `environ` pointer when needed.
+        if ecx.target_os_is_unix() {
+            // This is memory backing an extern static, hence `ExternStatic`, not `Env`.
+            let layout = ecx.machine.layouts.mut_raw_ptr;
+            let place = ecx.allocate(layout, MiriMemoryKind::ExternStatic.into())?;
+            ecx.write_null(&place)?;
+            ecx.machine.env_vars.environ = Some(place);
+            ecx.update_environ()?;
+        }
+        Ok(())
     }
 
     pub(crate) fn cleanup<'mir>(
@@ -87,9 +95,11 @@ impl<'tcx> EnvVars<'tcx> {
             ecx.deallocate_ptr(ptr, None, MiriMemoryKind::Runtime.into())?;
         }
         // Deallocate environ var list.
-        let environ = ecx.machine.env_vars.environ.as_ref().unwrap();
-        let old_vars_ptr = ecx.read_pointer(environ)?;
-        ecx.deallocate_ptr(old_vars_ptr, None, MiriMemoryKind::Runtime.into())?;
+        if ecx.target_os_is_unix() {
+            let environ = ecx.machine.env_vars.environ.as_ref().unwrap();
+            let old_vars_ptr = ecx.read_pointer(environ)?;
+            ecx.deallocate_ptr(old_vars_ptr, None, MiriMemoryKind::Runtime.into())?;
+        }
         Ok(())
     }
 }
@@ -127,6 +137,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
         let name_ptr = this.read_pointer(name_op)?;
         let name = this.read_os_str_from_c_str(name_ptr)?;
+        this.read_environ()?;
         Ok(match this.machine.env_vars.map.get(name) {
             Some(var_ptr) => {
                 // The offset is used to strip the "{name}=" part of the string.
@@ -275,7 +286,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             // Delete environment variable `{name}`
             if let Some(var) = this.machine.env_vars.map.remove(&name) {
                 this.deallocate_ptr(var, None, MiriMemoryKind::Runtime.into())?;
-                this.update_environ()?;
             }
             Ok(this.eval_windows("c", "TRUE"))
         } else {
@@ -284,7 +294,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             if let Some(var) = this.machine.env_vars.map.insert(name, var_ptr) {
                 this.deallocate_ptr(var, None, MiriMemoryKind::Runtime.into())?;
             }
-            this.update_environ()?;
             Ok(this.eval_windows("c", "TRUE"))
         }
     }
@@ -431,15 +440,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     fn update_environ(&mut self) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
         // Deallocate the old environ list, if any.
-        if let Some(environ) = this.machine.env_vars.environ.as_ref() {
-            let old_vars_ptr = this.read_pointer(environ)?;
+        let environ = this.machine.env_vars.environ.as_ref().unwrap().clone();
+        let old_vars_ptr = this.read_pointer(&environ)?;
+        if !this.ptr_is_null(old_vars_ptr)? {
             this.deallocate_ptr(old_vars_ptr, None, MiriMemoryKind::Runtime.into())?;
-        } else {
-            // No `environ` allocated yet, let's do that.
-            // This is memory backing an extern static, hence `ExternStatic`, not `Env`.
-            let layout = this.machine.layouts.mut_raw_ptr;
-            let place = this.allocate(layout, MiriMemoryKind::ExternStatic.into())?;
-            this.machine.env_vars.environ = Some(place);
         }
 
         // Collect all the pointers to each variable in a vector.
@@ -459,11 +463,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             let place = this.project_field(&vars_place, idx)?;
             this.write_pointer(var, &place)?;
         }
-        this.write_pointer(vars_place.ptr(), &this.machine.env_vars.environ.clone().unwrap())?;
+        this.write_pointer(vars_place.ptr(), &environ)?;
 
         Ok(())
     }
 
+    /// Reads from the `environ` static.
+    /// We don't actually care about the result, but we care about this potentially causing a data race.
+    fn read_environ(&self) -> InterpResult<'tcx> {
+        let this = self.eval_context_ref();
+        let environ = this.machine.env_vars.environ.as_ref().unwrap();
+        let _vars_ptr = this.read_pointer(environ)?;
+        Ok(())
+    }
+
     fn getpid(&mut self) -> InterpResult<'tcx, i32> {
         let this = self.eval_context_mut();
         this.assert_target_os_is_unix("getpid");
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index d7aaa08dbf3..6443efd7bde 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -22,7 +22,6 @@ use rustc_target::{
 };
 
 use super::backtrace::EvalContextExt as _;
-use crate::helpers::target_os_is_unix;
 use crate::*;
 
 /// Type of dynamic symbols (for `dlsym` et al)
@@ -1058,7 +1057,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             // Platform-specific shims
             _ =>
                 return match this.tcx.sess.target.os.as_ref() {
-                    target_os if target_os_is_unix(target_os) =>
+                    _ if this.target_os_is_unix() =>
                         shims::unix::foreign_items::EvalContextExt::emulate_foreign_item_inner(
                             this, link_name, abi, args, dest,
                         ),
diff --git a/src/tools/miri/src/shims/unix/android/foreign_items.rs b/src/tools/miri/src/shims/unix/android/foreign_items.rs
index f61ebd5a3a8..5653e3f1129 100644
--- a/src/tools/miri/src/shims/unix/android/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/android/foreign_items.rs
@@ -11,7 +11,7 @@ pub fn is_dyn_sym(_name: &str) -> bool {
 }
 
 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
-    #[allow(unused, clippy::match_single_binding)] // there isn't anything here yet
+    #[allow(unused, clippy::match_single_binding)] // FIXME: there isn't anything here yet
     fn emulate_foreign_item_inner(
         &mut self,
         link_name: Symbol,
diff --git a/src/tools/miri/tests/fail-dep/shims/env-set_var-data-race.rs b/src/tools/miri/tests/fail-dep/shims/env-set_var-data-race.rs
new file mode 100644
index 00000000000..2b9e7a34d65
--- /dev/null
+++ b/src/tools/miri/tests/fail-dep/shims/env-set_var-data-race.rs
@@ -0,0 +1,17 @@
+//@compile-flags: -Zmiri-disable-isolation -Zmiri-preemption-rate=0
+//@ignore-target-windows: No libc on Windows
+
+use std::env;
+use std::thread;
+
+fn main() {
+    let t = thread::spawn(|| unsafe {
+        // Access the environment in another thread without taking the env lock.
+        // This represents some C code that queries the environment.
+        libc::getenv(b"TZ\0".as_ptr().cast()); //~ERROR: Data race detected
+    });
+    // Meanwhile, the main thread uses the "safe" Rust env accessor.
+    env::set_var("MY_RUST_VAR", "Ferris");
+
+    t.join().unwrap();
+}
diff --git a/src/tools/miri/tests/fail-dep/shims/env-set_var-data-race.stderr b/src/tools/miri/tests/fail-dep/shims/env-set_var-data-race.stderr
new file mode 100644
index 00000000000..a202d7c6844
--- /dev/null
+++ b/src/tools/miri/tests/fail-dep/shims/env-set_var-data-race.stderr
@@ -0,0 +1,20 @@
+error: Undefined Behavior: Data race detected between (1) non-atomic write on thread `main` and (2) non-atomic read on thread `<unnamed>` at ALLOC. (2) just happened here
+  --> $DIR/env-set_var-data-race.rs:LL:CC
+   |
+LL |         libc::getenv(b"TZ/0".as_ptr().cast());
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) non-atomic write on thread `main` and (2) non-atomic read on thread `<unnamed>` at ALLOC. (2) just happened here
+   |
+help: and (1) occurred earlier here
+  --> $DIR/env-set_var-data-race.rs:LL:CC
+   |
+LL |     env::set_var("MY_RUST_VAR", "Ferris");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = 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
+   = note: BACKTRACE (of the first span):
+   = note: inside closure at $DIR/env-set_var-data-race.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+
diff --git a/src/tools/miri/tests/pass-dep/shims/env-cleanup-data-race.rs b/src/tools/miri/tests/pass-dep/shims/env-cleanup-data-race.rs
index d36ffe70321..5c29a1b15a7 100644
--- a/src/tools/miri/tests/pass-dep/shims/env-cleanup-data-race.rs
+++ b/src/tools/miri/tests/pass-dep/shims/env-cleanup-data-race.rs
@@ -2,15 +2,13 @@
 //@ignore-target-windows: No libc on Windows
 
 use std::ffi::CStr;
-use std::ffi::CString;
 use std::thread;
 
 fn main() {
     unsafe {
         thread::spawn(|| {
             // Access the environment in another thread without taking the env lock
-            let k = CString::new("MIRI_ENV_VAR_TEST".as_bytes()).unwrap();
-            let s = libc::getenv(k.as_ptr()) as *const libc::c_char;
+            let s = libc::getenv("MIRI_ENV_VAR_TEST\0".as_ptr().cast());
             if s.is_null() {
                 panic!("null");
             }
@@ -19,5 +17,6 @@ fn main() {
         thread::yield_now();
         // After the main thread exits, env vars will be cleaned up -- but because we have not *joined*
         // the other thread, those accesses technically race with those in the other thread.
+        // We don't want to emit an error here, though.
     }
 }

From 4b69e525f5e090d1268cbace2846a8985dce6fae Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Thu, 23 Nov 2023 08:19:01 +0100
Subject: [PATCH 11/22] remove stub android files that don't do anything

---
 .../src/shims/unix/android/foreign_items.rs   | 30 -------------------
 src/tools/miri/src/shims/unix/android/mod.rs  |  1 -
 .../miri/src/shims/unix/foreign_items.rs      |  5 +---
 src/tools/miri/src/shims/unix/mod.rs          |  1 -
 4 files changed, 1 insertion(+), 36 deletions(-)
 delete mode 100644 src/tools/miri/src/shims/unix/android/foreign_items.rs
 delete mode 100644 src/tools/miri/src/shims/unix/android/mod.rs

diff --git a/src/tools/miri/src/shims/unix/android/foreign_items.rs b/src/tools/miri/src/shims/unix/android/foreign_items.rs
deleted file mode 100644
index 5653e3f1129..00000000000
--- a/src/tools/miri/src/shims/unix/android/foreign_items.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-use rustc_span::Symbol;
-use rustc_target::spec::abi::Abi;
-
-use crate::*;
-use shims::foreign_items::EmulateForeignItemResult;
-
-impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
-
-pub fn is_dyn_sym(_name: &str) -> bool {
-    false
-}
-
-pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
-    #[allow(unused, clippy::match_single_binding)] // FIXME: there isn't anything here yet
-    fn emulate_foreign_item_inner(
-        &mut self,
-        link_name: Symbol,
-        abi: Abi,
-        args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
-    ) -> InterpResult<'tcx, EmulateForeignItemResult> {
-        let this = self.eval_context_mut();
-
-        match link_name.as_str() {
-            _ => return Ok(EmulateForeignItemResult::NotSupported),
-        }
-
-        Ok(EmulateForeignItemResult::NeedsJumping)
-    }
-}
diff --git a/src/tools/miri/src/shims/unix/android/mod.rs b/src/tools/miri/src/shims/unix/android/mod.rs
deleted file mode 100644
index 09c6507b24f..00000000000
--- a/src/tools/miri/src/shims/unix/android/mod.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub mod foreign_items;
diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs
index 7bc26788b26..c1c3e3fa10c 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -15,7 +15,6 @@ use shims::unix::mem::EvalContextExt as _;
 use shims::unix::sync::EvalContextExt as _;
 use shims::unix::thread::EvalContextExt as _;
 
-use shims::unix::android::foreign_items as android;
 use shims::unix::freebsd::foreign_items as freebsd;
 use shims::unix::linux::foreign_items as linux;
 use shims::unix::macos::foreign_items as macos;
@@ -32,11 +31,10 @@ fn is_dyn_sym(name: &str, target_os: &str) -> bool {
         // Give specific OSes a chance to allow their symbols.
         _ =>
             match target_os {
-                "android" => android::is_dyn_sym(name),
                 "freebsd" => freebsd::is_dyn_sym(name),
                 "linux" => linux::is_dyn_sym(name),
                 "macos" => macos::is_dyn_sym(name),
-                target_os => panic!("unsupported Unix OS {target_os}"),
+                _ => false,
             },
     }
 }
@@ -706,7 +704,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             _ => {
                 let target_os = &*this.tcx.sess.target.os;
                 return match target_os {
-                    "android" => android::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
                     "freebsd" => freebsd::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
                     "linux" => linux::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
                     "macos" => macos::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
diff --git a/src/tools/miri/src/shims/unix/mod.rs b/src/tools/miri/src/shims/unix/mod.rs
index 2f801493352..638473da02b 100644
--- a/src/tools/miri/src/shims/unix/mod.rs
+++ b/src/tools/miri/src/shims/unix/mod.rs
@@ -5,7 +5,6 @@ mod mem;
 mod sync;
 mod thread;
 
-mod android;
 mod freebsd;
 mod linux;
 mod macos;

From 28550240634a36ddd0696823dff89c84805e10bb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= <eduardosm-dev@e64.io>
Date: Thu, 23 Nov 2023 20:14:12 +0100
Subject: [PATCH 12/22] Refactor `float_to_int_checked` to remove its generic
 parameter and reduce code duplication a bit

---
 src/tools/miri/src/helpers.rs                 | 104 ++++++++++--------
 src/tools/miri/src/shims/intrinsics/mod.rs    |  38 ++-----
 src/tools/miri/src/shims/intrinsics/simd.rs   |  17 +--
 src/tools/miri/src/shims/x86/mod.rs           |  39 ++++++-
 src/tools/miri/src/shims/x86/sse.rs           |   4 +-
 src/tools/miri/src/shims/x86/sse2.rs          |  90 +++++----------
 src/tools/miri/src/shims/x86/sse41.rs         |   2 +-
 .../intrinsics/float_to_int_32_inf1.stderr    |   4 +-
 .../intrinsics/float_to_int_32_infneg1.stderr |   4 +-
 .../intrinsics/float_to_int_32_nan.stderr     |   4 +-
 .../intrinsics/float_to_int_32_nanneg.stderr  |   4 +-
 .../intrinsics/float_to_int_32_neg.stderr     |   4 +-
 .../float_to_int_32_too_big1.stderr           |   4 +-
 .../float_to_int_32_too_big2.stderr           |   4 +-
 .../float_to_int_32_too_small1.stderr         |   4 +-
 .../intrinsics/float_to_int_64_inf1.stderr    |   4 +-
 .../intrinsics/float_to_int_64_infneg1.stderr |   4 +-
 .../intrinsics/float_to_int_64_infneg2.stderr |   4 +-
 .../intrinsics/float_to_int_64_nan.stderr     |   4 +-
 .../intrinsics/float_to_int_64_neg.stderr     |   4 +-
 .../float_to_int_64_too_big1.stderr           |   4 +-
 .../float_to_int_64_too_big2.stderr           |   4 +-
 .../float_to_int_64_too_big3.stderr           |   4 +-
 .../float_to_int_64_too_big4.stderr           |   4 +-
 .../float_to_int_64_too_big5.stderr           |   4 +-
 .../float_to_int_64_too_big6.stderr           |   4 +-
 .../float_to_int_64_too_big7.stderr           |   4 +-
 .../float_to_int_64_too_small1.stderr         |   4 +-
 .../float_to_int_64_too_small2.stderr         |   4 +-
 .../float_to_int_64_too_small3.stderr         |   4 +-
 .../fail/intrinsics/simd-float-to-int.stderr  |   4 +-
 31 files changed, 185 insertions(+), 205 deletions(-)

diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index 650008b98ed..21f1d684924 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -5,17 +5,18 @@ use std::time::Duration;
 
 use log::trace;
 
+use rustc_apfloat::ieee::{Double, Single};
 use rustc_hir::def::{DefKind, Namespace};
 use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX};
 use rustc_index::IndexVec;
 use rustc_middle::mir;
 use rustc_middle::ty::{
     self,
-    layout::{IntegerExt as _, LayoutOf, TyAndLayout},
-    IntTy, Ty, TyCtxt, UintTy,
+    layout::{LayoutOf, TyAndLayout},
+    FloatTy, IntTy, Ty, TyCtxt, UintTy,
 };
 use rustc_span::{def_id::CrateNum, sym, Span, Symbol};
-use rustc_target::abi::{Align, FieldIdx, FieldsShape, Integer, Size, Variants};
+use rustc_target::abi::{Align, FieldIdx, FieldsShape, Size, Variants};
 use rustc_target::spec::abi::Abi;
 
 use rand::RngCore;
@@ -986,65 +987,74 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         }
     }
 
-    /// Converts `f` to integer type `dest_ty` after rounding with mode `round`.
+    /// Converts `src` from floating point to integer type `dest_ty`
+    /// after rounding with mode `round`.
     /// Returns `None` if `f` is NaN or out of range.
-    fn float_to_int_checked<F>(
+    fn float_to_int_checked(
         &self,
-        f: F,
+        src: &ImmTy<'tcx, Provenance>,
         cast_to: TyAndLayout<'tcx>,
         round: rustc_apfloat::Round,
-    ) -> Option<ImmTy<'tcx, Provenance>>
-    where
-        F: rustc_apfloat::Float + Into<Scalar<Provenance>>,
-    {
+    ) -> InterpResult<'tcx, Option<ImmTy<'tcx, Provenance>>> {
         let this = self.eval_context_ref();
 
-        let val = match cast_to.ty.kind() {
-            // Unsigned
-            ty::Uint(t) => {
-                let size = Integer::from_uint_ty(this, *t).size();
-                let res = f.to_u128_r(size.bits_usize(), round, &mut false);
-                if res.status.intersects(
-                    rustc_apfloat::Status::INVALID_OP
-                        | rustc_apfloat::Status::OVERFLOW
-                        | rustc_apfloat::Status::UNDERFLOW,
-                ) {
-                    // Floating point value is NaN (flagged with INVALID_OP) or outside the range
-                    // of values of the integer type (flagged with OVERFLOW or UNDERFLOW).
-                    return None;
-                } else {
-                    // Floating point value can be represented by the integer type after rounding.
-                    // The INEXACT flag is ignored on purpose to allow rounding.
-                    Scalar::from_uint(res.value, size)
+        fn float_to_int_inner<'tcx, F: rustc_apfloat::Float>(
+            this: &MiriInterpCx<'_, 'tcx>,
+            src: F,
+            cast_to: TyAndLayout<'tcx>,
+            round: rustc_apfloat::Round,
+        ) -> (Scalar<Provenance>, rustc_apfloat::Status) {
+            let int_size = cast_to.layout.size;
+            match cast_to.ty.kind() {
+                // Unsigned
+                ty::Uint(_) => {
+                    let res = src.to_u128_r(int_size.bits_usize(), round, &mut false);
+                    (Scalar::from_uint(res.value, int_size), res.status)
                 }
-            }
-            // Signed
-            ty::Int(t) => {
-                let size = Integer::from_int_ty(this, *t).size();
-                let res = f.to_i128_r(size.bits_usize(), round, &mut false);
-                if res.status.intersects(
-                    rustc_apfloat::Status::INVALID_OP
-                        | rustc_apfloat::Status::OVERFLOW
-                        | rustc_apfloat::Status::UNDERFLOW,
-                ) {
-                    // Floating point value is NaN (flagged with INVALID_OP) or outside the range
-                    // of values of the integer type (flagged with OVERFLOW or UNDERFLOW).
-                    return None;
-                } else {
-                    // Floating point value can be represented by the integer type after rounding.
-                    // The INEXACT flag is ignored on purpose to allow rounding.
-                    Scalar::from_int(res.value, size)
+                // Signed
+                ty::Int(_) => {
+                    let res = src.to_i128_r(int_size.bits_usize(), round, &mut false);
+                    (Scalar::from_int(res.value, int_size), res.status)
                 }
+                // Nothing else
+                _ =>
+                    span_bug!(
+                        this.cur_span(),
+                        "attempted float-to-int conversion with non-int output type {}",
+                        cast_to.ty,
+                    ),
             }
+        }
+
+        let (val, status) = match src.layout.ty.kind() {
+            // f32
+            ty::Float(FloatTy::F32) =>
+                float_to_int_inner::<Single>(this, src.to_scalar().to_f32()?, cast_to, round),
+            // f64
+            ty::Float(FloatTy::F64) =>
+                float_to_int_inner::<Double>(this, src.to_scalar().to_f64()?, cast_to, round),
             // Nothing else
             _ =>
                 span_bug!(
                     this.cur_span(),
-                    "attempted float-to-int conversion with non-int output type {}",
-                    cast_to.ty,
+                    "attempted float-to-int conversion with non-float input type {}",
+                    src.layout.ty,
                 ),
         };
-        Some(ImmTy::from_scalar(val, cast_to))
+
+        if status.intersects(
+            rustc_apfloat::Status::INVALID_OP
+                | rustc_apfloat::Status::OVERFLOW
+                | rustc_apfloat::Status::UNDERFLOW,
+        ) {
+            // Floating point value is NaN (flagged with INVALID_OP) or outside the range
+            // of values of the integer type (flagged with OVERFLOW or UNDERFLOW).
+            Ok(None)
+        } else {
+            // Floating point value can be represented by the integer type after rounding.
+            // The INEXACT flag is ignored on purpose to allow rounding.
+            Ok(Some(ImmTy::from_scalar(val, cast_to)))
+        }
     }
 
     /// Returns an integer type that is twice wide as `ty`
diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs
index 8c90ceba1e4..66918db995d 100644
--- a/src/tools/miri/src/shims/intrinsics/mod.rs
+++ b/src/tools/miri/src/shims/intrinsics/mod.rs
@@ -365,36 +365,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let [val] = check_arg_count(args)?;
                 let val = this.read_immediate(val)?;
 
-                let res = match val.layout.ty.kind() {
-                    ty::Float(FloatTy::F32) => {
-                        let f = val.to_scalar().to_f32()?;
-                        this
-                            .float_to_int_checked(f, dest.layout, Round::TowardZero)
-                            .ok_or_else(|| {
-                                err_ub_format!(
-                                    "`float_to_int_unchecked` intrinsic called on {f} which cannot be represented in target type `{:?}`",
-                                    dest.layout.ty
-                                )
-                            })?
-                    }
-                    ty::Float(FloatTy::F64) => {
-                        let f = val.to_scalar().to_f64()?;
-                        this
-                            .float_to_int_checked(f, dest.layout, Round::TowardZero)
-                            .ok_or_else(|| {
-                                err_ub_format!(
-                                    "`float_to_int_unchecked` intrinsic called on {f} which cannot be represented in target type `{:?}`",
-                                    dest.layout.ty
-                                )
-                            })?
-                    }
-                    _ =>
-                        span_bug!(
-                            this.cur_span(),
-                            "`float_to_int_unchecked` called with non-float input type {:?}",
-                            val.layout.ty
-                        ),
-                };
+                let res = this
+                    .float_to_int_checked(&val, dest.layout, Round::TowardZero)?
+                    .ok_or_else(|| {
+                        err_ub_format!(
+                            "`float_to_int_unchecked` intrinsic called on {val} which cannot be represented in target type `{:?}`",
+                            dest.layout.ty
+                        )
+                    })?;
 
                 this.write_immediate(*res, dest)?;
             }
diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs
index 70f90aac2c2..d0a293d5f81 100644
--- a/src/tools/miri/src/shims/intrinsics/simd.rs
+++ b/src/tools/miri/src/shims/intrinsics/simd.rs
@@ -447,22 +447,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                         (ty::Float(_), ty::Int(_) | ty::Uint(_)) if safe_cast =>
                             this.float_to_float_or_int(&op, dest.layout)?,
                         // Float-to-int in unchecked mode
-                        (ty::Float(FloatTy::F32), ty::Int(_) | ty::Uint(_)) if unsafe_cast => {
-                            let f = op.to_scalar().to_f32()?;
-                            this.float_to_int_checked(f, dest.layout, Round::TowardZero)
+                        (ty::Float(_), ty::Int(_) | ty::Uint(_)) if unsafe_cast => {
+                            this.float_to_int_checked(&op, dest.layout, Round::TowardZero)?
                                 .ok_or_else(|| {
                                     err_ub_format!(
-                                        "`simd_cast` intrinsic called on {f} which cannot be represented in target type `{:?}`",
-                                        dest.layout.ty
-                                    )
-                                })?
-                        }
-                        (ty::Float(FloatTy::F64), ty::Int(_) | ty::Uint(_)) if unsafe_cast => {
-                            let f = op.to_scalar().to_f64()?;
-                            this.float_to_int_checked(f, dest.layout, Round::TowardZero)
-                                .ok_or_else(|| {
-                                    err_ub_format!(
-                                        "`simd_cast` intrinsic called on {f} which cannot be represented in target type `{:?}`",
+                                        "`simd_cast` intrinsic called on {op} which cannot be represented in target type `{:?}`",
                                         dest.layout.ty
                                     )
                                 })?
diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs
index 78590b08933..2ae269db412 100644
--- a/src/tools/miri/src/shims/x86/mod.rs
+++ b/src/tools/miri/src/shims/x86/mod.rs
@@ -1,4 +1,4 @@
-use rustc_middle::mir;
+use rustc_middle::{mir, ty};
 use rustc_span::Symbol;
 use rustc_target::abi::Size;
 use rustc_target::spec::abi::Abi;
@@ -331,6 +331,43 @@ fn bin_op_simd_float_all<'tcx, F: rustc_apfloat::Float>(
     Ok(())
 }
 
+/// 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.
+///
+/// If `op` has more elements than `dest`, extra elements are ignored. If `op`
+/// has less elements than `dest`, the rest is filled with zeros.
+fn convert_float_to_int<'tcx>(
+    this: &mut crate::MiriInterpCx<'_, 'tcx>,
+    op: &OpTy<'tcx, Provenance>,
+    rnd: rustc_apfloat::Round,
+    dest: &PlaceTy<'tcx, Provenance>,
+) -> InterpResult<'tcx, ()> {
+    let (op, op_len) = this.operand_to_simd(op)?;
+    let (dest, dest_len) = this.place_to_simd(dest)?;
+
+    // Output must be *signed* integers.
+    assert!(matches!(dest.layout.field(this, 0).ty.kind(), ty::Int(_)));
+
+    for i in 0..op_len.min(dest_len) {
+        let op = this.read_immediate(&this.project_index(&op, i)?)?;
+        let dest = this.project_index(&dest, i)?;
+
+        let res = this.float_to_int_checked(&op, dest.layout, rnd)?.unwrap_or_else(|| {
+            // Fallback to minimum acording to SSE/AVX semantics.
+            ImmTy::from_int(dest.layout.size.signed_int_min(), dest.layout)
+        });
+        this.write_immediate(*res, &dest)?;
+    }
+    // Fill remainder with zeros
+    for i in op_len..dest_len {
+        let dest = this.project_index(&dest, i)?;
+        this.write_scalar(Scalar::from_int(0, dest.layout.size), &dest)?;
+    }
+
+    Ok(())
+}
+
 /// Horizontaly performs `which` operation on adjacent values of
 /// `left` and `right` SIMD vectors and stores the result in `dest`.
 fn horizontal_bin_op<'tcx>(
diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs
index 8cdb3402f0c..6e06f62b34c 100644
--- a/src/tools/miri/src/shims/x86/sse.rs
+++ b/src/tools/miri/src/shims/x86/sse.rs
@@ -168,7 +168,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                 let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
                 let (op, _) = this.operand_to_simd(op)?;
 
-                let op = this.read_scalar(&this.project_index(&op, 0)?)?.to_f32()?;
+                let op = this.read_immediate(&this.project_index(&op, 0)?)?;
 
                 let rnd = match unprefixed_name {
                     // "current SSE rounding mode", assume nearest
@@ -180,7 +180,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                     _ => unreachable!(),
                 };
 
-                let res = this.float_to_int_checked(op, dest.layout, rnd).unwrap_or_else(|| {
+                let res = this.float_to_int_checked(&op, dest.layout, rnd)?.unwrap_or_else(|| {
                     // Fallback to minimum acording to SSE semantics.
                     ImmTy::from_int(dest.layout.size.signed_int_min(), dest.layout)
                 });
diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs
index 01496b319f1..49bf7547ab0 100644
--- a/src/tools/miri/src/shims/x86/sse2.rs
+++ b/src/tools/miri/src/shims/x86/sse2.rs
@@ -4,7 +4,7 @@ use rustc_middle::ty::Ty;
 use rustc_span::Symbol;
 use rustc_target::spec::abi::Abi;
 
-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, convert_float_to_int, FloatBinOp};
 use crate::*;
 use shims::foreign_items::EmulateForeignItemResult;
 
@@ -260,37 +260,42 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                     this.write_scalar(Scalar::from_u64(res), &dest)?;
                 }
             }
-            // Used to implement the _mm_cvtps_epi32 and _mm_cvttps_epi32 functions.
-            // Converts packed f32 to packed i32.
-            "cvtps2dq" | "cvttps2dq" => {
+            // Used to implement the _mm_cvtps_epi32, _mm_cvttps_epi32, _mm_cvtpd_epi32
+            // and _mm_cvttpd_epi32 functions.
+            // Converts packed f32/f64 to packed i32.
+            "cvtps2dq" | "cvttps2dq" | "cvtpd2dq" | "cvttpd2dq" => {
                 let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
 
-                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 (op_len, _) = op.layout.ty.simd_size_and_type(*this.tcx);
+                let (dest_len, _) = dest.layout.ty.simd_size_and_type(*this.tcx);
+                match unprefixed_name {
+                    "cvtps2dq" | "cvttps2dq" => {
+                        // f32x4 to i32x4 conversion
+                        assert_eq!(op_len, 4);
+                        assert_eq!(dest_len, op_len);
+                    }
+                    "cvtpd2dq" | "cvttpd2dq" => {
+                        // f64x2 to i32x4 conversion
+                        // the last two values are filled with zeros
+                        assert_eq!(op_len, 2);
+                        assert_eq!(dest_len, 4);
+                    }
+                    _ => unreachable!(),
+                }
 
                 let rnd = match unprefixed_name {
                     // "current SSE rounding mode", assume nearest
                     // https://www.felixcloutier.com/x86/cvtps2dq
-                    "cvtps2dq" => rustc_apfloat::Round::NearestTiesToEven,
+                    // https://www.felixcloutier.com/x86/cvtpd2dq
+                    "cvtps2dq" | "cvtpd2dq" => rustc_apfloat::Round::NearestTiesToEven,
                     // always truncate
                     // https://www.felixcloutier.com/x86/cvttps2dq
-                    "cvttps2dq" => rustc_apfloat::Round::TowardZero,
+                    // https://www.felixcloutier.com/x86/cvttpd2dq
+                    "cvttps2dq" | "cvttpd2dq" => rustc_apfloat::Round::TowardZero,
                     _ => unreachable!(),
                 };
 
-                for i in 0..dest_len {
-                    let op = this.read_scalar(&this.project_index(&op, i)?)?.to_f32()?;
-                    let dest = this.project_index(&dest, i)?;
-
-                    let res =
-                        this.float_to_int_checked(op, dest.layout, rnd).unwrap_or_else(|| {
-                            // Fallback to minimum acording to SSE2 semantics.
-                            ImmTy::from_int(i32::MIN, this.machine.layouts.i32)
-                        });
-                    this.write_immediate(*res, &dest)?;
-                }
+                convert_float_to_int(this, op, rnd, dest)?;
             }
             // Used to implement the _mm_packs_epi16 function.
             // Converts two 16-bit integer vectors to a single 8-bit integer
@@ -527,45 +532,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                 };
                 this.write_scalar(Scalar::from_i32(i32::from(res)), dest)?;
             }
-            // Used to implement the _mm_cvtpd_epi32 and _mm_cvttpd_epi32 functions.
-            // Converts packed f64 to packed i32.
-            "cvtpd2dq" | "cvttpd2dq" => {
-                let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
-
-                let (op, op_len) = this.operand_to_simd(op)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
-
-                // op is f64x2, dest is i32x4
-                assert_eq!(op_len, 2);
-                assert_eq!(dest_len, 4);
-
-                let rnd = match unprefixed_name {
-                    // "current SSE rounding mode", assume nearest
-                    // https://www.felixcloutier.com/x86/cvtpd2dq
-                    "cvtpd2dq" => rustc_apfloat::Round::NearestTiesToEven,
-                    // always truncate
-                    // https://www.felixcloutier.com/x86/cvttpd2dq
-                    "cvttpd2dq" => rustc_apfloat::Round::TowardZero,
-                    _ => unreachable!(),
-                };
-
-                for i in 0..op_len {
-                    let op = this.read_scalar(&this.project_index(&op, i)?)?.to_f64()?;
-                    let dest = this.project_index(&dest, i)?;
-
-                    let res =
-                        this.float_to_int_checked(op, dest.layout, rnd).unwrap_or_else(|| {
-                            // Fallback to minimum acording to SSE2 semantics.
-                            ImmTy::from_int(i32::MIN, this.machine.layouts.i32)
-                        });
-                    this.write_immediate(*res, &dest)?;
-                }
-                // Fill the remaining with zeros
-                for i in op_len..dest_len {
-                    let dest = this.project_index(&dest, i)?;
-                    this.write_scalar(Scalar::from_i32(0), &dest)?;
-                }
-            }
             // Use to implement the _mm_cvtsd_si32, _mm_cvttsd_si32,
             // _mm_cvtsd_si64 and _mm_cvttsd_si64 functions.
             // Converts the first component of `op` from f64 to i32/i64.
@@ -573,7 +539,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                 let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
                 let (op, _) = this.operand_to_simd(op)?;
 
-                let op = this.read_scalar(&this.project_index(&op, 0)?)?.to_f64()?;
+                let op = this.read_immediate(&this.project_index(&op, 0)?)?;
 
                 let rnd = match unprefixed_name {
                     // "current SSE rounding mode", assume nearest
@@ -585,7 +551,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                     _ => unreachable!(),
                 };
 
-                let res = this.float_to_int_checked(op, dest.layout, rnd).unwrap_or_else(|| {
+                let res = this.float_to_int_checked(&op, dest.layout, rnd)?.unwrap_or_else(|| {
                     // Fallback to minimum acording to SSE semantics.
                     ImmTy::from_int(dest.layout.size.signed_int_min(), dest.layout)
                 });
diff --git a/src/tools/miri/src/shims/x86/sse41.rs b/src/tools/miri/src/shims/x86/sse41.rs
index d9bccecb497..b3d1056ab06 100644
--- a/src/tools/miri/src/shims/x86/sse41.rs
+++ b/src/tools/miri/src/shims/x86/sse41.rs
@@ -200,7 +200,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                     Scalar::from_u16(min_index.try_into().unwrap()),
                     &this.project_index(&dest, 1)?,
                 )?;
-                // Fill remaining with zeros
+                // Fill remainder with zeros
                 for i in 2..dest_len {
                     this.write_scalar(Scalar::from_u16(0), &this.project_index(&dest, i)?)?;
                 }
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.stderr
index c82d6b30224..27318c0a98d 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on +Inf which cannot be represented in target type `i32`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on +Inff32 which cannot be represented in target type `i32`
   --> $DIR/float_to_int_32_inf1.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f32, i32>(f32::INFINITY);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on +Inf which cannot be represented in target type `i32`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on +Inff32 which cannot be represented in target type `i32`
    |
    = 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/fail/intrinsics/float_to_int_32_infneg1.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.stderr
index 4ca41b676e9..bcf6b9015c1 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -Inf which cannot be represented in target type `i32`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -Inff32 which cannot be represented in target type `i32`
   --> $DIR/float_to_int_32_infneg1.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f32, i32>(f32::NEG_INFINITY);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -Inf which cannot be represented in target type `i32`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -Inff32 which cannot be represented in target type `i32`
    |
    = 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/fail/intrinsics/float_to_int_32_nan.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.stderr
index 88b8948b0c2..3e71fd10058 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on NaN which cannot be represented in target type `u32`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on NaNf32 which cannot be represented in target type `u32`
   --> $DIR/float_to_int_32_nan.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f32, u32>(f32::NAN);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on NaN which cannot be represented in target type `u32`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on NaNf32 which cannot be represented in target type `u32`
    |
    = 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/fail/intrinsics/float_to_int_32_nanneg.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.stderr
index ca798dd391a..479ea2c6b6f 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on NaN which cannot be represented in target type `u32`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on NaNf32 which cannot be represented in target type `u32`
   --> $DIR/float_to_int_32_nanneg.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f32, u32>(-f32::NAN);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on NaN which cannot be represented in target type `u32`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on NaNf32 which cannot be represented in target type `u32`
    |
    = 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/fail/intrinsics/float_to_int_32_neg.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.stderr
index 4ff6eb80985..ae17d676174 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -1 which cannot be represented in target type `u32`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -1f32 which cannot be represented in target type `u32`
   --> $DIR/float_to_int_32_neg.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f32, u32>(-1.000000001f32);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -1 which cannot be represented in target type `u32`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -1f32 which cannot be represented in target type `u32`
    |
    = 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/fail/intrinsics/float_to_int_32_too_big1.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.stderr
index fd17709d164..9edda4f2027 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 2.14748365E+9 which cannot be represented in target type `i32`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 2.14748365E+9f32 which cannot be represented in target type `i32`
   --> $DIR/float_to_int_32_too_big1.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f32, i32>(2147483648.0f32);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 2.14748365E+9 which cannot be represented in target type `i32`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 2.14748365E+9f32 which cannot be represented in target type `i32`
    |
    = 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/fail/intrinsics/float_to_int_32_too_big2.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.stderr
index fdc1f65dc14..7b394f97fd1 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 4.2949673E+9 which cannot be represented in target type `u32`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 4.2949673E+9f32 which cannot be represented in target type `u32`
   --> $DIR/float_to_int_32_too_big2.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f32, u32>((u32::MAX - 127) as f32);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 4.2949673E+9 which cannot be represented in target type `u32`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 4.2949673E+9f32 which cannot be represented in target type `u32`
    |
    = 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/fail/intrinsics/float_to_int_32_too_small1.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_small1.stderr
index 9e743a32144..1d8ab4b3cb1 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_small1.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_small1.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -2.1474839E+9 which cannot be represented in target type `i32`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -2.1474839E+9f32 which cannot be represented in target type `i32`
   --> $DIR/float_to_int_32_too_small1.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f32, i32>(-2147483904.0f32);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -2.1474839E+9 which cannot be represented in target type `i32`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -2.1474839E+9f32 which cannot be represented in target type `i32`
    |
    = 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/fail/intrinsics/float_to_int_64_inf1.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.stderr
index ee01143dc8d..857bd355fc5 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on +Inf which cannot be represented in target type `u128`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on +Inff64 which cannot be represented in target type `u128`
   --> $DIR/float_to_int_64_inf1.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f64, u128>(f64::INFINITY);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on +Inf which cannot be represented in target type `u128`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on +Inff64 which cannot be represented in target type `u128`
    |
    = 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/fail/intrinsics/float_to_int_64_infneg1.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.stderr
index f37b8ae5506..fc089182e6b 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -Inf which cannot be represented in target type `u128`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -Inff64 which cannot be represented in target type `u128`
   --> $DIR/float_to_int_64_infneg1.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f64, u128>(f64::NEG_INFINITY);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -Inf which cannot be represented in target type `u128`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -Inff64 which cannot be represented in target type `u128`
    |
    = 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/fail/intrinsics/float_to_int_64_infneg2.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.stderr
index 05dcd5ebcf6..c5d99c4d360 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -Inf which cannot be represented in target type `i128`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -Inff64 which cannot be represented in target type `i128`
   --> $DIR/float_to_int_64_infneg2.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f64, i128>(f64::NEG_INFINITY);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -Inf which cannot be represented in target type `i128`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -Inff64 which cannot be represented in target type `i128`
    |
    = 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/fail/intrinsics/float_to_int_64_nan.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.stderr
index 0a914abb2ce..05a7da06321 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on NaN which cannot be represented in target type `u32`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on NaNf64 which cannot be represented in target type `u32`
   --> $DIR/float_to_int_64_nan.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f64, u32>(f64::NAN);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on NaN which cannot be represented in target type `u32`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on NaNf64 which cannot be represented in target type `u32`
    |
    = 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/fail/intrinsics/float_to_int_64_neg.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.stderr
index ddf3249d059..d1ac6765336 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -1.0000000000000999 which cannot be represented in target type `u128`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -1.0000000000000999f64 which cannot be represented in target type `u128`
   --> $DIR/float_to_int_64_neg.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f64, u128>(-1.0000000000001f64);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -1.0000000000000999 which cannot be represented in target type `u128`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -1.0000000000000999f64 which cannot be represented in target type `u128`
    |
    = 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/fail/intrinsics/float_to_int_64_too_big1.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.stderr
index 42da33321f3..3122c83f970 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 2147483648 which cannot be represented in target type `i32`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 2147483648f64 which cannot be represented in target type `i32`
   --> $DIR/float_to_int_64_too_big1.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f64, i32>(2147483648.0f64);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 2147483648 which cannot be represented in target type `i32`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 2147483648f64 which cannot be represented in target type `i32`
    |
    = 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/fail/intrinsics/float_to_int_64_too_big2.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.stderr
index af4c4ceb3f7..8db497e2c00 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 9.2233720368547758E+18 which cannot be represented in target type `i64`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 9.2233720368547758E+18f64 which cannot be represented in target type `i64`
   --> $DIR/float_to_int_64_too_big2.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f64, i64>(9223372036854775808.0f64);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 9.2233720368547758E+18 which cannot be represented in target type `i64`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 9.2233720368547758E+18f64 which cannot be represented in target type `i64`
    |
    = 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/fail/intrinsics/float_to_int_64_too_big3.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.stderr
index 6e384a6fbc7..2a2de75f4bd 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 1.8446744073709552E+19 which cannot be represented in target type `u64`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 1.8446744073709552E+19f64 which cannot be represented in target type `u64`
   --> $DIR/float_to_int_64_too_big3.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f64, u64>(18446744073709551616.0f64);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 1.8446744073709552E+19 which cannot be represented in target type `u64`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 1.8446744073709552E+19f64 which cannot be represented in target type `u64`
    |
    = 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/fail/intrinsics/float_to_int_64_too_big4.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.stderr
index 77f05ff91e3..0e29fc7cd07 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 3.4028236692093846E+38 which cannot be represented in target type `u128`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 3.4028236692093846E+38f64 which cannot be represented in target type `u128`
   --> $DIR/float_to_int_64_too_big4.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f64, u128>(u128::MAX as f64);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 3.4028236692093846E+38 which cannot be represented in target type `u128`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 3.4028236692093846E+38f64 which cannot be represented in target type `u128`
    |
    = 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/fail/intrinsics/float_to_int_64_too_big5.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.stderr
index cb5eba490b4..d5d79d455f9 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 2.4028236692093845E+38 which cannot be represented in target type `i128`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 2.4028236692093845E+38f64 which cannot be represented in target type `i128`
   --> $DIR/float_to_int_64_too_big5.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f64, i128>(240282366920938463463374607431768211455.0f64);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 2.4028236692093845E+38 which cannot be represented in target type `i128`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 2.4028236692093845E+38f64 which cannot be represented in target type `i128`
    |
    = 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/fail/intrinsics/float_to_int_64_too_big6.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.stderr
index d899d2f808a..d7e87b62af0 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 1.7976931348623157E+308 which cannot be represented in target type `u128`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 1.7976931348623157E+308f64 which cannot be represented in target type `u128`
   --> $DIR/float_to_int_64_too_big6.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f64, u128>(f64::MAX);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 1.7976931348623157E+308 which cannot be represented in target type `u128`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 1.7976931348623157E+308f64 which cannot be represented in target type `u128`
    |
    = 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/fail/intrinsics/float_to_int_64_too_big7.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.stderr
index 443b2759c26..4e3751da9a3 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -1.7976931348623157E+308 which cannot be represented in target type `i128`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -1.7976931348623157E+308f64 which cannot be represented in target type `i128`
   --> $DIR/float_to_int_64_too_big7.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f64, i128>(f64::MIN);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -1.7976931348623157E+308 which cannot be represented in target type `i128`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -1.7976931348623157E+308f64 which cannot be represented in target type `i128`
    |
    = 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/fail/intrinsics/float_to_int_64_too_small1.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small1.stderr
index f8d88c44aa8..610702371d7 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small1.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small1.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -2147483649 which cannot be represented in target type `i32`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -2147483649f64 which cannot be represented in target type `i32`
   --> $DIR/float_to_int_64_too_small1.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f64, i32>(-2147483649.0f64);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -2147483649 which cannot be represented in target type `i32`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -2147483649f64 which cannot be represented in target type `i32`
    |
    = 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/fail/intrinsics/float_to_int_64_too_small2.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small2.stderr
index d94e57b1e67..e92655af2a8 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small2.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small2.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -9.2233720368547778E+18 which cannot be represented in target type `i64`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -9.2233720368547778E+18f64 which cannot be represented in target type `i64`
   --> $DIR/float_to_int_64_too_small2.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f64, i64>(-9223372036854777856.0f64);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -9.2233720368547778E+18 which cannot be represented in target type `i64`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -9.2233720368547778E+18f64 which cannot be represented in target type `i64`
    |
    = 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/fail/intrinsics/float_to_int_64_too_small3.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small3.stderr
index 59b74f5f51f..7d81945476f 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small3.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small3.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -2.4028236692093845E+38 which cannot be represented in target type `i128`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -2.4028236692093845E+38f64 which cannot be represented in target type `i128`
   --> $DIR/float_to_int_64_too_small3.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f64, i128>(-240282366920938463463374607431768211455.0f64);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -2.4028236692093845E+38 which cannot be represented in target type `i128`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -2.4028236692093845E+38f64 which cannot be represented in target type `i128`
    |
    = 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/fail/intrinsics/simd-float-to-int.stderr b/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.stderr
index 7b2387944af..df4792f8d80 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `simd_cast` intrinsic called on 3.40282347E+38 which cannot be represented in target type `i32`
+error: Undefined Behavior: `simd_cast` intrinsic called on 3.40282347E+38f32 which cannot be represented in target type `i32`
   --> $DIR/simd-float-to-int.rs:LL:CC
    |
 LL |         let _x: i32x2 = f32x2::from_array([f32::MAX, f32::MIN]).to_int_unchecked();
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `simd_cast` intrinsic called on 3.40282347E+38 which cannot be represented in target type `i32`
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `simd_cast` intrinsic called on 3.40282347E+38f32 which cannot be represented in target type `i32`
    |
    = 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

From c17444876bcc827e0e4223b193ea40a0f4253b21 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sat, 25 Nov 2023 08:00:32 +0100
Subject: [PATCH 13/22] Preparing for merge from rustc

---
 src/tools/miri/rust-version | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index ee27d8ed9a8..76ae9227983 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-360bafad68cfea2682cf016070e533c45a00150f
+34c5ab9aac327a8a18e18ea37a2468a320d82fb0

From 2df4fc0e8b6210b9f2807b26717000f3c69034a4 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sat, 25 Nov 2023 08:03:51 +0100
Subject: [PATCH 14/22] fmt

---
 src/tools/miri/src/provenance_gc.rs | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/src/tools/miri/src/provenance_gc.rs b/src/tools/miri/src/provenance_gc.rs
index b5106c22740..ab178f82d9f 100644
--- a/src/tools/miri/src/provenance_gc.rs
+++ b/src/tools/miri/src/provenance_gc.rs
@@ -194,10 +194,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
 
     fn remove_unreachable_allocs(&mut self, allocs: FxHashSet<AllocId>) {
         let this = self.eval_context_mut();
-        let allocs = LiveAllocs {
-            ecx: this,
-            collected: allocs,
-        };
+        let allocs = LiveAllocs { ecx: this, collected: allocs };
         this.machine.allocation_spans.borrow_mut().retain(|id, _| allocs.is_live(*id));
         this.machine.intptrcast.borrow_mut().remove_unreachable_allocs(&allocs);
         if let Some(borrow_tracker) = &this.machine.borrow_tracker {

From 34a8680cd50a20e5a2f5a7a6861d7c8b700dc3c6 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sat, 25 Nov 2023 08:27:42 +0100
Subject: [PATCH 15/22] bless

---
 .../miri/tests/fail-dep/shims/env-set_var-data-race.stderr      | 2 +-
 src/tools/miri/tests/fail/shims/intrinsic_target_feature.stderr | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/tools/miri/tests/fail-dep/shims/env-set_var-data-race.stderr b/src/tools/miri/tests/fail-dep/shims/env-set_var-data-race.stderr
index a202d7c6844..b81e8db9e0c 100644
--- a/src/tools/miri/tests/fail-dep/shims/env-set_var-data-race.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/env-set_var-data-race.stderr
@@ -16,5 +16,5 @@ LL |     env::set_var("MY_RUST_VAR", "Ferris");
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
 
-error: aborting due to previous error
+error: aborting due to 1 previous error
 
diff --git a/src/tools/miri/tests/fail/shims/intrinsic_target_feature.stderr b/src/tools/miri/tests/fail/shims/intrinsic_target_feature.stderr
index c034261338a..8e83d20854f 100644
--- a/src/tools/miri/tests/fail/shims/intrinsic_target_feature.stderr
+++ b/src/tools/miri/tests/fail/shims/intrinsic_target_feature.stderr
@@ -11,5 +11,5 @@ LL |         dpps(_mm_setzero_ps(), _mm_setzero_ps(), 0);
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
 
-error: aborting due to previous error
+error: aborting due to 1 previous error
 

From 69ea9520d3b7dee9df59128acec43f9b15aa3ee2 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sat, 25 Nov 2023 10:15:17 +0100
Subject: [PATCH 16/22] make tests/utils work with edition 2015

---
 src/tools/miri/tests/utils/mod.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/tools/miri/tests/utils/mod.rs b/src/tools/miri/tests/utils/mod.rs
index 3b817667f13..cb9380f5753 100644
--- a/src/tools/miri/tests/utils/mod.rs
+++ b/src/tools/miri/tests/utils/mod.rs
@@ -7,8 +7,8 @@ mod macros;
 mod fs;
 mod miri_extern;
 
-pub use fs::*;
-pub use miri_extern::*;
+pub use self::fs::*;
+pub use self::miri_extern::*;
 
 pub fn run_provenance_gc() {
     // SAFETY: No preconditions. The GC is fine to run at any time.

From ce94b22cd6130a560155f02b8634f117f7fd36c6 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sat, 25 Nov 2023 10:29:22 +0100
Subject: [PATCH 17/22] read off_t at the right size for the current target

---
 src/tools/miri/src/shims/unix/foreign_items.rs | 4 ++--
 src/tools/miri/src/shims/unix/fs.rs            | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs
index c1c3e3fa10c..23342c8045e 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -163,14 +163,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
                 let length = this.read_scalar(length)?.to_i64()?;
-                let result = this.ftruncate64(fd, length)?;
+                let result = this.ftruncate64(fd, length.into())?;
                 this.write_scalar(result, dest)?;
             }
             "ftruncate" => {
                 let [fd, length] =
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
-                let length = this.read_target_isize(length)?;
+                let length = this.read_scalar(length)?.to_int(this.libc_ty_layout("off_t").size)?;
                 let result = this.ftruncate64(fd, length)?;
                 this.write_scalar(result, dest)?;
             }
diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs
index d545cb46069..ba40a1b3c32 100644
--- a/src/tools/miri/src/shims/unix/fs.rs
+++ b/src/tools/miri/src/shims/unix/fs.rs
@@ -1504,7 +1504,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         }
     }
 
-    fn ftruncate64(&mut self, fd: i32, length: i64) -> InterpResult<'tcx, Scalar<Provenance>> {
+    fn ftruncate64(&mut self, fd: i32, length: i128) -> InterpResult<'tcx, Scalar<Provenance>> {
         let this = self.eval_context_mut();
 
         // Reject if isolation is enabled.

From b750b5495821063f0746ad0c516f65b17cc6ff51 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sat, 25 Nov 2023 10:29:31 +0100
Subject: [PATCH 18/22] run tests on 32bit freebsd

---
 src/tools/miri/ci.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/tools/miri/ci.sh b/src/tools/miri/ci.sh
index 378d7744cf2..b8f90b8df6c 100755
--- a/src/tools/miri/ci.sh
+++ b/src/tools/miri/ci.sh
@@ -109,6 +109,7 @@ case $HOST_TARGET in
     MIRI_TEST_TARGET=aarch64-apple-darwin run_tests
     MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests
     MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthread-threadname libc-getentropy libc-getrandom libc-misc libc-fs atomic env align
+    MIRI_TEST_TARGET=i686-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthread-threadname libc-getentropy libc-getrandom libc-misc libc-fs atomic env align
     MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal hello integer vec panic/panic
     MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings wasm
     MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings wasm

From 2a89b74bc75d1b30f5e71091cc66fc9f5789d69a Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sat, 25 Nov 2023 10:11:05 +0100
Subject: [PATCH 19/22] run the provenance-gc=1 test on all targets, but only
 for some of the tests

before: only on Linux host, all tests
after: only the test suite itself (not cargo-miri or the mir-opt-level=4 run),
on all hosts for the host target and on Linux for all "full" targets.
---
 src/tools/miri/.github/workflows/ci.yml |  4 ----
 src/tools/miri/ci.sh                    | 17 ++++++++++++-----
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/src/tools/miri/.github/workflows/ci.yml b/src/tools/miri/.github/workflows/ci.yml
index 554a12909fc..dec85e9232f 100644
--- a/src/tools/miri/.github/workflows/ci.yml
+++ b/src/tools/miri/.github/workflows/ci.yml
@@ -35,10 +35,6 @@ jobs:
     steps:
       - uses: actions/checkout@v3
 
-      - name: Set the tag GC interval to 1 on linux
-        if: runner.os == 'Linux'
-        run: echo "MIRIFLAGS=-Zmiri-provenance-gc=1" >> $GITHUB_ENV
-
       # Cache the global cargo directory, but NOT the local `target` directory which
       # we cannot reuse anyway when the nightly changes (and it grows quite large
       # over time).
diff --git a/src/tools/miri/ci.sh b/src/tools/miri/ci.sh
index 378d7744cf2..0492953671e 100755
--- a/src/tools/miri/ci.sh
+++ b/src/tools/miri/ci.sh
@@ -30,16 +30,23 @@ endgroup
 
 # Test
 function run_tests {
-  if [ -n "${MIRI_TEST_TARGET+exists}" ]; then
+  if [ -n "${MIRI_TEST_TARGET:-}" ]; then
     begingroup "Testing foreign architecture $MIRI_TEST_TARGET"
   else
     begingroup "Testing host architecture"
   fi
 
   ## ui test suite
-  ./miri test
-  if [ -z "${MIRI_TEST_TARGET+exists}" ]; then
-    # Host-only tests: running these on all targets is unlikely to catch more problems and would
+  # On the host and on Linux, also stress-test the GC.
+  if [ -z "${MIRI_TEST_TARGET:-}" ] || [ "$HOST_TARGET" = x86_64-unknown-linux-gnu ]; then
+    MIRIFLAGS="${MIRIFLAGS:-} -Zmiri-provenance-gc=1" ./miri test
+  else
+    ./miri test
+  fi
+
+  # Host-only tests
+  if [ -z "${MIRI_TEST_TARGET:-}" ]; then
+    # Running these on all targets is unlikely to catch more problems and would
     # cost a lot of CI time.
 
     # Tests with optimizations (`-O` is what cargo passes, but crank MIR optimizations up all the
@@ -85,7 +92,7 @@ function run_tests {
 }
 
 function run_tests_minimal {
-  if [ -n "${MIRI_TEST_TARGET+exists}" ]; then
+  if [ -n "${MIRI_TEST_TARGET:-}" ]; then
     begingroup "Testing MINIMAL foreign architecture $MIRI_TEST_TARGET: only testing $@"
   else
     begingroup "Testing MINIMAL host architecture: only testing $@"

From 695f1a515e532e079545982b63906233879959f4 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sat, 25 Nov 2023 13:09:35 +0100
Subject: [PATCH 20/22] tweak ci.sh

---
 src/tools/miri/ci.sh | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/tools/miri/ci.sh b/src/tools/miri/ci.sh
index 0492953671e..34892489c80 100755
--- a/src/tools/miri/ci.sh
+++ b/src/tools/miri/ci.sh
@@ -95,7 +95,8 @@ function run_tests_minimal {
   if [ -n "${MIRI_TEST_TARGET:-}" ]; then
     begingroup "Testing MINIMAL foreign architecture $MIRI_TEST_TARGET: only testing $@"
   else
-    begingroup "Testing MINIMAL host architecture: only testing $@"
+    echo "run_tests_minimal requires MIRI_TEST_TARGET to be set"
+    exit 1
   fi
 
   ./miri test -- "$@"
@@ -106,15 +107,20 @@ function run_tests_minimal {
   endgroup
 }
 
-# host
+## Main Testing Logic ##
+
+# Host target.
 run_tests
 
+# Extra targets.
+# In particular, fully cover all tier 1 targets.
 case $HOST_TARGET in
   x86_64-unknown-linux-gnu)
     MIRI_TEST_TARGET=i686-unknown-linux-gnu run_tests
     MIRI_TEST_TARGET=aarch64-unknown-linux-gnu run_tests
     MIRI_TEST_TARGET=aarch64-apple-darwin run_tests
     MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests
+    # Some targets are only partially supported.
     MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthread-threadname libc-getentropy libc-getrandom libc-misc libc-fs atomic env align
     MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal hello integer vec panic/panic
     MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings wasm

From 2f825fb3d45c622fa7bc0d453fd13773c4f8a199 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sat, 25 Nov 2023 14:19:37 +0100
Subject: [PATCH 21/22] Preparing for merge from rustc

---
 src/tools/miri/rust-version | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 76ae9227983..ecebb8a331b 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-34c5ab9aac327a8a18e18ea37a2468a320d82fb0
+3668a8af1b81447c4afa1f82f60d7b94b71a549f

From feb37829e152e0880dffa337e4897f75ca35eb84 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sat, 25 Nov 2023 14:26:00 +0100
Subject: [PATCH 22/22] bless

---
 .../miri/tests/fail/intrinsics/float_to_int_32_inf1.stderr    | 4 ++--
 .../miri/tests/fail/intrinsics/float_to_int_32_infneg1.stderr | 4 ++--
 .../miri/tests/fail/intrinsics/float_to_int_32_nan.stderr     | 4 ++--
 .../miri/tests/fail/intrinsics/float_to_int_32_nanneg.stderr  | 4 ++--
 .../miri/tests/fail/intrinsics/float_to_int_64_inf1.stderr    | 4 ++--
 .../miri/tests/fail/intrinsics/float_to_int_64_infneg1.stderr | 4 ++--
 .../miri/tests/fail/intrinsics/float_to_int_64_infneg2.stderr | 4 ++--
 .../miri/tests/fail/intrinsics/float_to_int_64_nan.stderr     | 4 ++--
 8 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.stderr
index 9ed527d850d..2de8f3420b7 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on +Inff32 which cannot be represented in target type `i32`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on +Inf_f32 which cannot be represented in target type `i32`
   --> $DIR/float_to_int_32_inf1.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f32, i32>(f32::INFINITY);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on +Inff32 which cannot be represented in target type `i32`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on +Inf_f32 which cannot be represented in target type `i32`
    |
    = 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/fail/intrinsics/float_to_int_32_infneg1.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.stderr
index d1aaaf26a30..53ed208bdee 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -Inff32 which cannot be represented in target type `i32`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -Inf_f32 which cannot be represented in target type `i32`
   --> $DIR/float_to_int_32_infneg1.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f32, i32>(f32::NEG_INFINITY);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -Inff32 which cannot be represented in target type `i32`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -Inf_f32 which cannot be represented in target type `i32`
    |
    = 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/fail/intrinsics/float_to_int_32_nan.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.stderr
index bd00f00e70a..afda7124c11 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on NaNf32 which cannot be represented in target type `u32`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on NaN_f32 which cannot be represented in target type `u32`
   --> $DIR/float_to_int_32_nan.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f32, u32>(f32::NAN);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on NaNf32 which cannot be represented in target type `u32`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on NaN_f32 which cannot be represented in target type `u32`
    |
    = 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/fail/intrinsics/float_to_int_32_nanneg.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.stderr
index ab717efbfe0..8ba46de8641 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on NaNf32 which cannot be represented in target type `u32`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on NaN_f32 which cannot be represented in target type `u32`
   --> $DIR/float_to_int_32_nanneg.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f32, u32>(-f32::NAN);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on NaNf32 which cannot be represented in target type `u32`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on NaN_f32 which cannot be represented in target type `u32`
    |
    = 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/fail/intrinsics/float_to_int_64_inf1.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.stderr
index c68fd64f62a..5db9fb1417c 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on +Inff64 which cannot be represented in target type `u128`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on +Inf_f64 which cannot be represented in target type `u128`
   --> $DIR/float_to_int_64_inf1.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f64, u128>(f64::INFINITY);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on +Inff64 which cannot be represented in target type `u128`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on +Inf_f64 which cannot be represented in target type `u128`
    |
    = 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/fail/intrinsics/float_to_int_64_infneg1.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.stderr
index 83b6c04bb1d..3e8dadb79e4 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -Inff64 which cannot be represented in target type `u128`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -Inf_f64 which cannot be represented in target type `u128`
   --> $DIR/float_to_int_64_infneg1.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f64, u128>(f64::NEG_INFINITY);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -Inff64 which cannot be represented in target type `u128`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -Inf_f64 which cannot be represented in target type `u128`
    |
    = 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/fail/intrinsics/float_to_int_64_infneg2.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.stderr
index b7bfe1f7dd9..cb59974bf45 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -Inff64 which cannot be represented in target type `i128`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -Inf_f64 which cannot be represented in target type `i128`
   --> $DIR/float_to_int_64_infneg2.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f64, i128>(f64::NEG_INFINITY);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -Inff64 which cannot be represented in target type `i128`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -Inf_f64 which cannot be represented in target type `i128`
    |
    = 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/fail/intrinsics/float_to_int_64_nan.stderr b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.stderr
index 1df594bce43..68697060515 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on NaNf64 which cannot be represented in target type `u32`
+error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on NaN_f64 which cannot be represented in target type `u32`
   --> $DIR/float_to_int_64_nan.rs:LL:CC
    |
 LL |         float_to_int_unchecked::<f64, u32>(f64::NAN);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on NaNf64 which cannot be represented in target type `u32`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on NaN_f64 which cannot be represented in target type `u32`
    |
    = 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