From b208706b6e2d7b2a218347e4311a05fe3a022d52 Mon Sep 17 00:00:00 2001
From: Chayim Refael Friedman <chayimfr@gmail.com>
Date: Sat, 16 Nov 2024 22:23:19 +0200
Subject: [PATCH 01/14] Add `DerefMut` for `Lazy[Cell/Lock]` that delegates to
 the unstable `force_mut()`

---
 library/core/src/cell/lazy.rs     | 10 +++++++++-
 library/std/src/sync/lazy_lock.rs | 10 +++++++++-
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs
index 5ac33516684d7..c9c4a6d311192 100644
--- a/library/core/src/cell/lazy.rs
+++ b/library/core/src/cell/lazy.rs
@@ -1,6 +1,6 @@
 use super::UnsafeCell;
 use crate::hint::unreachable_unchecked;
-use crate::ops::Deref;
+use crate::ops::{Deref, DerefMut};
 use crate::{fmt, mem};
 
 enum State<T, F> {
@@ -284,6 +284,14 @@ impl<T, F: FnOnce() -> T> Deref for LazyCell<T, F> {
     }
 }
 
+#[stable(feature = "lazy_deref_mut", since = "CURRENT_RUSTC_VERSION")]
+impl<T, F: FnOnce() -> T> DerefMut for LazyCell<T, F> {
+    #[inline]
+    fn deref_mut(&mut self) -> &mut T {
+        LazyCell::force_mut(self)
+    }
+}
+
 #[stable(feature = "lazy_cell", since = "1.80.0")]
 impl<T: Default> Default for LazyCell<T> {
     /// Creates a new lazy value using `Default` as the initializing function.
diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs
index 40510f5613450..4379a1519c6bc 100644
--- a/library/std/src/sync/lazy_lock.rs
+++ b/library/std/src/sync/lazy_lock.rs
@@ -1,7 +1,7 @@
 use super::once::ExclusiveState;
 use crate::cell::UnsafeCell;
 use crate::mem::ManuallyDrop;
-use crate::ops::Deref;
+use crate::ops::{Deref, DerefMut};
 use crate::panic::{RefUnwindSafe, UnwindSafe};
 use crate::sync::Once;
 use crate::{fmt, ptr};
@@ -312,6 +312,14 @@ impl<T, F: FnOnce() -> T> Deref for LazyLock<T, F> {
     }
 }
 
+#[stable(feature = "lazy_deref_mut", since = "CURRENT_RUSTC_VERSION")]
+impl<T, F: FnOnce() -> T> DerefMut for LazyLock<T, F> {
+    #[inline]
+    fn deref_mut(&mut self) -> &mut T {
+        LazyLock::force_mut(self)
+    }
+}
+
 #[stable(feature = "lazy_cell", since = "1.80.0")]
 impl<T: Default> Default for LazyLock<T> {
     /// Creates a new lazy value using `Default` as the initializing function.

From e7efab9ec95449d6565fec41d94c69abf5d3088a Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 22 Apr 2025 09:37:46 +0200
Subject: [PATCH 02/14] remove intrinsics::drop_in_place

---
 library/core/src/intrinsics/mod.rs                   |  9 ---------
 .../inline/inline_shims.drop.Inline.panic-abort.diff | 10 +++++-----
 .../inline_shims.drop.Inline.panic-unwind.diff       |  6 +++---
 tests/mir-opt/inline/inline_shims.rs                 |  2 +-
 ....Test.SimplifyCfg-make_shim.after.panic-abort.mir |  4 ++--
 ...Test.SimplifyCfg-make_shim.after.panic-unwind.mir |  4 ++--
 ...ace.[String;42].AddMovesForPackedDrops.before.mir |  4 ++--
 ..._place.[String].AddMovesForPackedDrops.before.mir |  4 ++--
 ..._place.Vec_i32_.AddMovesForPackedDrops.before.mir |  4 ++--
 tests/ui/consts/miri_unleashed/assoc_const.stderr    |  6 +++---
 tests/ui/consts/miri_unleashed/drop.rs               |  2 +-
 tests/ui/consts/miri_unleashed/drop.stderr           |  2 +-
 tests/ui/consts/qualif-indirect-mutation-fail.stderr | 12 ++++++------
 .../issue-99286-stable-intrinsics.rs                 |  3 +--
 14 files changed, 31 insertions(+), 41 deletions(-)

diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index a01efb2adebe3..7e052865046bd 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -74,15 +74,6 @@ pub mod simd;
 #[cfg(all(target_has_atomic = "8", target_has_atomic = "32", target_has_atomic = "ptr"))]
 use crate::sync::atomic::{self, AtomicBool, AtomicI32, AtomicIsize, AtomicU32, Ordering};
 
-#[stable(feature = "drop_in_place", since = "1.8.0")]
-#[rustc_allowed_through_unstable_modules = "import this function via `std::ptr` instead"]
-#[deprecated(note = "no longer an intrinsic - use `ptr::drop_in_place` directly", since = "1.52.0")]
-#[inline]
-pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
-    // SAFETY: see `ptr::drop_in_place`
-    unsafe { crate::ptr::drop_in_place(to_drop) }
-}
-
 // N.B., these intrinsics take raw pointers because they mutate aliased
 // memory, which is not valid for either `&` or `&mut`.
 
diff --git a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff
index 4337e0da18336..f6c111a2228a9 100644
--- a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff
@@ -8,7 +8,7 @@
       let _3: ();
       let mut _4: *mut std::vec::Vec<A>;
       let mut _5: *mut std::option::Option<B>;
-+     scope 1 (inlined std::ptr::drop_in_place::<Vec<A>> - shim(Some(Vec<A>))) {
++     scope 1 (inlined drop_in_place::<Vec<A>> - shim(Some(Vec<A>))) {
 +         let mut _6: &mut std::vec::Vec<A>;
 +         let mut _7: ();
 +         scope 2 (inlined <Vec<A> as Drop>::drop) {
@@ -38,14 +38,14 @@
 +                 scope 13 (inlined std::ptr::from_raw_parts_mut::<[A], A>) {
 +                 }
 +             }
-+             scope 14 (inlined std::ptr::drop_in_place::<[A]> - shim(Some([A]))) {
++             scope 14 (inlined drop_in_place::<[A]> - shim(Some([A]))) {
 +                 let mut _12: usize;
 +                 let mut _13: *mut A;
 +                 let mut _14: bool;
 +             }
 +         }
 +     }
-+     scope 15 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
++     scope 15 (inlined drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
 +         let mut _15: isize;
 +         let mut _16: isize;
 +     }
@@ -54,7 +54,7 @@
           StorageLive(_3);
           StorageLive(_4);
           _4 = copy _1;
--         _3 = std::ptr::drop_in_place::<Vec<A>>(move _4) -> [return: bb1, unwind unreachable];
+-         _3 = drop_in_place::<Vec<A>>(move _4) -> [return: bb1, unwind unreachable];
 +         StorageLive(_6);
 +         StorageLive(_7);
 +         _6 = &mut (*_4);
@@ -82,7 +82,7 @@
           StorageDead(_3);
           StorageLive(_5);
           _5 = copy _2;
--         _0 = std::ptr::drop_in_place::<Option<B>>(move _5) -> [return: bb2, unwind unreachable];
+-         _0 = drop_in_place::<Option<B>>(move _5) -> [return: bb2, unwind unreachable];
 +         StorageLive(_15);
 +         StorageLive(_16);
 +         _15 = discriminant((*_5));
diff --git a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff
index d89ca003d77b3..1832427642528 100644
--- a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff
@@ -8,7 +8,7 @@
       let _3: ();
       let mut _4: *mut std::vec::Vec<A>;
       let mut _5: *mut std::option::Option<B>;
-+     scope 1 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
++     scope 1 (inlined drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
 +         let mut _6: isize;
 +         let mut _7: isize;
 +     }
@@ -17,7 +17,7 @@
           StorageLive(_3);
           StorageLive(_4);
           _4 = copy _1;
-          _3 = std::ptr::drop_in_place::<Vec<A>>(move _4) -> [return: bb1, unwind continue];
+          _3 = drop_in_place::<Vec<A>>(move _4) -> [return: bb1, unwind continue];
       }
   
       bb1: {
@@ -25,7 +25,7 @@
           StorageDead(_3);
           StorageLive(_5);
           _5 = copy _2;
--         _0 = std::ptr::drop_in_place::<Option<B>>(move _5) -> [return: bb2, unwind continue];
+-         _0 = drop_in_place::<Option<B>>(move _5) -> [return: bb2, unwind continue];
 +         StorageLive(_6);
 +         StorageLive(_7);
 +         _6 = discriminant((*_5));
diff --git a/tests/mir-opt/inline/inline_shims.rs b/tests/mir-opt/inline/inline_shims.rs
index a223c2d2614b1..bd6cdd78157c2 100644
--- a/tests/mir-opt/inline/inline_shims.rs
+++ b/tests/mir-opt/inline/inline_shims.rs
@@ -11,7 +11,7 @@ pub fn clone<A, B>(f: fn(A, B)) -> fn(A, B) {
 // EMIT_MIR inline_shims.drop.Inline.diff
 pub fn drop<A, B>(a: *mut Vec<A>, b: *mut Option<B>) {
     // CHECK-LABEL: fn drop(
-    // CHECK: (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>)))
+    // CHECK: (inlined drop_in_place::<Option<B>> - shim(Some(Option<B>)))
     unsafe { std::ptr::drop_in_place(a) }
     unsafe { std::ptr::drop_in_place(b) }
 }
diff --git a/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-abort.mir b/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-abort.mir
index 146f4240f308a..7be3ab8cbae92 100644
--- a/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-abort.mir
+++ b/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-abort.mir
@@ -1,6 +1,6 @@
-// MIR for `std::ptr::drop_in_place` after SimplifyCfg-make_shim
+// MIR for `drop_in_place` after SimplifyCfg-make_shim
 
-fn std::ptr::drop_in_place(_1: *mut Test) -> () {
+fn drop_in_place(_1: *mut Test) -> () {
     let mut _0: ();
     let mut _2: &mut Test;
     let mut _3: &mut Test;
diff --git a/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-unwind.mir b/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-unwind.mir
index 70c53bafa3737..6c3c1aaa2bd2b 100644
--- a/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-unwind.mir
+++ b/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-unwind.mir
@@ -1,6 +1,6 @@
-// MIR for `std::ptr::drop_in_place` after SimplifyCfg-make_shim
+// MIR for `drop_in_place` after SimplifyCfg-make_shim
 
-fn std::ptr::drop_in_place(_1: *mut Test) -> () {
+fn drop_in_place(_1: *mut Test) -> () {
     let mut _0: ();
     let mut _2: &mut Test;
     let mut _3: &mut Test;
diff --git a/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String;42].AddMovesForPackedDrops.before.mir b/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String;42].AddMovesForPackedDrops.before.mir
index 13df2195ab04d..9d5af8e84e4f1 100644
--- a/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String;42].AddMovesForPackedDrops.before.mir
+++ b/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String;42].AddMovesForPackedDrops.before.mir
@@ -1,6 +1,6 @@
-// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops
+// MIR for `drop_in_place` before AddMovesForPackedDrops
 
-fn std::ptr::drop_in_place(_1: *mut [String; 42]) -> () {
+fn drop_in_place(_1: *mut [String; 42]) -> () {
     let mut _0: ();
     let mut _2: *mut [std::string::String; 42];
     let mut _3: *mut [std::string::String];
diff --git a/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir b/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir
index 0633b765644d5..144880d15989c 100644
--- a/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir
+++ b/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir
@@ -1,6 +1,6 @@
-// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops
+// MIR for `drop_in_place` before AddMovesForPackedDrops
 
-fn std::ptr::drop_in_place(_1: *mut [String]) -> () {
+fn drop_in_place(_1: *mut [String]) -> () {
     let mut _0: ();
     let mut _2: usize;
     let mut _3: usize;
diff --git a/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir b/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir
index b587941835515..51ef9f7c068ec 100644
--- a/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir
+++ b/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir
@@ -1,6 +1,6 @@
-// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops
+// MIR for `drop_in_place` before AddMovesForPackedDrops
 
-fn std::ptr::drop_in_place(_1: *mut Vec<i32>) -> () {
+fn drop_in_place(_1: *mut Vec<i32>) -> () {
     let mut _0: ();
     let mut _2: &mut std::vec::Vec<i32>;
     let mut _3: ();
diff --git a/tests/ui/consts/miri_unleashed/assoc_const.stderr b/tests/ui/consts/miri_unleashed/assoc_const.stderr
index f259765f6e57a..758f1a2533990 100644
--- a/tests/ui/consts/miri_unleashed/assoc_const.stderr
+++ b/tests/ui/consts/miri_unleashed/assoc_const.stderr
@@ -1,12 +1,12 @@
-error[E0080]: evaluation of `std::ptr::drop_in_place::<Vec<u32>> - shim(Some(Vec<u32>))` failed
+error[E0080]: evaluation of `drop_in_place::<Vec<u32>> - shim(Some(Vec<u32>))` failed
   --> $DIR/assoc_const.rs:12:31
    |
 LL |     const F: u32 = (U::X, 42).1;
    |                               ^ calling non-const function `<Vec<u32> as Drop>::drop`
    |
-note: inside `std::ptr::drop_in_place::<(Vec<u32>, u32)> - shim(Some((Vec<u32>, u32)))`
+note: inside `drop_in_place::<(Vec<u32>, u32)> - shim(Some((Vec<u32>, u32)))`
   --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-note: inside `std::ptr::drop_in_place::<Vec<u32>> - shim(Some(Vec<u32>))`
+note: inside `drop_in_place::<Vec<u32>> - shim(Some(Vec<u32>))`
   --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
 
 note: erroneous constant encountered
diff --git a/tests/ui/consts/miri_unleashed/drop.rs b/tests/ui/consts/miri_unleashed/drop.rs
index 190072d9c2062..ff9281358d4b3 100644
--- a/tests/ui/consts/miri_unleashed/drop.rs
+++ b/tests/ui/consts/miri_unleashed/drop.rs
@@ -15,6 +15,6 @@ static TEST_BAD: () = {
     let _v: Vec<i32> = Vec::new();
 }; //~ ERROR could not evaluate static initializer
    //~| NOTE calling non-const function `<Vec<i32> as Drop>::drop`
-   //~| NOTE inside `std::ptr::drop_in_place::<Vec<i32>> - shim(Some(Vec<i32>))`
+   //~| NOTE inside `drop_in_place::<Vec<i32>> - shim(Some(Vec<i32>))`
 
 //~? WARN skipping const checks
diff --git a/tests/ui/consts/miri_unleashed/drop.stderr b/tests/ui/consts/miri_unleashed/drop.stderr
index f9ff5491ea6c0..0286c43127945 100644
--- a/tests/ui/consts/miri_unleashed/drop.stderr
+++ b/tests/ui/consts/miri_unleashed/drop.stderr
@@ -4,7 +4,7 @@ error[E0080]: could not evaluate static initializer
 LL | };
    | ^ calling non-const function `<Vec<i32> as Drop>::drop`
    |
-note: inside `std::ptr::drop_in_place::<Vec<i32>> - shim(Some(Vec<i32>))`
+note: inside `drop_in_place::<Vec<i32>> - shim(Some(Vec<i32>))`
   --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
 
 warning: skipping const checks
diff --git a/tests/ui/consts/qualif-indirect-mutation-fail.stderr b/tests/ui/consts/qualif-indirect-mutation-fail.stderr
index d3bb01af7547e..dd575e07c2013 100644
--- a/tests/ui/consts/qualif-indirect-mutation-fail.stderr
+++ b/tests/ui/consts/qualif-indirect-mutation-fail.stderr
@@ -13,11 +13,11 @@ error[E0080]: evaluation of constant value failed
 LL | };
    | ^ calling non-const function `<Vec<u8> as Drop>::drop`
    |
-note: inside `std::ptr::drop_in_place::<Option<String>> - shim(Some(Option<String>))`
+note: inside `drop_in_place::<Option<String>> - shim(Some(Option<String>))`
   --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-note: inside `std::ptr::drop_in_place::<String> - shim(Some(String))`
+note: inside `drop_in_place::<String> - shim(Some(String))`
   --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-note: inside `std::ptr::drop_in_place::<Vec<u8>> - shim(Some(Vec<u8>))`
+note: inside `drop_in_place::<Vec<u8>> - shim(Some(Vec<u8>))`
   --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
 
 error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time
@@ -34,11 +34,11 @@ error[E0080]: evaluation of constant value failed
 LL | };
    | ^ calling non-const function `<Vec<u8> as Drop>::drop`
    |
-note: inside `std::ptr::drop_in_place::<Option<String>> - shim(Some(Option<String>))`
+note: inside `drop_in_place::<Option<String>> - shim(Some(Option<String>))`
   --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-note: inside `std::ptr::drop_in_place::<String> - shim(Some(String))`
+note: inside `drop_in_place::<String> - shim(Some(String))`
   --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-note: inside `std::ptr::drop_in_place::<Vec<u8>> - shim(Some(Vec<u8>))`
+note: inside `drop_in_place::<Vec<u8>> - shim(Some(Vec<u8>))`
   --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
 
 error[E0493]: destructor of `(u32, Option<String>)` cannot be evaluated at compile-time
diff --git a/tests/ui/stability-attribute/issue-99286-stable-intrinsics.rs b/tests/ui/stability-attribute/issue-99286-stable-intrinsics.rs
index b76603740ff9b..d9e810362f2e9 100644
--- a/tests/ui/stability-attribute/issue-99286-stable-intrinsics.rs
+++ b/tests/ui/stability-attribute/issue-99286-stable-intrinsics.rs
@@ -8,10 +8,9 @@
 #![allow(unused_imports)]
 #![allow(deprecated)]
 
-use std::intrinsics::drop_in_place as _;
 use std::intrinsics::copy_nonoverlapping as _;
 use std::intrinsics::copy as _;
 use std::intrinsics::write_bytes as _;
-use std::intrinsics::{drop_in_place, copy_nonoverlapping, copy, write_bytes};
+use std::intrinsics::{copy_nonoverlapping, copy, write_bytes};
 
 fn main() {}

From ca42f15f96ea966b7eb15e75dbdf0702d352ebcf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Kr=C3=B6ning?=
 <martin.kroening@eonerc.rwth-aachen.de>
Date: Wed, 7 May 2025 15:40:02 +0200
Subject: [PATCH 03/14] update hermit-abi to 0.5.1

---
 library/Cargo.lock | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/library/Cargo.lock b/library/Cargo.lock
index 5100b4d8176dc..93e9a8b7e8b4a 100644
--- a/library/Cargo.lock
+++ b/library/Cargo.lock
@@ -139,9 +139,9 @@ dependencies = [
 
 [[package]]
 name = "hermit-abi"
-version = "0.5.0"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e"
+checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08"
 dependencies = [
  "compiler_builtins",
  "rustc-std-workspace-alloc",

From ae25c39f2216ea1f6f062faac71761cd3f1bdd16 Mon Sep 17 00:00:00 2001
From: Luca Versari <veluca93@gmail.com>
Date: Thu, 8 May 2025 09:33:38 +0200
Subject: [PATCH 04/14] Update documentation of OnceLock::get_or_init.

Explicitly point out that if the function panics the init function might
be called multiple times.
---
 library/std/src/sync/once_lock.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs
index ffb90b1469584..324b5451873bf 100644
--- a/library/std/src/sync/once_lock.rs
+++ b/library/std/src/sync/once_lock.rs
@@ -279,7 +279,7 @@ impl<T> OnceLock<T> {
     ///
     /// Many threads may call `get_or_init` concurrently with different
     /// initializing functions, but it is guaranteed that only one function
-    /// will be executed.
+    /// will be executed if the function doesn't panic.
     ///
     /// # Panics
     ///

From 72393a672d5ffc6f02bd10d71c37715bded3dbfd Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui@loongson.cn>
Date: Tue, 18 Mar 2025 13:37:40 +0800
Subject: [PATCH 05/14] Partially stabilize LoongArch target features

---
 compiler/rustc_target/src/target_features.rs | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index 5a21925ba04e7..5428aa4cf7085 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -693,17 +693,17 @@ static CSKY_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
 
 static LOONGARCH_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     // tidy-alphabetical-start
-    ("d", Unstable(sym::loongarch_target_feature), &["f"]),
+    ("d", Stable, &["f"]),
     ("div32", Unstable(sym::loongarch_target_feature), &[]),
-    ("f", Unstable(sym::loongarch_target_feature), &[]),
-    ("frecipe", Unstable(sym::loongarch_target_feature), &[]),
+    ("f", Stable, &[]),
+    ("frecipe", Stable, &[]),
     ("lam-bh", Unstable(sym::loongarch_target_feature), &[]),
     ("lamcas", Unstable(sym::loongarch_target_feature), &[]),
-    ("lasx", Unstable(sym::loongarch_target_feature), &["lsx"]),
-    ("lbt", Unstable(sym::loongarch_target_feature), &[]),
+    ("lasx", Stable, &["lsx"]),
+    ("lbt", Stable, &[]),
     ("ld-seq-sa", Unstable(sym::loongarch_target_feature), &[]),
-    ("lsx", Unstable(sym::loongarch_target_feature), &["d"]),
-    ("lvz", Unstable(sym::loongarch_target_feature), &[]),
+    ("lsx", Stable, &["d"]),
+    ("lvz", Stable, &[]),
     ("relax", Unstable(sym::loongarch_target_feature), &[]),
     ("scq", Unstable(sym::loongarch_target_feature), &[]),
     ("ual", Unstable(sym::loongarch_target_feature), &[]),

From 4a662c25dc0715a2ab5ef91dfb8cb869d1ae0d7c Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui@loongson.cn>
Date: Fri, 9 May 2025 11:26:08 +0800
Subject: [PATCH 06/14] Update target feature tests

---
 ...bi-required-target-feature-flag-disable.loongarch.stderr | 6 +-----
 .../abi-required-target-feature-flag-disable.rs             | 2 +-
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/tests/ui/target-feature/abi-required-target-feature-flag-disable.loongarch.stderr b/tests/ui/target-feature/abi-required-target-feature-flag-disable.loongarch.stderr
index 35102e0571f43..a69544a34c9af 100644
--- a/tests/ui/target-feature/abi-required-target-feature-flag-disable.loongarch.stderr
+++ b/tests/ui/target-feature/abi-required-target-feature-flag-disable.loongarch.stderr
@@ -3,9 +3,5 @@ warning: target feature `d` must be enabled to ensure that the ABI of the curren
    = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
 
-warning: unstable feature specified for `-Ctarget-feature`: `d`
-   |
-   = note: this feature is not stably supported; its behavior can change in the future
-
-warning: 2 warnings emitted
+warning: 1 warning emitted
 
diff --git a/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs b/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs
index c3ce05baa64b9..98723e99c36e3 100644
--- a/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs
+++ b/tests/ui/target-feature/abi-required-target-feature-flag-disable.rs
@@ -24,4 +24,4 @@
 pub trait Sized {}
 
 //~? WARN must be enabled to ensure that the ABI of the current target can be implemented correctly
-//[x86,riscv,loongarch]~? WARN unstable feature specified for `-Ctarget-feature`
+//[x86,riscv]~? WARN unstable feature specified for `-Ctarget-feature`

From f04eb8ced394b3665d66ab22b899d885e10e1947 Mon Sep 17 00:00:00 2001
From: Andrew Zhogin <andrew.zhogin@gmail.com>
Date: Thu, 20 Mar 2025 12:43:44 +0700
Subject: [PATCH 07/14] -Zsanitize and -Zsanitizer-cfi-normalize-integers flags
 are now target modifiers with custom consistency check function

---
 compiler/rustc_metadata/src/creader.rs        | 18 +++--
 compiler/rustc_session/src/options.rs         | 71 ++++++++++++++++++-
 tests/codegen/naked-asan.rs                   |  2 +
 .../address-sanitizer-globals-tracking.rs     |  1 +
 .../cfi/add-canonical-jump-tables-flag.rs     |  2 +
 .../cfi/add-cfi-normalize-integers-flag.rs    |  2 +
 .../cfi/add-enable-split-lto-unit-flag.rs     |  1 +
 .../cfi/dbg-location-on-cfi-blocks.rs         |  1 +
 .../cfi/emit-type-checks-attr-no-sanitize.rs  |  1 +
 .../codegen/sanitizer/cfi/emit-type-checks.rs |  1 +
 .../emit-type-metadata-attr-cfi-encoding.rs   |  1 +
 ...adata-id-itanium-cxx-abi-const-generics.rs |  1 +
 ...tadata-id-itanium-cxx-abi-drop-in-place.rs |  1 +
 ...adata-id-itanium-cxx-abi-function-types.rs |  1 +
 ...e-metadata-id-itanium-cxx-abi-lifetimes.rs |  1 +
 ...itanium-cxx-abi-method-secondary-typeid.rs |  1 +
 ...-type-metadata-id-itanium-cxx-abi-paths.rs |  1 +
 ...tadata-id-itanium-cxx-abi-pointer-types.rs |  1 +
 ...data-id-itanium-cxx-abi-primitive-types.rs |  1 +
 ...-itanium-cxx-abi-repr-transparent-types.rs |  1 +
 ...adata-id-itanium-cxx-abi-sequence-types.rs |  1 +
 ...metadata-id-itanium-cxx-abi-trait-types.rs |  1 +
 ...a-id-itanium-cxx-abi-user-defined-types.rs |  1 +
 ...pe-metadata-itanium-cxx-abi-generalized.rs |  1 +
 ...-itanium-cxx-abi-normalized-generalized.rs |  1 +
 ...ype-metadata-itanium-cxx-abi-normalized.rs |  1 +
 .../cfi/emit-type-metadata-itanium-cxx-abi.rs |  1 +
 .../cfi/emit-type-metadata-trait-objects.rs   |  1 +
 .../sanitizer/cfi/external_weak_symbols.rs    |  1 +
 .../sanitizer/cfi/generalize-pointers.rs      |  1 +
 .../sanitizer/cfi/normalize-integers.rs       |  1 +
 .../dataflow-instrument-functions.rs          |  1 +
 .../codegen/sanitizer/memory-track-origins.rs |  1 +
 .../codegen/sanitizer/no-sanitize-inlining.rs |  1 +
 tests/codegen/sanitizer/no-sanitize.rs        |  1 +
 .../codegen/sanitizer/safestack-attr-check.rs |  1 +
 tests/codegen/sanitizer/sanitizer-recover.rs  |  1 +
 tests/run-make/sanitizer-cdylib-link/rmake.rs |  2 +
 tests/run-make/sanitizer-dylib-link/rmake.rs  |  2 +
 .../sanitizer-staticlib-link/rmake.rs         |  2 +
 tests/rustdoc/sanitizer-option.rs             |  1 +
 .../asm/global-asm-isnt-really-a-mir-body.rs  |  2 +
 tests/ui/lto/issue-100772.rs                  |  1 +
 tests/ui/sanitizer/address.rs                 |  1 +
 tests/ui/sanitizer/asan_odr_windows.rs        |  1 +
 tests/ui/sanitizer/badfree.rs                 |  1 +
 .../cfi/assoc-ty-lifetime-issue-123053.rs     |  1 +
 tests/ui/sanitizer/cfi/async-closures.rs      |  1 +
 tests/ui/sanitizer/cfi/can-reveal-opaques.rs  |  1 +
 tests/ui/sanitizer/cfi/closures.rs            |  1 +
 tests/ui/sanitizer/cfi/complex-receiver.rs    |  1 +
 tests/ui/sanitizer/cfi/coroutine.rs           |  1 +
 tests/ui/sanitizer/cfi/drop-in-place.rs       |  1 +
 tests/ui/sanitizer/cfi/drop-no-principal.rs   |  2 +-
 tests/ui/sanitizer/cfi/fn-ptr.rs              |  1 +
 .../cfi/generalize-pointers-attr-cfg.rs       |  1 +
 .../cfi/normalize-integers-attr-cfg.rs        |  1 +
 tests/ui/sanitizer/cfi/self-ref.rs            |  1 +
 tests/ui/sanitizer/cfi/sized-associated-ty.rs |  1 +
 tests/ui/sanitizer/cfi/supertraits.rs         |  1 +
 .../sanitizer/cfi/transparent-has-regions.rs  |  1 +
 tests/ui/sanitizer/cfi/virtual-auto.rs        |  1 +
 tests/ui/sanitizer/dataflow.rs                |  1 +
 tests/ui/sanitizer/hwaddress.rs               |  1 +
 .../issue-111184-cfi-coroutine-witness.rs     |  1 +
 ...issue-114275-cfi-const-expr-in-arry-len.rs |  1 +
 .../issue-72154-address-lifetime-markers.rs   |  1 +
 tests/ui/sanitizer/kcfi-mangling.rs           |  1 +
 tests/ui/sanitizer/leak.rs                    |  1 +
 tests/ui/sanitizer/memory-eager.rs            |  2 +
 tests/ui/sanitizer/memory-passing.rs          |  2 +
 tests/ui/sanitizer/memory.rs                  |  2 +
 .../new-llvm-pass-manager-thin-lto.rs         |  2 +
 tests/ui/sanitizer/thread.rs                  |  1 +
 tests/ui/sanitizer/use-after-scope.rs         |  1 +
 .../auxiliary/kcfi-normalize-ints.rs          |  7 ++
 .../auxiliary/no-sanitizers.rs                |  6 ++
 .../auxiliary/safestack-and-kcfi.rs           | 10 +++
 .../sanitizer-kcfi-normalize-ints.rs          | 19 +++++
 ...izer-kcfi-normalize-ints.wrong_flag.stderr | 13 ++++
 ...kcfi-normalize-ints.wrong_sanitizer.stderr | 13 ++++
 .../sanitizers-good-for-inconsistency.rs      | 19 +++++
 ...zers-safestack-and-kcfi.missed_both.stderr | 13 ++++
 ...zers-safestack-and-kcfi.missed_kcfi.stderr | 13 ++++
 ...safestack-and-kcfi.missed_safestack.stderr | 13 ++++
 .../sanitizers-safestack-and-kcfi.rs          | 23 ++++++
 86 files changed, 315 insertions(+), 8 deletions(-)
 create mode 100644 tests/ui/target_modifiers/auxiliary/kcfi-normalize-ints.rs
 create mode 100644 tests/ui/target_modifiers/auxiliary/no-sanitizers.rs
 create mode 100644 tests/ui/target_modifiers/auxiliary/safestack-and-kcfi.rs
 create mode 100644 tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.rs
 create mode 100644 tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_flag.stderr
 create mode 100644 tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_sanitizer.stderr
 create mode 100644 tests/ui/target_modifiers/sanitizers-good-for-inconsistency.rs
 create mode 100644 tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_both.stderr
 create mode 100644 tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_kcfi.stderr
 create mode 100644 tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_safestack.stderr
 create mode 100644 tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.rs

diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 07fb2de8a3e0c..b2e35e2ff5181 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -419,7 +419,7 @@ impl CStore {
             match (&left_name_val, &right_name_val) {
                 (Some(l), Some(r)) => match l.1.opt.cmp(&r.1.opt) {
                     cmp::Ordering::Equal => {
-                        if l.0.tech_value != r.0.tech_value {
+                        if !l.1.consistent(&tcx.sess.opts, Some(&r.1)) {
                             report_diff(
                                 &l.0.prefix,
                                 &l.0.name,
@@ -431,20 +431,28 @@ impl CStore {
                         right_name_val = None;
                     }
                     cmp::Ordering::Greater => {
-                        report_diff(&r.0.prefix, &r.0.name, None, Some(&r.1.value_name));
+                        if !r.1.consistent(&tcx.sess.opts, None) {
+                            report_diff(&r.0.prefix, &r.0.name, None, Some(&r.1.value_name));
+                        }
                         right_name_val = None;
                     }
                     cmp::Ordering::Less => {
-                        report_diff(&l.0.prefix, &l.0.name, Some(&l.1.value_name), None);
+                        if !l.1.consistent(&tcx.sess.opts, None) {
+                            report_diff(&l.0.prefix, &l.0.name, Some(&l.1.value_name), None);
+                        }
                         left_name_val = None;
                     }
                 },
                 (Some(l), None) => {
-                    report_diff(&l.0.prefix, &l.0.name, Some(&l.1.value_name), None);
+                    if !l.1.consistent(&tcx.sess.opts, None) {
+                        report_diff(&l.0.prefix, &l.0.name, Some(&l.1.value_name), None);
+                    }
                     left_name_val = None;
                 }
                 (None, Some(r)) => {
-                    report_diff(&r.0.prefix, &r.0.name, None, Some(&r.1.value_name));
+                    if !r.1.consistent(&tcx.sess.opts, None) {
+                        report_diff(&r.0.prefix, &r.0.name, None, Some(&r.1.value_name));
+                    }
                     right_name_val = None;
                 }
                 (None, None) => break,
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index b95ebfbe89f24..78e1a73c78813 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -83,10 +83,77 @@ pub struct TargetModifier {
     pub value_name: String,
 }
 
+mod target_modifier_consistency_check {
+    use super::*;
+    pub(super) fn sanitizer(l: &TargetModifier, r: Option<&TargetModifier>) -> bool {
+        let mut lparsed: SanitizerSet = Default::default();
+        let lval = if l.value_name.is_empty() { None } else { Some(l.value_name.as_str()) };
+        parse::parse_sanitizers(&mut lparsed, lval);
+
+        let mut rparsed: SanitizerSet = Default::default();
+        let rval = r.filter(|v| !v.value_name.is_empty()).map(|v| v.value_name.as_str());
+        parse::parse_sanitizers(&mut rparsed, rval);
+
+        // Some sanitizers need to be target modifiers, and some do not.
+        // For now, we should mark all sanitizers as target modifiers except for these:
+        // AddressSanitizer, LeakSanitizer
+        let tmod_sanitizers = SanitizerSet::MEMORY
+            | SanitizerSet::THREAD
+            | SanitizerSet::HWADDRESS
+            | SanitizerSet::CFI
+            | SanitizerSet::MEMTAG
+            | SanitizerSet::SHADOWCALLSTACK
+            | SanitizerSet::KCFI
+            | SanitizerSet::KERNELADDRESS
+            | SanitizerSet::SAFESTACK
+            | SanitizerSet::DATAFLOW;
+
+        lparsed & tmod_sanitizers == rparsed & tmod_sanitizers
+    }
+    pub(super) fn sanitizer_cfi_normalize_integers(
+        opts: &Options,
+        l: &TargetModifier,
+        r: Option<&TargetModifier>,
+    ) -> bool {
+        // For kCFI, the helper flag -Zsanitizer-cfi-normalize-integers should also be a target modifier
+        if opts.unstable_opts.sanitizer.contains(SanitizerSet::KCFI) {
+            if let Some(r) = r {
+                return l.extend().tech_value == r.extend().tech_value;
+            } else {
+                return false;
+            }
+        }
+        true
+    }
+}
+
 impl TargetModifier {
     pub fn extend(&self) -> ExtendedTargetModifierInfo {
         self.opt.reparse(&self.value_name)
     }
+    // Custom consistency check for target modifiers (or default `l.tech_value == r.tech_value`)
+    // When other is None, consistency with default value is checked
+    pub fn consistent(&self, opts: &Options, other: Option<&TargetModifier>) -> bool {
+        assert!(other.is_none() || self.opt == other.unwrap().opt);
+        match self.opt {
+            OptionsTargetModifiers::UnstableOptions(unstable) => match unstable {
+                UnstableOptionsTargetModifiers::sanitizer => {
+                    return target_modifier_consistency_check::sanitizer(self, other);
+                }
+                UnstableOptionsTargetModifiers::sanitizer_cfi_normalize_integers => {
+                    return target_modifier_consistency_check::sanitizer_cfi_normalize_integers(
+                        opts, self, other,
+                    );
+                }
+                _ => {}
+            },
+            _ => {}
+        };
+        match other {
+            Some(other) => self.extend().tech_value == other.extend().tech_value,
+            None => false,
+        }
+    }
 }
 
 fn tmod_push_impl(
@@ -2446,13 +2513,13 @@ options! {
     remark_dir: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
         "directory into which to write optimization remarks (if not specified, they will be \
 written to standard error output)"),
-    sanitizer: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED],
+    sanitizer: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED TARGET_MODIFIER],
         "use a sanitizer"),
     sanitizer_cfi_canonical_jump_tables: Option<bool> = (Some(true), parse_opt_bool, [TRACKED],
         "enable canonical jump tables (default: yes)"),
     sanitizer_cfi_generalize_pointers: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "enable generalizing pointer types (default: no)"),
-    sanitizer_cfi_normalize_integers: Option<bool> = (None, parse_opt_bool, [TRACKED],
+    sanitizer_cfi_normalize_integers: Option<bool> = (None, parse_opt_bool, [TRACKED TARGET_MODIFIER],
         "enable normalizing integer types (default: no)"),
     sanitizer_dataflow_abilist: Vec<String> = (Vec::new(), parse_comma_list, [TRACKED],
         "additional ABI list files that control how shadow parameters are passed (comma separated)"),
diff --git a/tests/codegen/naked-asan.rs b/tests/codegen/naked-asan.rs
index 223c41b15bb35..430de6f736a51 100644
--- a/tests/codegen/naked-asan.rs
+++ b/tests/codegen/naked-asan.rs
@@ -4,6 +4,8 @@
 //@ needs-sanitizer-address
 //@ compile-flags: -Zsanitizer=address -Ctarget-feature=-crt-static
 
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
+
 #![crate_type = "lib"]
 #![no_std]
 #![feature(abi_x86_interrupt)]
diff --git a/tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs b/tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs
index f319306f93fd8..b19920b8e6d1c 100644
--- a/tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs
+++ b/tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs
@@ -20,6 +20,7 @@
 //
 //@ revisions:ASAN ASAN-FAT-LTO
 //@                compile-flags: -Zsanitizer=address -Ctarget-feature=-crt-static
+//@                compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@[ASAN]          compile-flags:
 //@[ASAN-FAT-LTO]  compile-flags: -Cprefer-dynamic=false -Clto=fat
 
diff --git a/tests/codegen/sanitizer/cfi/add-canonical-jump-tables-flag.rs b/tests/codegen/sanitizer/cfi/add-canonical-jump-tables-flag.rs
index 22577e2a3c46b..82fd290d7069a 100644
--- a/tests/codegen/sanitizer/cfi/add-canonical-jump-tables-flag.rs
+++ b/tests/codegen/sanitizer/cfi/add-canonical-jump-tables-flag.rs
@@ -3,6 +3,8 @@
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
 
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
+
 #![crate_type = "lib"]
 
 pub fn foo() {}
diff --git a/tests/codegen/sanitizer/cfi/add-cfi-normalize-integers-flag.rs b/tests/codegen/sanitizer/cfi/add-cfi-normalize-integers-flag.rs
index a54a6d84a8073..59271b228c4ba 100644
--- a/tests/codegen/sanitizer/cfi/add-cfi-normalize-integers-flag.rs
+++ b/tests/codegen/sanitizer/cfi/add-cfi-normalize-integers-flag.rs
@@ -3,6 +3,8 @@
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers
 
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer,sanitizer-cfi-normalize-integers
+
 #![crate_type = "lib"]
 
 pub fn foo() {}
diff --git a/tests/codegen/sanitizer/cfi/add-enable-split-lto-unit-flag.rs b/tests/codegen/sanitizer/cfi/add-enable-split-lto-unit-flag.rs
index 283b8f2610294..50042f7724a1f 100644
--- a/tests/codegen/sanitizer/cfi/add-enable-split-lto-unit-flag.rs
+++ b/tests/codegen/sanitizer/cfi/add-enable-split-lto-unit-flag.rs
@@ -2,6 +2,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/cfi/dbg-location-on-cfi-blocks.rs b/tests/codegen/sanitizer/cfi/dbg-location-on-cfi-blocks.rs
index df65960dfe0be..2085d121aa306 100644
--- a/tests/codegen/sanitizer/cfi/dbg-location-on-cfi-blocks.rs
+++ b/tests/codegen/sanitizer/cfi/dbg-location-on-cfi-blocks.rs
@@ -2,6 +2,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -Cdebuginfo=1
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/cfi/emit-type-checks-attr-no-sanitize.rs b/tests/codegen/sanitizer/cfi/emit-type-checks-attr-no-sanitize.rs
index 71ccdc8ca624f..18dfe51a63309 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-checks-attr-no-sanitize.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-checks-attr-no-sanitize.rs
@@ -2,6 +2,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 #![feature(no_sanitize)]
diff --git a/tests/codegen/sanitizer/cfi/emit-type-checks.rs b/tests/codegen/sanitizer/cfi/emit-type-checks.rs
index ebc66a015df69..2cab35f23520b 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-checks.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-checks.rs
@@ -2,6 +2,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-attr-cfi-encoding.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-attr-cfi-encoding.rs
index 9bc2e42db0f61..59469c987dc76 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-attr-cfi-encoding.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-attr-cfi-encoding.rs
@@ -2,6 +2,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 #![feature(cfi_encoding, extern_types)]
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs
index 9048c6a1f1838..a74a582694f51 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs
@@ -3,6 +3,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 #![feature(type_alias_impl_trait)]
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-drop-in-place.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-drop-in-place.rs
index 2a7eca6fc1963..6cb096f9f3835 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-drop-in-place.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-drop-in-place.rs
@@ -2,6 +2,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-function-types.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-function-types.rs
index 7e60aafff6802..0a27c36987512 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-function-types.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-function-types.rs
@@ -3,6 +3,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs
index 36d2e8c9f25a2..6795860331aac 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs
@@ -3,6 +3,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 #![feature(type_alias_impl_trait)]
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-method-secondary-typeid.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-method-secondary-typeid.rs
index 9d611777ff0ba..0e700b39afd54 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-method-secondary-typeid.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-method-secondary-typeid.rs
@@ -3,6 +3,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs
index a8ba8db1be3b4..0f687221d4aff 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs
@@ -3,6 +3,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 #![feature(type_alias_impl_trait)]
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-pointer-types.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-pointer-types.rs
index d37bb740f5505..c1c2c95723043 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-pointer-types.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-pointer-types.rs
@@ -3,6 +3,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-primitive-types.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-primitive-types.rs
index 7d9e4d0587276..719236ea9811e 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-primitive-types.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-primitive-types.rs
@@ -3,6 +3,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-repr-transparent-types.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-repr-transparent-types.rs
index 0f97c70f3f923..07a89844d3af9 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-repr-transparent-types.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-repr-transparent-types.rs
@@ -3,6 +3,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-sequence-types.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-sequence-types.rs
index bdee3f47a837d..8ca445843371a 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-sequence-types.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-sequence-types.rs
@@ -3,6 +3,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-trait-types.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-trait-types.rs
index 55e816178f8fc..196c4dbd7499f 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-trait-types.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-trait-types.rs
@@ -3,6 +3,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-user-defined-types.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-user-defined-types.rs
index c1f3ca61afeb1..fab158586dcab 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-user-defined-types.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-user-defined-types.rs
@@ -3,6 +3,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 #![feature(extern_types)]
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-generalized.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-generalized.rs
index 32637b64b3ea8..dafbb770d3b81 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-generalized.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-generalized.rs
@@ -2,6 +2,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-generalize-pointers
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs
index 51121b0aef1aa..cd982c3249b3b 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs
@@ -2,6 +2,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers -Zsanitizer-cfi-generalize-pointers
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer,sanitizer-cfi-normalize-integers
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized.rs
index 1cfdd23006e3a..05ec3f31bc31f 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized.rs
@@ -2,6 +2,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer,sanitizer-cfi-normalize-integers
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi.rs
index 56ab1ce4b3582..390ae0c0fd3e9 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi.rs
@@ -2,6 +2,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-trait-objects.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-trait-objects.rs
index 0e57ce322d127..36c96c4272c68 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-trait-objects.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-trait-objects.rs
@@ -2,6 +2,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/cfi/external_weak_symbols.rs b/tests/codegen/sanitizer/cfi/external_weak_symbols.rs
index 00e9b5029af8c..4e3d331f863c9 100644
--- a/tests/codegen/sanitizer/cfi/external_weak_symbols.rs
+++ b/tests/codegen/sanitizer/cfi/external_weak_symbols.rs
@@ -3,6 +3,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clinker-plugin-lto -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 #![crate_type = "bin"]
 #![feature(linkage)]
 
diff --git a/tests/codegen/sanitizer/cfi/generalize-pointers.rs b/tests/codegen/sanitizer/cfi/generalize-pointers.rs
index 57004da6f8e06..b77e9a9d37788 100644
--- a/tests/codegen/sanitizer/cfi/generalize-pointers.rs
+++ b/tests/codegen/sanitizer/cfi/generalize-pointers.rs
@@ -2,6 +2,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-generalize-pointers -Copt-level=0
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/cfi/normalize-integers.rs b/tests/codegen/sanitizer/cfi/normalize-integers.rs
index 770ee4e64e089..f28b7f17aa788 100644
--- a/tests/codegen/sanitizer/cfi/normalize-integers.rs
+++ b/tests/codegen/sanitizer/cfi/normalize-integers.rs
@@ -2,6 +2,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers -Copt-level=0
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer,sanitizer-cfi-normalize-integers
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/dataflow-instrument-functions.rs b/tests/codegen/sanitizer/dataflow-instrument-functions.rs
index a2d0d63cc1754..2145a9fe70362 100644
--- a/tests/codegen/sanitizer/dataflow-instrument-functions.rs
+++ b/tests/codegen/sanitizer/dataflow-instrument-functions.rs
@@ -2,6 +2,7 @@
 //
 //@ needs-sanitizer-dataflow
 //@ compile-flags: -Copt-level=0 -Zsanitizer=dataflow
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/memory-track-origins.rs b/tests/codegen/sanitizer/memory-track-origins.rs
index 318c277e10cba..d96e4b4d59fc0 100644
--- a/tests/codegen/sanitizer/memory-track-origins.rs
+++ b/tests/codegen/sanitizer/memory-track-origins.rs
@@ -5,6 +5,7 @@
 //@ revisions:MSAN-0 MSAN-1 MSAN-2 MSAN-1-LTO MSAN-2-LTO
 //
 //@ compile-flags: -Zsanitizer=memory -Ctarget-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@[MSAN-0] compile-flags:
 //@[MSAN-1] compile-flags: -Zsanitizer-memory-track-origins=1
 //@[MSAN-2] compile-flags: -Zsanitizer-memory-track-origins
diff --git a/tests/codegen/sanitizer/no-sanitize-inlining.rs b/tests/codegen/sanitizer/no-sanitize-inlining.rs
index 4bd832d2ab195..79bd454d1d096 100644
--- a/tests/codegen/sanitizer/no-sanitize-inlining.rs
+++ b/tests/codegen/sanitizer/no-sanitize-inlining.rs
@@ -5,6 +5,7 @@
 //@ needs-sanitizer-leak
 //@ revisions: ASAN LSAN
 //@       compile-flags: -Copt-level=3 -Zmir-opt-level=4 -Ctarget-feature=-crt-static
+//@       compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@[ASAN] compile-flags: -Zsanitizer=address
 //@[LSAN] compile-flags: -Zsanitizer=leak
 
diff --git a/tests/codegen/sanitizer/no-sanitize.rs b/tests/codegen/sanitizer/no-sanitize.rs
index 2a309f6b9c696..727f0c5891296 100644
--- a/tests/codegen/sanitizer/no-sanitize.rs
+++ b/tests/codegen/sanitizer/no-sanitize.rs
@@ -3,6 +3,7 @@
 //
 //@ needs-sanitizer-address
 //@ compile-flags: -Zsanitizer=address -Ctarget-feature=-crt-static -Copt-level=0
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 #![feature(no_sanitize)]
diff --git a/tests/codegen/sanitizer/safestack-attr-check.rs b/tests/codegen/sanitizer/safestack-attr-check.rs
index 050a60333afa1..9ae45828439e7 100644
--- a/tests/codegen/sanitizer/safestack-attr-check.rs
+++ b/tests/codegen/sanitizer/safestack-attr-check.rs
@@ -2,6 +2,7 @@
 //
 //@ needs-sanitizer-safestack
 //@ compile-flags: -Zsanitizer=safestack -Copt-level=0
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/sanitizer-recover.rs b/tests/codegen/sanitizer/sanitizer-recover.rs
index 6b65932048184..4363e16389ef3 100644
--- a/tests/codegen/sanitizer/sanitizer-recover.rs
+++ b/tests/codegen/sanitizer/sanitizer-recover.rs
@@ -7,6 +7,7 @@
 //@ no-prefer-dynamic
 //
 //@                   compile-flags: -Ctarget-feature=-crt-static
+//@                   compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@[ASAN]             compile-flags: -Zsanitizer=address -Copt-level=0
 //@[ASAN-RECOVER]     compile-flags: -Zsanitizer=address -Zsanitizer-recover=address -Copt-level=0
 //@[MSAN]             compile-flags: -Zsanitizer=memory
diff --git a/tests/run-make/sanitizer-cdylib-link/rmake.rs b/tests/run-make/sanitizer-cdylib-link/rmake.rs
index f9d7fd98789e6..8ff58594d109a 100644
--- a/tests/run-make/sanitizer-cdylib-link/rmake.rs
+++ b/tests/run-make/sanitizer-cdylib-link/rmake.rs
@@ -8,6 +8,8 @@
 //@ needs-sanitizer-support
 //@ needs-sanitizer-address
 
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
+
 use run_make_support::{run_fail, rustc};
 
 fn main() {
diff --git a/tests/run-make/sanitizer-dylib-link/rmake.rs b/tests/run-make/sanitizer-dylib-link/rmake.rs
index b43420adc72ba..bae3240a23648 100644
--- a/tests/run-make/sanitizer-dylib-link/rmake.rs
+++ b/tests/run-make/sanitizer-dylib-link/rmake.rs
@@ -7,6 +7,8 @@
 //@ needs-sanitizer-support
 //@ needs-sanitizer-address
 
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
+
 use run_make_support::{run_fail, rustc};
 
 fn main() {
diff --git a/tests/run-make/sanitizer-staticlib-link/rmake.rs b/tests/run-make/sanitizer-staticlib-link/rmake.rs
index e38d15a8a3c4b..dda9262618903 100644
--- a/tests/run-make/sanitizer-staticlib-link/rmake.rs
+++ b/tests/run-make/sanitizer-staticlib-link/rmake.rs
@@ -11,6 +11,8 @@
 //@ needs-sanitizer-support
 //@ needs-sanitizer-address
 
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
+
 use run_make_support::{cc, extra_c_flags, extra_cxx_flags, run_fail, rustc, static_lib_name};
 
 fn main() {
diff --git a/tests/rustdoc/sanitizer-option.rs b/tests/rustdoc/sanitizer-option.rs
index 2adf1be51fd7f..c52be83b03279 100644
--- a/tests/rustdoc/sanitizer-option.rs
+++ b/tests/rustdoc/sanitizer-option.rs
@@ -1,6 +1,7 @@
 //@ needs-sanitizer-support
 //@ needs-sanitizer-address
 //@ compile-flags: --test -Z sanitizer=address
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //
 // #43031: Verify that rustdoc passes `-Z` options to rustc. Use an extern
 // function that is provided by the sanitizer runtime, if flag is not passed
diff --git a/tests/ui/asm/global-asm-isnt-really-a-mir-body.rs b/tests/ui/asm/global-asm-isnt-really-a-mir-body.rs
index b7636d116ec6c..aef25d057d4ba 100644
--- a/tests/ui/asm/global-asm-isnt-really-a-mir-body.rs
+++ b/tests/ui/asm/global-asm-isnt-really-a-mir-body.rs
@@ -1,5 +1,7 @@
 //@ revisions: emit_mir instrument cfi
 
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
+
 // Make sure we don't try to emit MIR for it.
 //@[emit_mir] compile-flags: --emit=mir
 
diff --git a/tests/ui/lto/issue-100772.rs b/tests/ui/lto/issue-100772.rs
index 29ec5b9bf9647..293741be7db6a 100644
--- a/tests/ui/lto/issue-100772.rs
+++ b/tests/ui/lto/issue-100772.rs
@@ -1,6 +1,7 @@
 //@ build-pass
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ no-prefer-dynamic
 //@ only-x86_64-unknown-linux-gnu
 
diff --git a/tests/ui/sanitizer/address.rs b/tests/ui/sanitizer/address.rs
index 7a5e767687cf1..b9aa3ed1903fc 100644
--- a/tests/ui/sanitizer/address.rs
+++ b/tests/ui/sanitizer/address.rs
@@ -3,6 +3,7 @@
 //@ ignore-cross-compile
 //
 //@ compile-flags: -Z sanitizer=address -O -g
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //
 //@ run-fail
 //@ error-pattern: AddressSanitizer: stack-buffer-overflow
diff --git a/tests/ui/sanitizer/asan_odr_windows.rs b/tests/ui/sanitizer/asan_odr_windows.rs
index 28c2471676155..de510e154fca7 100644
--- a/tests/ui/sanitizer/asan_odr_windows.rs
+++ b/tests/ui/sanitizer/asan_odr_windows.rs
@@ -3,6 +3,7 @@
 
 //@ run-pass
 //@ compile-flags:-Zsanitizer=address
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ aux-build: asan_odr_win-2.rs
 //@ only-windows-msvc
 //@ needs-sanitizer-support
diff --git a/tests/ui/sanitizer/badfree.rs b/tests/ui/sanitizer/badfree.rs
index ecbb58eba00d4..cffbbcf90f4df 100644
--- a/tests/ui/sanitizer/badfree.rs
+++ b/tests/ui/sanitizer/badfree.rs
@@ -3,6 +3,7 @@
 //@ ignore-cross-compile
 //
 //@ compile-flags: -Z sanitizer=address -O
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //
 //@ run-fail
 //@ regex-error-pattern: AddressSanitizer: (SEGV|attempting free on address which was not malloc)
diff --git a/tests/ui/sanitizer/cfi/assoc-ty-lifetime-issue-123053.rs b/tests/ui/sanitizer/cfi/assoc-ty-lifetime-issue-123053.rs
index f4f383e008a08..0f2202e7ba00f 100644
--- a/tests/ui/sanitizer/cfi/assoc-ty-lifetime-issue-123053.rs
+++ b/tests/ui/sanitizer/cfi/assoc-ty-lifetime-issue-123053.rs
@@ -3,6 +3,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ edition: 2021
 //@ no-prefer-dynamic
 //@ only-x86_64-unknown-linux-gnu
diff --git a/tests/ui/sanitizer/cfi/async-closures.rs b/tests/ui/sanitizer/cfi/async-closures.rs
index 351853ab1a710..41959b445286a 100644
--- a/tests/ui/sanitizer/cfi/async-closures.rs
+++ b/tests/ui/sanitizer/cfi/async-closures.rs
@@ -7,6 +7,7 @@
 //@ [cfi] needs-sanitizer-cfi
 //@ [kcfi] needs-sanitizer-kcfi
 //@ compile-flags: -C target-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
 //@ [cfi] compile-flags: -Z sanitizer=cfi
 //@ [kcfi] compile-flags: -Z sanitizer=kcfi
diff --git a/tests/ui/sanitizer/cfi/can-reveal-opaques.rs b/tests/ui/sanitizer/cfi/can-reveal-opaques.rs
index 99c12d72eb524..35f150670a233 100644
--- a/tests/ui/sanitizer/cfi/can-reveal-opaques.rs
+++ b/tests/ui/sanitizer/cfi/can-reveal-opaques.rs
@@ -1,5 +1,6 @@
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ no-prefer-dynamic
 //@ only-x86_64-unknown-linux-gnu
 //@ build-pass
diff --git a/tests/ui/sanitizer/cfi/closures.rs b/tests/ui/sanitizer/cfi/closures.rs
index 9f9002da674f5..d096cbd69c798 100644
--- a/tests/ui/sanitizer/cfi/closures.rs
+++ b/tests/ui/sanitizer/cfi/closures.rs
@@ -6,6 +6,7 @@
 //@ [cfi] needs-sanitizer-cfi
 //@ [kcfi] needs-sanitizer-kcfi
 //@ compile-flags: -C target-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
 //@ [cfi] compile-flags: -Z sanitizer=cfi
 //@ [kcfi] compile-flags: -Z sanitizer=kcfi
diff --git a/tests/ui/sanitizer/cfi/complex-receiver.rs b/tests/ui/sanitizer/cfi/complex-receiver.rs
index c7b45a775ca1d..c8a25983c32d6 100644
--- a/tests/ui/sanitizer/cfi/complex-receiver.rs
+++ b/tests/ui/sanitizer/cfi/complex-receiver.rs
@@ -8,6 +8,7 @@
 //@ [cfi] needs-sanitizer-cfi
 //@ [kcfi] needs-sanitizer-kcfi
 //@ compile-flags: -C target-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
 //@ [cfi] compile-flags: -Z sanitizer=cfi
 //@ [kcfi] compile-flags: -Z sanitizer=kcfi
diff --git a/tests/ui/sanitizer/cfi/coroutine.rs b/tests/ui/sanitizer/cfi/coroutine.rs
index 39a754f103637..1dde34bcdf0d4 100644
--- a/tests/ui/sanitizer/cfi/coroutine.rs
+++ b/tests/ui/sanitizer/cfi/coroutine.rs
@@ -7,6 +7,7 @@
 //@ [cfi] needs-sanitizer-cfi
 //@ [kcfi] needs-sanitizer-kcfi
 //@ compile-flags: -C target-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
 //@ [cfi] compile-flags: -Z sanitizer=cfi
 //@ [kcfi] compile-flags: -Z sanitizer=kcfi
diff --git a/tests/ui/sanitizer/cfi/drop-in-place.rs b/tests/ui/sanitizer/cfi/drop-in-place.rs
index 8ce2c43260261..17956aadc9a71 100644
--- a/tests/ui/sanitizer/cfi/drop-in-place.rs
+++ b/tests/ui/sanitizer/cfi/drop-in-place.rs
@@ -4,6 +4,7 @@
 //@ only-linux
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Copt-level=0 -Cprefer-dynamic=off -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ run-pass
 
 struct EmptyDrop;
diff --git a/tests/ui/sanitizer/cfi/drop-no-principal.rs b/tests/ui/sanitizer/cfi/drop-no-principal.rs
index c1c88c8c71c73..2875f76f09b3d 100644
--- a/tests/ui/sanitizer/cfi/drop-no-principal.rs
+++ b/tests/ui/sanitizer/cfi/drop-no-principal.rs
@@ -3,7 +3,7 @@
 //@ needs-sanitizer-cfi
 // FIXME(#122848) Remove only-linux once OSX CFI binaries works
 //@ only-linux
-//@ compile-flags: --crate-type=bin -Cprefer-dynamic=off -Clto -Zsanitizer=cfi
+//@ compile-flags: --crate-type=bin -Cprefer-dynamic=off -Clto -Zsanitizer=cfi -C unsafe-allow-abi-mismatch=sanitizer
 //@ compile-flags: -C target-feature=-crt-static -C codegen-units=1 -C opt-level=0
 // FIXME(#118761) Should be run-pass once the labels on drop are compatible.
 // This test is being landed ahead of that to test that the compiler doesn't ICE while labeling the
diff --git a/tests/ui/sanitizer/cfi/fn-ptr.rs b/tests/ui/sanitizer/cfi/fn-ptr.rs
index 505b4b8e7f032..1943dcb4797df 100644
--- a/tests/ui/sanitizer/cfi/fn-ptr.rs
+++ b/tests/ui/sanitizer/cfi/fn-ptr.rs
@@ -6,6 +6,7 @@
 //@ [cfi] needs-sanitizer-cfi
 //@ [kcfi] needs-sanitizer-kcfi
 //@ compile-flags: -C target-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ [cfi] compile-flags: -C opt-level=0 -C codegen-units=1 -C lto
 //@ [cfi] compile-flags: -C prefer-dynamic=off
 //@ [cfi] compile-flags: -Z sanitizer=cfi
diff --git a/tests/ui/sanitizer/cfi/generalize-pointers-attr-cfg.rs b/tests/ui/sanitizer/cfi/generalize-pointers-attr-cfg.rs
index d46002c69fda0..44cdcb250e701 100644
--- a/tests/ui/sanitizer/cfi/generalize-pointers-attr-cfg.rs
+++ b/tests/ui/sanitizer/cfi/generalize-pointers-attr-cfg.rs
@@ -4,6 +4,7 @@
 //@ needs-sanitizer-cfi
 //@ check-pass
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-generalize-pointers
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![feature(cfg_sanitizer_cfi)]
 
diff --git a/tests/ui/sanitizer/cfi/normalize-integers-attr-cfg.rs b/tests/ui/sanitizer/cfi/normalize-integers-attr-cfg.rs
index 24c2c2c13da75..49e5e85ffeec4 100644
--- a/tests/ui/sanitizer/cfi/normalize-integers-attr-cfg.rs
+++ b/tests/ui/sanitizer/cfi/normalize-integers-attr-cfg.rs
@@ -4,6 +4,7 @@
 //@ needs-sanitizer-cfi
 //@ check-pass
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer,sanitizer-cfi-normalize-integers
 
 #![feature(cfg_sanitizer_cfi)]
 
diff --git a/tests/ui/sanitizer/cfi/self-ref.rs b/tests/ui/sanitizer/cfi/self-ref.rs
index 3b524ac661cf8..af757568b0080 100644
--- a/tests/ui/sanitizer/cfi/self-ref.rs
+++ b/tests/ui/sanitizer/cfi/self-ref.rs
@@ -6,6 +6,7 @@
 //@ [cfi] needs-sanitizer-cfi
 //@ [kcfi] needs-sanitizer-kcfi
 //@ compile-flags: -C target-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
 //@ [cfi] compile-flags: -Z sanitizer=cfi
 //@ [kcfi] compile-flags: -Z sanitizer=kcfi
diff --git a/tests/ui/sanitizer/cfi/sized-associated-ty.rs b/tests/ui/sanitizer/cfi/sized-associated-ty.rs
index f5b4e22e9d99b..a5ef199989e47 100644
--- a/tests/ui/sanitizer/cfi/sized-associated-ty.rs
+++ b/tests/ui/sanitizer/cfi/sized-associated-ty.rs
@@ -7,6 +7,7 @@
 //@ [cfi] needs-sanitizer-cfi
 //@ [kcfi] needs-sanitizer-kcfi
 //@ compile-flags: -C target-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
 //@ [cfi] compile-flags: -Z sanitizer=cfi
 //@ [kcfi] compile-flags: -Z sanitizer=kcfi
diff --git a/tests/ui/sanitizer/cfi/supertraits.rs b/tests/ui/sanitizer/cfi/supertraits.rs
index f80b316918804..e46f6431a9255 100644
--- a/tests/ui/sanitizer/cfi/supertraits.rs
+++ b/tests/ui/sanitizer/cfi/supertraits.rs
@@ -6,6 +6,7 @@
 //@ [cfi] needs-sanitizer-cfi
 //@ [kcfi] needs-sanitizer-kcfi
 //@ compile-flags: -C target-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
 //@ [cfi] compile-flags: -Z sanitizer=cfi
 //@ [kcfi] compile-flags: -Z sanitizer=kcfi
diff --git a/tests/ui/sanitizer/cfi/transparent-has-regions.rs b/tests/ui/sanitizer/cfi/transparent-has-regions.rs
index b70e1ea179121..e576bb2436d70 100644
--- a/tests/ui/sanitizer/cfi/transparent-has-regions.rs
+++ b/tests/ui/sanitizer/cfi/transparent-has-regions.rs
@@ -1,5 +1,6 @@
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ no-prefer-dynamic
 //@ only-x86_64-unknown-linux-gnu
 //@ build-pass
diff --git a/tests/ui/sanitizer/cfi/virtual-auto.rs b/tests/ui/sanitizer/cfi/virtual-auto.rs
index 6971d516a2057..6d5a4c9b06808 100644
--- a/tests/ui/sanitizer/cfi/virtual-auto.rs
+++ b/tests/ui/sanitizer/cfi/virtual-auto.rs
@@ -6,6 +6,7 @@
 //@ [cfi] needs-sanitizer-cfi
 //@ [kcfi] needs-sanitizer-kcfi
 //@ compile-flags: -C target-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
 //@ [cfi] compile-flags: -Z sanitizer=cfi
 //@ [kcfi] compile-flags: -Z sanitizer=kcfi
diff --git a/tests/ui/sanitizer/dataflow.rs b/tests/ui/sanitizer/dataflow.rs
index 658a9e4808664..0d9a56774c5c8 100644
--- a/tests/ui/sanitizer/dataflow.rs
+++ b/tests/ui/sanitizer/dataflow.rs
@@ -5,6 +5,7 @@
 //@ needs-sanitizer-dataflow
 //@ run-pass
 //@ compile-flags: -Zsanitizer=dataflow -Zsanitizer-dataflow-abilist={{src-base}}/sanitizer/dataflow-abilist.txt
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 use std::mem::size_of;
 use std::os::raw::{c_int, c_long, c_void};
diff --git a/tests/ui/sanitizer/hwaddress.rs b/tests/ui/sanitizer/hwaddress.rs
index e5939eb734b66..4f88347994a4e 100644
--- a/tests/ui/sanitizer/hwaddress.rs
+++ b/tests/ui/sanitizer/hwaddress.rs
@@ -6,6 +6,7 @@
 //
 // FIXME(#83989): codegen-units=1 triggers linker errors on aarch64-gnu
 //@ compile-flags: -Z sanitizer=hwaddress -O -g -C codegen-units=16
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //
 //@ run-fail
 //@ error-pattern: HWAddressSanitizer: tag-mismatch
diff --git a/tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs b/tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs
index 7d0c73c2841e8..b51bb0e403a67 100644
--- a/tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs
+++ b/tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs
@@ -3,6 +3,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ edition: 2021
 //@ no-prefer-dynamic
 //@ only-x86_64-unknown-linux-gnu
diff --git a/tests/ui/sanitizer/issue-114275-cfi-const-expr-in-arry-len.rs b/tests/ui/sanitizer/issue-114275-cfi-const-expr-in-arry-len.rs
index b1b7487fa2a4d..01d5edcdc9b64 100644
--- a/tests/ui/sanitizer/issue-114275-cfi-const-expr-in-arry-len.rs
+++ b/tests/ui/sanitizer/issue-114275-cfi-const-expr-in-arry-len.rs
@@ -3,6 +3,7 @@
 //
 //@ build-pass
 //@ compile-flags: -Ccodegen-units=1 -Clto -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ needs-sanitizer-cfi
 
 #![crate_type = "lib"]
diff --git a/tests/ui/sanitizer/issue-72154-address-lifetime-markers.rs b/tests/ui/sanitizer/issue-72154-address-lifetime-markers.rs
index aa0c19db9a12b..787bc9153a332 100644
--- a/tests/ui/sanitizer/issue-72154-address-lifetime-markers.rs
+++ b/tests/ui/sanitizer/issue-72154-address-lifetime-markers.rs
@@ -8,6 +8,7 @@
 //@ ignore-cross-compile
 //
 //@ compile-flags: -Copt-level=0 -Zsanitizer=address
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ run-pass
 
 pub struct Wrap {
diff --git a/tests/ui/sanitizer/kcfi-mangling.rs b/tests/ui/sanitizer/kcfi-mangling.rs
index fde7b5451b6e2..adf03b86e702b 100644
--- a/tests/ui/sanitizer/kcfi-mangling.rs
+++ b/tests/ui/sanitizer/kcfi-mangling.rs
@@ -3,6 +3,7 @@
 //@ needs-sanitizer-kcfi
 //@ no-prefer-dynamic
 //@ compile-flags: -C panic=abort -Zsanitizer=kcfi -C symbol-mangling-version=v0
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ build-pass
 
 trait Foo {
diff --git a/tests/ui/sanitizer/leak.rs b/tests/ui/sanitizer/leak.rs
index 65915ec24b723..d184e7353558e 100644
--- a/tests/ui/sanitizer/leak.rs
+++ b/tests/ui/sanitizer/leak.rs
@@ -2,6 +2,7 @@
 //@ needs-sanitizer-leak
 //
 //@ compile-flags: -Z sanitizer=leak -O
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //
 //@ run-fail
 //@ error-pattern: LeakSanitizer: detected memory leaks
diff --git a/tests/ui/sanitizer/memory-eager.rs b/tests/ui/sanitizer/memory-eager.rs
index 532d7b308f63d..297112398dda2 100644
--- a/tests/ui/sanitizer/memory-eager.rs
+++ b/tests/ui/sanitizer/memory-eager.rs
@@ -1,6 +1,8 @@
 //@ needs-sanitizer-support
 //@ needs-sanitizer-memory
 //
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
+//
 //@ revisions: unoptimized optimized
 //
 //@ [optimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O
diff --git a/tests/ui/sanitizer/memory-passing.rs b/tests/ui/sanitizer/memory-passing.rs
index 96a4cd909c7c2..6ac41b178fe7f 100644
--- a/tests/ui/sanitizer/memory-passing.rs
+++ b/tests/ui/sanitizer/memory-passing.rs
@@ -1,6 +1,8 @@
 //@ needs-sanitizer-support
 //@ needs-sanitizer-memory
 //
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
+//
 //@ revisions: unoptimized optimized
 //
 //@ [optimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O
diff --git a/tests/ui/sanitizer/memory.rs b/tests/ui/sanitizer/memory.rs
index a91fefe4d16da..1566637acd222 100644
--- a/tests/ui/sanitizer/memory.rs
+++ b/tests/ui/sanitizer/memory.rs
@@ -1,6 +1,8 @@
 //@ needs-sanitizer-support
 //@ needs-sanitizer-memory
 //
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
+//
 //@ revisions: unoptimized optimized
 //
 //@ [optimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O
diff --git a/tests/ui/sanitizer/new-llvm-pass-manager-thin-lto.rs b/tests/ui/sanitizer/new-llvm-pass-manager-thin-lto.rs
index b7dd4a437821a..eac02f6f21bbd 100644
--- a/tests/ui/sanitizer/new-llvm-pass-manager-thin-lto.rs
+++ b/tests/ui/sanitizer/new-llvm-pass-manager-thin-lto.rs
@@ -6,6 +6,8 @@
 //@ needs-sanitizer-address
 //@ ignore-cross-compile
 //
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
+//
 //@ no-prefer-dynamic
 //@ revisions: opt0 opt1
 //@ compile-flags: -Zsanitizer=address -Clto=thin
diff --git a/tests/ui/sanitizer/thread.rs b/tests/ui/sanitizer/thread.rs
index 566774d6b1d64..512100f55ee90 100644
--- a/tests/ui/sanitizer/thread.rs
+++ b/tests/ui/sanitizer/thread.rs
@@ -14,6 +14,7 @@
 //@ needs-sanitizer-thread
 //
 //@ compile-flags: -Z sanitizer=thread -O
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //
 //@ run-fail
 //@ error-pattern: WARNING: ThreadSanitizer: data race
diff --git a/tests/ui/sanitizer/use-after-scope.rs b/tests/ui/sanitizer/use-after-scope.rs
index 4d7f6f6c2f2b5..f8eb7257c789f 100644
--- a/tests/ui/sanitizer/use-after-scope.rs
+++ b/tests/ui/sanitizer/use-after-scope.rs
@@ -3,6 +3,7 @@
 //@ ignore-cross-compile
 //
 //@ compile-flags: -Zsanitizer=address
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ run-fail
 //@ error-pattern: ERROR: AddressSanitizer: stack-use-after-scope
 
diff --git a/tests/ui/target_modifiers/auxiliary/kcfi-normalize-ints.rs b/tests/ui/target_modifiers/auxiliary/kcfi-normalize-ints.rs
new file mode 100644
index 0000000000000..f97005a14502d
--- /dev/null
+++ b/tests/ui/target_modifiers/auxiliary/kcfi-normalize-ints.rs
@@ -0,0 +1,7 @@
+//@ no-prefer-dynamic
+//@ needs-sanitizer-kcfi
+//@ compile-flags: -C panic=abort -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers
+
+#![feature(no_core)]
+#![crate_type = "rlib"]
+#![no_core]
diff --git a/tests/ui/target_modifiers/auxiliary/no-sanitizers.rs b/tests/ui/target_modifiers/auxiliary/no-sanitizers.rs
new file mode 100644
index 0000000000000..1d47ff6826dab
--- /dev/null
+++ b/tests/ui/target_modifiers/auxiliary/no-sanitizers.rs
@@ -0,0 +1,6 @@
+//@ no-prefer-dynamic
+//@ compile-flags: -C panic=abort
+
+#![feature(no_core)]
+#![crate_type = "rlib"]
+#![no_core]
diff --git a/tests/ui/target_modifiers/auxiliary/safestack-and-kcfi.rs b/tests/ui/target_modifiers/auxiliary/safestack-and-kcfi.rs
new file mode 100644
index 0000000000000..029744d2a1fe4
--- /dev/null
+++ b/tests/ui/target_modifiers/auxiliary/safestack-and-kcfi.rs
@@ -0,0 +1,10 @@
+//@ no-prefer-dynamic
+
+//@ needs-sanitizer-kcfi
+//@ needs-sanitizer-safestack
+
+//@ compile-flags: -C panic=abort -Zsanitizer=safestack,kcfi
+
+#![feature(no_core)]
+#![crate_type = "rlib"]
+#![no_core]
diff --git a/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.rs b/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.rs
new file mode 100644
index 0000000000000..0d1ea1637c598
--- /dev/null
+++ b/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.rs
@@ -0,0 +1,19 @@
+// For kCFI, the helper flag -Zsanitizer-cfi-normalize-integers should also be a target modifier.
+
+//@ needs-sanitizer-kcfi
+//@ aux-build:kcfi-normalize-ints.rs
+//@ compile-flags: -Cpanic=abort
+
+//@ revisions: ok wrong_flag wrong_sanitizer
+//@[ok] compile-flags: -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers
+//@[wrong_flag] compile-flags: -Zsanitizer=kcfi
+//@[wrong_sanitizer] compile-flags:
+//@[ok] check-pass
+
+#![feature(no_core)]
+//[wrong_flag]~^ ERROR mixing `-Zsanitizer-cfi-normalize-integers` will cause an ABI mismatch in crate `sanitizer_kcfi_normalize_ints`
+//[wrong_sanitizer]~^^ ERROR mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizer_kcfi_normalize_ints`
+#![crate_type = "rlib"]
+#![no_core]
+
+extern crate kcfi_normalize_ints;
diff --git a/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_flag.stderr b/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_flag.stderr
new file mode 100644
index 0000000000000..ceb406cef0da5
--- /dev/null
+++ b/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_flag.stderr
@@ -0,0 +1,13 @@
+error: mixing `-Zsanitizer-cfi-normalize-integers` will cause an ABI mismatch in crate `sanitizer_kcfi_normalize_ints`
+  --> $DIR/sanitizer-kcfi-normalize-ints.rs:13:1
+   |
+LL | #![feature(no_core)]
+   | ^
+   |
+   = help: the `-Zsanitizer-cfi-normalize-integers` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
+   = note: unset `-Zsanitizer-cfi-normalize-integers` in this crate is incompatible with `-Zsanitizer-cfi-normalize-integers=` in dependency `kcfi_normalize_ints`
+   = help: set `-Zsanitizer-cfi-normalize-integers=` in this crate or unset `-Zsanitizer-cfi-normalize-integers` in `kcfi_normalize_ints`
+   = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=sanitizer-cfi-normalize-integers` to silence this error
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_sanitizer.stderr b/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_sanitizer.stderr
new file mode 100644
index 0000000000000..98a24fcd71693
--- /dev/null
+++ b/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_sanitizer.stderr
@@ -0,0 +1,13 @@
+error: mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizer_kcfi_normalize_ints`
+  --> $DIR/sanitizer-kcfi-normalize-ints.rs:13:1
+   |
+LL | #![feature(no_core)]
+   | ^
+   |
+   = help: the `-Zsanitizer` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
+   = note: unset `-Zsanitizer` in this crate is incompatible with `-Zsanitizer=kcfi` in dependency `kcfi_normalize_ints`
+   = help: set `-Zsanitizer=kcfi` in this crate or unset `-Zsanitizer` in `kcfi_normalize_ints`
+   = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=sanitizer` to silence this error
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/target_modifiers/sanitizers-good-for-inconsistency.rs b/tests/ui/target_modifiers/sanitizers-good-for-inconsistency.rs
new file mode 100644
index 0000000000000..b94d9d2dfb423
--- /dev/null
+++ b/tests/ui/target_modifiers/sanitizers-good-for-inconsistency.rs
@@ -0,0 +1,19 @@
+// AddressSanitizer, LeakSanitizer are good to be inconsistent (they are not a target modifiers)
+
+//@ revisions: wrong_address_san wrong_leak_san
+
+//@[wrong_address_san] needs-sanitizer-address
+//@[wrong_leak_san] needs-sanitizer-leak
+
+//@ aux-build:no-sanitizers.rs
+//@ compile-flags: -Cpanic=abort
+
+//@[wrong_address_san] compile-flags: -Zsanitizer=address
+//@[wrong_leak_san] compile-flags: -Zsanitizer=leak
+//@ check-pass
+
+#![feature(no_core)]
+#![crate_type = "rlib"]
+#![no_core]
+
+extern crate no_sanitizers;
diff --git a/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_both.stderr b/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_both.stderr
new file mode 100644
index 0000000000000..440a91c7707f8
--- /dev/null
+++ b/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_both.stderr
@@ -0,0 +1,13 @@
+error: mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizers_safestack_and_kcfi`
+  --> $DIR/sanitizers-safestack-and-kcfi.rs:16:1
+   |
+LL | #![feature(no_core)]
+   | ^
+   |
+   = help: the `-Zsanitizer` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
+   = note: unset `-Zsanitizer` in this crate is incompatible with `-Zsanitizer=safestack,kcfi` in dependency `safestack_and_kcfi`
+   = help: set `-Zsanitizer=safestack,kcfi` in this crate or unset `-Zsanitizer` in `safestack_and_kcfi`
+   = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=sanitizer` to silence this error
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_kcfi.stderr b/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_kcfi.stderr
new file mode 100644
index 0000000000000..6cdd7facc3781
--- /dev/null
+++ b/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_kcfi.stderr
@@ -0,0 +1,13 @@
+error: mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizers_safestack_and_kcfi`
+  --> $DIR/sanitizers-safestack-and-kcfi.rs:16:1
+   |
+LL | #![feature(no_core)]
+   | ^
+   |
+   = help: the `-Zsanitizer` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
+   = note: `-Zsanitizer=safestack` in this crate is incompatible with `-Zsanitizer=safestack,kcfi` in dependency `safestack_and_kcfi`
+   = help: set `-Zsanitizer=safestack,kcfi` in this crate or `-Zsanitizer=safestack` in `safestack_and_kcfi`
+   = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=sanitizer` to silence this error
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_safestack.stderr b/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_safestack.stderr
new file mode 100644
index 0000000000000..ecfbcace39fe5
--- /dev/null
+++ b/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_safestack.stderr
@@ -0,0 +1,13 @@
+error: mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizers_safestack_and_kcfi`
+  --> $DIR/sanitizers-safestack-and-kcfi.rs:16:1
+   |
+LL | #![feature(no_core)]
+   | ^
+   |
+   = help: the `-Zsanitizer` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
+   = note: `-Zsanitizer=kcfi` in this crate is incompatible with `-Zsanitizer=safestack,kcfi` in dependency `safestack_and_kcfi`
+   = help: set `-Zsanitizer=safestack,kcfi` in this crate or `-Zsanitizer=kcfi` in `safestack_and_kcfi`
+   = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=sanitizer` to silence this error
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.rs b/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.rs
new file mode 100644
index 0000000000000..312f22f1609a8
--- /dev/null
+++ b/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.rs
@@ -0,0 +1,23 @@
+//@ needs-sanitizer-kcfi
+//@ needs-sanitizer-safestack
+
+//@ aux-build:safestack-and-kcfi.rs
+//@ compile-flags: -Cpanic=abort
+
+//@ revisions: good good_reverted missed_safestack missed_kcfi missed_both
+//@[good] compile-flags: -Zsanitizer=safestack,kcfi
+//@[good_reverted] compile-flags: -Zsanitizer=kcfi,safestack
+//@[missed_safestack] compile-flags: -Zsanitizer=kcfi
+//@[missed_kcfi] compile-flags: -Zsanitizer=safestack
+//@[missed_both] compile-flags:
+//@[good] check-pass
+//@[good_reverted] check-pass
+
+#![feature(no_core)]
+//[missed_safestack]~^ ERROR mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizers_safestack_and_kcfi`
+//[missed_kcfi]~^^ ERROR mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizers_safestack_and_kcfi`
+//[missed_both]~^^^ ERROR mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizers_safestack_and_kcfi`
+#![crate_type = "rlib"]
+#![no_core]
+
+extern crate safestack_and_kcfi;

From e7247df590831b6429b3e8aa520d04b8458ac531 Mon Sep 17 00:00:00 2001
From: Urgau <urgau@numericable.fr>
Date: Thu, 8 May 2025 12:43:10 +0200
Subject: [PATCH 08/14] Use intrinsics for
 `{f16,f32,f64,f128}::{minimum,maximum}` operations

---
 .../src/intrinsics/mod.rs                     |  37 +++++++
 .../rustc_codegen_gcc/src/intrinsic/mod.rs    |  36 ++++++
 compiler/rustc_codegen_llvm/src/context.rs    |  10 ++
 compiler/rustc_codegen_llvm/src/intrinsic.rs  |  10 ++
 .../src/interpret/intrinsics.rs               |  42 +++++++
 .../rustc_hir_analysis/src/check/intrinsic.rs |  18 +++
 compiler/rustc_span/src/symbol.rs             |   8 ++
 library/core/src/intrinsics/mod.rs            | 104 ++++++++++++++++--
 library/core/src/num/f128.rs                  |  50 ++++++---
 library/core/src/num/f16.rs                   |  50 ++++++---
 library/core/src/num/f32.rs                   |  50 ++++++---
 library/core/src/num/f64.rs                   |  50 ++++++---
 12 files changed, 389 insertions(+), 76 deletions(-)

diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
index e866b8962551a..9018d78b00aeb 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
@@ -1109,6 +1109,43 @@ fn codegen_regular_intrinsic_call<'tcx>(
             ret.write_cvalue(fx, old);
         }
 
+        sym::minimumf32 => {
+            intrinsic_args!(fx, args => (a, b); intrinsic);
+            let a = a.load_scalar(fx);
+            let b = b.load_scalar(fx);
+
+            let val = fx.bcx.ins().fmin(a, b);
+            let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f32));
+            ret.write_cvalue(fx, val);
+        }
+        sym::minimumf64 => {
+            intrinsic_args!(fx, args => (a, b); intrinsic);
+            let a = a.load_scalar(fx);
+            let b = b.load_scalar(fx);
+
+            let val = fx.bcx.ins().fmin(a, b);
+            let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f64));
+            ret.write_cvalue(fx, val);
+        }
+        sym::maximumf32 => {
+            intrinsic_args!(fx, args => (a, b); intrinsic);
+            let a = a.load_scalar(fx);
+            let b = b.load_scalar(fx);
+
+            let val = fx.bcx.ins().fmax(a, b);
+            let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f32));
+            ret.write_cvalue(fx, val);
+        }
+        sym::maximumf64 => {
+            intrinsic_args!(fx, args => (a, b); intrinsic);
+            let a = a.load_scalar(fx);
+            let b = b.load_scalar(fx);
+
+            let val = fx.bcx.ins().fmax(a, b);
+            let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f64));
+            ret.write_cvalue(fx, val);
+        }
+
         sym::minnumf32 => {
             intrinsic_args!(fx, args => (a, b); intrinsic);
             let a = a.load_scalar(fx);
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
index 2ed5ec4381edf..9caceca92957a 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
@@ -74,8 +74,44 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
         sym::fabsf64 => "fabs",
         sym::minnumf32 => "fminf",
         sym::minnumf64 => "fmin",
+        sym::minimumf32 => "fminimumf",
+        sym::minimumf64 => "fminimum",
+        sym::minimumf128 => {
+            // GCC doesn't have the intrinsic we want so we use the compiler-builtins one
+            // https://docs.rs/compiler_builtins/latest/compiler_builtins/math/full_availability/fn.fminimumf128.html
+            let f128_type = cx.type_f128();
+            return Some(cx.context.new_function(
+                None,
+                FunctionType::Extern,
+                f128_type,
+                &[
+                    cx.context.new_parameter(None, f128_type, "a"),
+                    cx.context.new_parameter(None, f128_type, "b"),
+                ],
+                "fminimumf128",
+                false,
+            ));
+        }
         sym::maxnumf32 => "fmaxf",
         sym::maxnumf64 => "fmax",
+        sym::maximumf32 => "fmaximumf",
+        sym::maximumf64 => "fmaximum",
+        sym::maximumf128 => {
+            // GCC doesn't have the intrinsic we want so we use the compiler-builtins one
+            // https://docs.rs/compiler_builtins/latest/compiler_builtins/math/full_availability/fn.fmaximumf128.html
+            let f128_type = cx.type_f128();
+            return Some(cx.context.new_function(
+                None,
+                FunctionType::Extern,
+                f128_type,
+                &[
+                    cx.context.new_parameter(None, f128_type, "a"),
+                    cx.context.new_parameter(None, f128_type, "b"),
+                ],
+                "fmaximumf128",
+                false,
+            ));
+        }
         sym::copysignf32 => "copysignf",
         sym::copysignf64 => "copysign",
         sym::copysignf128 => "copysignl",
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index ed50515b70716..0c6006fbc6acb 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -1009,11 +1009,21 @@ impl<'ll> CodegenCx<'ll, '_> {
         ifn!("llvm.minnum.f64", fn(t_f64, t_f64) -> t_f64);
         ifn!("llvm.minnum.f128", fn(t_f128, t_f128) -> t_f128);
 
+        ifn!("llvm.minimum.f16", fn(t_f16, t_f16) -> t_f16);
+        ifn!("llvm.minimum.f32", fn(t_f32, t_f32) -> t_f32);
+        ifn!("llvm.minimum.f64", fn(t_f64, t_f64) -> t_f64);
+        ifn!("llvm.minimum.f128", fn(t_f128, t_f128) -> t_f128);
+
         ifn!("llvm.maxnum.f16", fn(t_f16, t_f16) -> t_f16);
         ifn!("llvm.maxnum.f32", fn(t_f32, t_f32) -> t_f32);
         ifn!("llvm.maxnum.f64", fn(t_f64, t_f64) -> t_f64);
         ifn!("llvm.maxnum.f128", fn(t_f128, t_f128) -> t_f128);
 
+        ifn!("llvm.maximum.f16", fn(t_f16, t_f16) -> t_f16);
+        ifn!("llvm.maximum.f32", fn(t_f32, t_f32) -> t_f32);
+        ifn!("llvm.maximum.f64", fn(t_f64, t_f64) -> t_f64);
+        ifn!("llvm.maximum.f128", fn(t_f128, t_f128) -> t_f128);
+
         ifn!("llvm.floor.f16", fn(t_f16) -> t_f16);
         ifn!("llvm.floor.f32", fn(t_f32) -> t_f32);
         ifn!("llvm.floor.f64", fn(t_f64) -> t_f64);
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index bfaad8f2f1ef0..c68e0036d6efa 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -103,11 +103,21 @@ fn get_simple_intrinsic<'ll>(
         sym::minnumf64 => "llvm.minnum.f64",
         sym::minnumf128 => "llvm.minnum.f128",
 
+        sym::minimumf16 => "llvm.minimum.f16",
+        sym::minimumf32 => "llvm.minimum.f32",
+        sym::minimumf64 => "llvm.minimum.f64",
+        sym::minimumf128 => "llvm.minimum.f128",
+
         sym::maxnumf16 => "llvm.maxnum.f16",
         sym::maxnumf32 => "llvm.maxnum.f32",
         sym::maxnumf64 => "llvm.maxnum.f64",
         sym::maxnumf128 => "llvm.maxnum.f128",
 
+        sym::maximumf16 => "llvm.maximum.f16",
+        sym::maximumf32 => "llvm.maximum.f32",
+        sym::maximumf64 => "llvm.maximum.f64",
+        sym::maximumf128 => "llvm.maximum.f128",
+
         sym::copysignf16 => "llvm.copysign.f16",
         sym::copysignf32 => "llvm.copysign.f32",
         sym::copysignf64 => "llvm.copysign.f64",
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 04a8ed1e0f1e9..090b2a692cfc3 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -493,11 +493,21 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             sym::minnumf64 => self.float_min_intrinsic::<Double>(args, dest)?,
             sym::minnumf128 => self.float_min_intrinsic::<Quad>(args, dest)?,
 
+            sym::minimumf16 => self.float_minimum_intrinsic::<Half>(args, dest)?,
+            sym::minimumf32 => self.float_minimum_intrinsic::<Single>(args, dest)?,
+            sym::minimumf64 => self.float_minimum_intrinsic::<Double>(args, dest)?,
+            sym::minimumf128 => self.float_minimum_intrinsic::<Quad>(args, dest)?,
+
             sym::maxnumf16 => self.float_max_intrinsic::<Half>(args, dest)?,
             sym::maxnumf32 => self.float_max_intrinsic::<Single>(args, dest)?,
             sym::maxnumf64 => self.float_max_intrinsic::<Double>(args, dest)?,
             sym::maxnumf128 => self.float_max_intrinsic::<Quad>(args, dest)?,
 
+            sym::maximumf16 => self.float_maximum_intrinsic::<Half>(args, dest)?,
+            sym::maximumf32 => self.float_maximum_intrinsic::<Single>(args, dest)?,
+            sym::maximumf64 => self.float_maximum_intrinsic::<Double>(args, dest)?,
+            sym::maximumf128 => self.float_maximum_intrinsic::<Quad>(args, dest)?,
+
             sym::copysignf16 => self.float_copysign_intrinsic::<Half>(args, dest)?,
             sym::copysignf32 => self.float_copysign_intrinsic::<Single>(args, dest)?,
             sym::copysignf64 => self.float_copysign_intrinsic::<Double>(args, dest)?,
@@ -830,6 +840,38 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         interp_ok(())
     }
 
+    fn float_minimum_intrinsic<F>(
+        &mut self,
+        args: &[OpTy<'tcx, M::Provenance>],
+        dest: &MPlaceTy<'tcx, M::Provenance>,
+    ) -> InterpResult<'tcx, ()>
+    where
+        F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>,
+    {
+        let a: F = self.read_scalar(&args[0])?.to_float()?;
+        let b: F = self.read_scalar(&args[1])?.to_float()?;
+        let res = a.minimum(b);
+        let res = self.adjust_nan(res, &[a, b]);
+        self.write_scalar(res, dest)?;
+        interp_ok(())
+    }
+
+    fn float_maximum_intrinsic<F>(
+        &mut self,
+        args: &[OpTy<'tcx, M::Provenance>],
+        dest: &MPlaceTy<'tcx, M::Provenance>,
+    ) -> InterpResult<'tcx, ()>
+    where
+        F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>,
+    {
+        let a: F = self.read_scalar(&args[0])?.to_float()?;
+        let b: F = self.read_scalar(&args[1])?.to_float()?;
+        let res = a.maximum(b);
+        let res = self.adjust_nan(res, &[a, b]);
+        self.write_scalar(res, dest)?;
+        interp_ok(())
+    }
+
     fn float_copysign_intrinsic<F>(
         &mut self,
         args: &[OpTy<'tcx, M::Provenance>],
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 692784bf1714d..9fd158ad154d8 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -103,10 +103,18 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
         | sym::minnumf32
         | sym::minnumf64
         | sym::minnumf128
+        | sym::minimumf16
+        | sym::minimumf32
+        | sym::minimumf64
+        | sym::minimumf128
         | sym::maxnumf16
         | sym::maxnumf32
         | sym::maxnumf64
         | sym::maxnumf128
+        | sym::maximumf16
+        | sym::maximumf32
+        | sym::maximumf64
+        | sym::maximumf128
         | sym::rustc_peek
         | sym::type_name
         | sym::forget
@@ -374,11 +382,21 @@ pub(crate) fn check_intrinsic_type(
             sym::minnumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
             sym::minnumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
 
+            sym::minimumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
+            sym::minimumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
+            sym::minimumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
+            sym::minimumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
+
             sym::maxnumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
             sym::maxnumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
             sym::maxnumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
             sym::maxnumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
 
+            sym::maximumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
+            sym::maximumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
+            sym::maximumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
+            sym::maximumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
+
             sym::copysignf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
             sym::copysignf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
             sym::copysignf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 40cec4083089a..a0420eccfb000 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1301,6 +1301,10 @@ symbols! {
         match_beginning_vert,
         match_default_bindings,
         matches_macro,
+        maximumf128,
+        maximumf16,
+        maximumf32,
+        maximumf64,
         maxnumf128,
         maxnumf16,
         maxnumf32,
@@ -1335,6 +1339,10 @@ symbols! {
         min_generic_const_args,
         min_specialization,
         min_type_alias_impl_trait,
+        minimumf128,
+        minimumf16,
+        minimumf32,
+        minimumf64,
         minnumf128,
         minnumf16,
         minnumf32,
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index 5649736e40492..002ef418ae237 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -3928,7 +3928,7 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
     }
 }
 
-/// Returns the minimum of two `f16` values.
+/// Returns the minimum (IEEE 754-2008 minNum) of two `f16` values.
 ///
 /// Note that, unlike most intrinsics, this is safe to call;
 /// it does not require an `unsafe` block.
@@ -3941,7 +3941,7 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
 #[rustc_intrinsic]
 pub const fn minnumf16(x: f16, y: f16) -> f16;
 
-/// Returns the minimum of two `f32` values.
+/// Returns the minimum (IEEE 754-2008 minNum) of two `f32` values.
 ///
 /// Note that, unlike most intrinsics, this is safe to call;
 /// it does not require an `unsafe` block.
@@ -3955,7 +3955,7 @@ pub const fn minnumf16(x: f16, y: f16) -> f16;
 #[rustc_intrinsic]
 pub const fn minnumf32(x: f32, y: f32) -> f32;
 
-/// Returns the minimum of two `f64` values.
+/// Returns the minimum (IEEE 754-2008 minNum) of two `f64` values.
 ///
 /// Note that, unlike most intrinsics, this is safe to call;
 /// it does not require an `unsafe` block.
@@ -3969,7 +3969,7 @@ pub const fn minnumf32(x: f32, y: f32) -> f32;
 #[rustc_intrinsic]
 pub const fn minnumf64(x: f64, y: f64) -> f64;
 
-/// Returns the minimum of two `f128` values.
+/// Returns the minimum (IEEE 754-2008 minNum) of two `f128` values.
 ///
 /// Note that, unlike most intrinsics, this is safe to call;
 /// it does not require an `unsafe` block.
@@ -3982,7 +3982,51 @@ pub const fn minnumf64(x: f64, y: f64) -> f64;
 #[rustc_intrinsic]
 pub const fn minnumf128(x: f128, y: f128) -> f128;
 
-/// Returns the maximum of two `f16` values.
+/// Returns the minimum (IEEE 754-2019 minimum) of two `f16` values.
+///
+/// Note that, unlike most intrinsics, this is safe to call;
+/// it does not require an `unsafe` block.
+/// Therefore, implementations must not require the user to uphold
+/// any safety invariants.
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[cfg(not(bootstrap))]
+pub const fn minimumf16(x: f16, y: f16) -> f16;
+
+/// Returns the minimum (IEEE 754-2019 minimum) of two `f32` values.
+///
+/// Note that, unlike most intrinsics, this is safe to call;
+/// it does not require an `unsafe` block.
+/// Therefore, implementations must not require the user to uphold
+/// any safety invariants.
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[cfg(not(bootstrap))]
+pub const fn minimumf32(x: f32, y: f32) -> f32;
+
+/// Returns the minimum (IEEE 754-2019 minimum) of two `f64` values.
+///
+/// Note that, unlike most intrinsics, this is safe to call;
+/// it does not require an `unsafe` block.
+/// Therefore, implementations must not require the user to uphold
+/// any safety invariants.
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[cfg(not(bootstrap))]
+pub const fn minimumf64(x: f64, y: f64) -> f64;
+
+/// Returns the minimum (IEEE 754-2019 minimum) of two `f128` values.
+///
+/// Note that, unlike most intrinsics, this is safe to call;
+/// it does not require an `unsafe` block.
+/// Therefore, implementations must not require the user to uphold
+/// any safety invariants.
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[cfg(not(bootstrap))]
+pub const fn minimumf128(x: f128, y: f128) -> f128;
+
+/// Returns the maximum (IEEE 754-2008 maxNum) of two `f16` values.
 ///
 /// Note that, unlike most intrinsics, this is safe to call;
 /// it does not require an `unsafe` block.
@@ -3995,7 +4039,7 @@ pub const fn minnumf128(x: f128, y: f128) -> f128;
 #[rustc_intrinsic]
 pub const fn maxnumf16(x: f16, y: f16) -> f16;
 
-/// Returns the maximum of two `f32` values.
+/// Returns the maximum (IEEE 754-2008 maxNum) of two `f32` values.
 ///
 /// Note that, unlike most intrinsics, this is safe to call;
 /// it does not require an `unsafe` block.
@@ -4009,7 +4053,7 @@ pub const fn maxnumf16(x: f16, y: f16) -> f16;
 #[rustc_intrinsic]
 pub const fn maxnumf32(x: f32, y: f32) -> f32;
 
-/// Returns the maximum of two `f64` values.
+/// Returns the maximum (IEEE 754-2008 maxNum) of two `f64` values.
 ///
 /// Note that, unlike most intrinsics, this is safe to call;
 /// it does not require an `unsafe` block.
@@ -4023,7 +4067,7 @@ pub const fn maxnumf32(x: f32, y: f32) -> f32;
 #[rustc_intrinsic]
 pub const fn maxnumf64(x: f64, y: f64) -> f64;
 
-/// Returns the maximum of two `f128` values.
+/// Returns the maximum (IEEE 754-2008 maxNum) of two `f128` values.
 ///
 /// Note that, unlike most intrinsics, this is safe to call;
 /// it does not require an `unsafe` block.
@@ -4036,6 +4080,50 @@ pub const fn maxnumf64(x: f64, y: f64) -> f64;
 #[rustc_intrinsic]
 pub const fn maxnumf128(x: f128, y: f128) -> f128;
 
+/// Returns the maximum (IEEE 754-2019 maximum) of two `f16` values.
+///
+/// Note that, unlike most intrinsics, this is safe to call;
+/// it does not require an `unsafe` block.
+/// Therefore, implementations must not require the user to uphold
+/// any safety invariants.
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[cfg(not(bootstrap))]
+pub const fn maximumf16(x: f16, y: f16) -> f16;
+
+/// Returns the maximum (IEEE 754-2019 maximum) of two `f32` values.
+///
+/// Note that, unlike most intrinsics, this is safe to call;
+/// it does not require an `unsafe` block.
+/// Therefore, implementations must not require the user to uphold
+/// any safety invariants.
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[cfg(not(bootstrap))]
+pub const fn maximumf32(x: f32, y: f32) -> f32;
+
+/// Returns the maximum (IEEE 754-2019 maximum) of two `f64` values.
+///
+/// Note that, unlike most intrinsics, this is safe to call;
+/// it does not require an `unsafe` block.
+/// Therefore, implementations must not require the user to uphold
+/// any safety invariants.
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[cfg(not(bootstrap))]
+pub const fn maximumf64(x: f64, y: f64) -> f64;
+
+/// Returns the maximum (IEEE 754-2019 maximum) of two `f128` values.
+///
+/// Note that, unlike most intrinsics, this is safe to call;
+/// it does not require an `unsafe` block.
+/// Therefore, implementations must not require the user to uphold
+/// any safety invariants.
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[cfg(not(bootstrap))]
+pub const fn maximumf128(x: f128, y: f128) -> f128;
+
 /// Returns the absolute value of an `f16`.
 ///
 /// The stabilized version of this intrinsic is
diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs
index b1119d4899bab..97e24a19ea614 100644
--- a/library/core/src/num/f128.rs
+++ b/library/core/src/num/f128.rs
@@ -755,16 +755,24 @@ impl f128 {
     #[inline]
     #[unstable(feature = "f128", issue = "116909")]
     // #[unstable(feature = "float_minimum_maximum", issue = "91079")]
+    #[rustc_const_unstable(feature = "f128", issue = "116909")]
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     pub const fn maximum(self, other: f128) -> f128 {
-        if self > other {
-            self
-        } else if other > self {
-            other
-        } else if self == other {
-            if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
-        } else {
-            self + other
+        #[cfg(not(bootstrap))]
+        {
+            intrinsics::maximumf128(self, other)
+        }
+        #[cfg(bootstrap)]
+        {
+            if self > other {
+                self
+            } else if other > self {
+                other
+            } else if self == other {
+                if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
+            } else {
+                self + other
+            }
         }
     }
 
@@ -796,17 +804,25 @@ impl f128 {
     #[inline]
     #[unstable(feature = "f128", issue = "116909")]
     // #[unstable(feature = "float_minimum_maximum", issue = "91079")]
+    #[rustc_const_unstable(feature = "f128", issue = "116909")]
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     pub const fn minimum(self, other: f128) -> f128 {
-        if self < other {
-            self
-        } else if other < self {
-            other
-        } else if self == other {
-            if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
-        } else {
-            // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
-            self + other
+        #[cfg(not(bootstrap))]
+        {
+            intrinsics::minimumf128(self, other)
+        }
+        #[cfg(bootstrap)]
+        {
+            if self < other {
+                self
+            } else if other < self {
+                other
+            } else if self == other {
+                if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
+            } else {
+                // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
+                self + other
+            }
         }
     }
 
diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs
index 54e38d9e1a6f1..d3af78123c84e 100644
--- a/library/core/src/num/f16.rs
+++ b/library/core/src/num/f16.rs
@@ -744,16 +744,24 @@ impl f16 {
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
     // #[unstable(feature = "float_minimum_maximum", issue = "91079")]
+    #[rustc_const_unstable(feature = "f16", issue = "116909")]
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     pub const fn maximum(self, other: f16) -> f16 {
-        if self > other {
-            self
-        } else if other > self {
-            other
-        } else if self == other {
-            if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
-        } else {
-            self + other
+        #[cfg(not(bootstrap))]
+        {
+            intrinsics::maximumf16(self, other)
+        }
+        #[cfg(bootstrap)]
+        {
+            if self > other {
+                self
+            } else if other > self {
+                other
+            } else if self == other {
+                if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
+            } else {
+                self + other
+            }
         }
     }
 
@@ -784,17 +792,25 @@ impl f16 {
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
     // #[unstable(feature = "float_minimum_maximum", issue = "91079")]
+    #[rustc_const_unstable(feature = "f16", issue = "116909")]
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     pub const fn minimum(self, other: f16) -> f16 {
-        if self < other {
-            self
-        } else if other < self {
-            other
-        } else if self == other {
-            if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
-        } else {
-            // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
-            self + other
+        #[cfg(not(bootstrap))]
+        {
+            intrinsics::minimumf16(self, other)
+        }
+        #[cfg(bootstrap)]
+        {
+            if self < other {
+                self
+            } else if other < self {
+                other
+            } else if self == other {
+                if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
+            } else {
+                // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
+                self + other
+            }
         }
     }
 
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index e66fd3bb52b86..9ee6c3f5f990e 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -942,16 +942,24 @@ impl f32 {
     /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     #[unstable(feature = "float_minimum_maximum", issue = "91079")]
+    #[rustc_const_unstable(feature = "float_minimum_maximum", issue = "91079")]
     #[inline]
     pub const fn maximum(self, other: f32) -> f32 {
-        if self > other {
-            self
-        } else if other > self {
-            other
-        } else if self == other {
-            if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
-        } else {
-            self + other
+        #[cfg(not(bootstrap))]
+        {
+            intrinsics::maximumf32(self, other)
+        }
+        #[cfg(bootstrap)]
+        {
+            if self > other {
+                self
+            } else if other > self {
+                other
+            } else if self == other {
+                if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
+            } else {
+                self + other
+            }
         }
     }
 
@@ -977,17 +985,25 @@ impl f32 {
     /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     #[unstable(feature = "float_minimum_maximum", issue = "91079")]
+    #[rustc_const_unstable(feature = "float_minimum_maximum", issue = "91079")]
     #[inline]
     pub const fn minimum(self, other: f32) -> f32 {
-        if self < other {
-            self
-        } else if other < self {
-            other
-        } else if self == other {
-            if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
-        } else {
-            // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
-            self + other
+        #[cfg(not(bootstrap))]
+        {
+            intrinsics::minimumf32(self, other)
+        }
+        #[cfg(bootstrap)]
+        {
+            if self < other {
+                self
+            } else if other < self {
+                other
+            } else if self == other {
+                if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
+            } else {
+                // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
+                self + other
+            }
         }
     }
 
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 2d791437b2825..900b936268a5b 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -960,16 +960,24 @@ impl f64 {
     /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     #[unstable(feature = "float_minimum_maximum", issue = "91079")]
+    #[rustc_const_unstable(feature = "float_minimum_maximum", issue = "91079")]
     #[inline]
     pub const fn maximum(self, other: f64) -> f64 {
-        if self > other {
-            self
-        } else if other > self {
-            other
-        } else if self == other {
-            if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
-        } else {
-            self + other
+        #[cfg(not(bootstrap))]
+        {
+            intrinsics::maximumf64(self, other)
+        }
+        #[cfg(bootstrap)]
+        {
+            if self > other {
+                self
+            } else if other > self {
+                other
+            } else if self == other {
+                if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
+            } else {
+                self + other
+            }
         }
     }
 
@@ -995,17 +1003,25 @@ impl f64 {
     /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     #[unstable(feature = "float_minimum_maximum", issue = "91079")]
+    #[rustc_const_unstable(feature = "float_minimum_maximum", issue = "91079")]
     #[inline]
     pub const fn minimum(self, other: f64) -> f64 {
-        if self < other {
-            self
-        } else if other < self {
-            other
-        } else if self == other {
-            if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
-        } else {
-            // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
-            self + other
+        #[cfg(not(bootstrap))]
+        {
+            intrinsics::minimumf64(self, other)
+        }
+        #[cfg(bootstrap)]
+        {
+            if self < other {
+                self
+            } else if other < self {
+                other
+            } else if self == other {
+                if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
+            } else {
+                // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
+                self + other
+            }
         }
     }
 

From 79dfd0a472c7a994bfe090cc95034b36d38e6b53 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Mon, 5 May 2025 15:26:06 +0200
Subject: [PATCH 09/14] remove 'unordered' atomic intrinsics

---
 compiler/rustc_codegen_gcc/src/builder.rs       |  1 -
 compiler/rustc_codegen_llvm/src/llvm/ffi.rs     |  2 +-
 compiler/rustc_codegen_ssa/src/common.rs        |  1 -
 compiler/rustc_codegen_ssa/src/mir/intrinsic.rs |  1 -
 library/core/src/intrinsics/mod.rs              | 12 ------------
 5 files changed, 1 insertion(+), 16 deletions(-)

diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs
index 6720f6186d16e..9e5ebf3a9a40b 100644
--- a/compiler/rustc_codegen_gcc/src/builder.rs
+++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -2454,7 +2454,6 @@ impl ToGccOrdering for AtomicOrdering {
         use MemOrdering::*;
 
         let ordering = match self {
-            AtomicOrdering::Unordered => __ATOMIC_RELAXED,
             AtomicOrdering::Relaxed => __ATOMIC_RELAXED, // TODO(antoyo): check if that's the same.
             AtomicOrdering::Acquire => __ATOMIC_ACQUIRE,
             AtomicOrdering::Release => __ATOMIC_RELEASE,
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index ffb490dcdc22b..a249cb86ed42e 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -415,6 +415,7 @@ impl AtomicRmwBinOp {
 pub(crate) enum AtomicOrdering {
     #[allow(dead_code)]
     NotAtomic = 0,
+    #[allow(dead_code)]
     Unordered = 1,
     Monotonic = 2,
     // Consume = 3,  // Not specified yet.
@@ -428,7 +429,6 @@ impl AtomicOrdering {
     pub(crate) fn from_generic(ao: rustc_codegen_ssa::common::AtomicOrdering) -> Self {
         use rustc_codegen_ssa::common::AtomicOrdering as Common;
         match ao {
-            Common::Unordered => Self::Unordered,
             Common::Relaxed => Self::Monotonic,
             Common::Acquire => Self::Acquire,
             Common::Release => Self::Release,
diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs
index 965bd34ac147b..6d0c9d8d06645 100644
--- a/compiler/rustc_codegen_ssa/src/common.rs
+++ b/compiler/rustc_codegen_ssa/src/common.rs
@@ -61,7 +61,6 @@ pub enum AtomicRmwBinOp {
 
 #[derive(Copy, Clone, Debug)]
 pub enum AtomicOrdering {
-    Unordered,
     Relaxed,
     Acquire,
     Release,
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
index 63025a4574fca..b0fcfee2adf5f 100644
--- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
@@ -336,7 +336,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 };
 
                 let parse_ordering = |bx: &Bx, s| match s {
-                    "unordered" => Unordered,
                     "relaxed" => Relaxed,
                     "acquire" => Acquire,
                     "release" => Release,
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index 5649736e40492..53db7795b8aaa 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -439,12 +439,6 @@ pub unsafe fn atomic_load_acquire<T: Copy>(src: *const T) -> T;
 #[rustc_intrinsic]
 #[rustc_nounwind]
 pub unsafe fn atomic_load_relaxed<T: Copy>(src: *const T) -> T;
-/// Do NOT use this intrinsic; "unordered" operations do not exist in our memory model!
-/// In terms of the Rust Abstract Machine, this operation is equivalent to `src.read()`,
-/// i.e., it performs a non-atomic read.
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_load_unordered<T: Copy>(src: *const T) -> T;
 
 /// Stores the value at the specified memory location.
 /// `T` must be an integer or pointer type.
@@ -473,12 +467,6 @@ pub unsafe fn atomic_store_release<T: Copy>(dst: *mut T, val: T);
 #[rustc_intrinsic]
 #[rustc_nounwind]
 pub unsafe fn atomic_store_relaxed<T: Copy>(dst: *mut T, val: T);
-/// Do NOT use this intrinsic; "unordered" operations do not exist in our memory model!
-/// In terms of the Rust Abstract Machine, this operation is equivalent to `dst.write(val)`,
-/// i.e., it performs a non-atomic write.
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_store_unordered<T: Copy>(dst: *mut T, val: T);
 
 /// Stores the value at the specified memory location, returning the old value.
 /// `T` must be an integer or pointer type.

From 35679bad981e1551138a8b367c0571b0a5928a27 Mon Sep 17 00:00:00 2001
From: Daniel Paoliello <danpao@microsoft.com>
Date: Fri, 9 May 2025 09:36:33 -0700
Subject: [PATCH 10/14] Enable non-leaf Frame Pointers for Arm64EC Windows

---
 .../src/spec/targets/arm64ec_pc_windows_msvc.rs           | 8 +++++++-
 tests/assembly/asm/aarch64-types.rs                       | 6 ++++--
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs
index bb3e3e544cba4..8f93523909e37 100644
--- a/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs
@@ -1,4 +1,4 @@
-use crate::spec::{LinkerFlavor, Lld, Target, TargetMetadata, add_link_args, base};
+use crate::spec::{FramePointer, LinkerFlavor, Lld, Target, TargetMetadata, add_link_args, base};
 
 pub(crate) fn target() -> Target {
     let mut base = base::windows_msvc::opts();
@@ -10,6 +10,12 @@ pub(crate) fn target() -> Target {
         &["/machine:arm64ec", "softintrin.lib"],
     );
 
+    // Microsoft recommends enabling frame pointers on Arm64 Windows.
+    // From https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#integer-registers
+    // "The frame pointer (x29) is required for compatibility with fast stack walking used by ETW
+    // and other services. It must point to the previous {x29, x30} pair on the stack."
+    base.frame_pointer = FramePointer::NonLeaf;
+
     Target {
         llvm_target: "arm64ec-pc-windows-msvc".into(),
         metadata: TargetMetadata {
diff --git a/tests/assembly/asm/aarch64-types.rs b/tests/assembly/asm/aarch64-types.rs
index 8e4e085032534..ad2770d43e37d 100644
--- a/tests/assembly/asm/aarch64-types.rs
+++ b/tests/assembly/asm/aarch64-types.rs
@@ -86,10 +86,12 @@ pub unsafe fn sym_static() {
 
 // Regression test for #75761
 // CHECK-LABEL: {{("#)?}}issue_75761{{"?}}
-// CHECK: str {{.*}}x30
+// aarch64: str {{.*}}x30
+// arm64ec: stp {{.*}}x30
 // CHECK: //APP
 // CHECK: //NO_APP
-// CHECK: ldr {{.*}}x30
+// aarch64: ldr {{.*}}x30
+// arm64ec: ldp {{.*}}x30
 #[no_mangle]
 pub unsafe fn issue_75761() {
     asm!("", out("v0") _, out("x30") _);

From dc69020aa49914ced62bcaf2371068e2c44bc46c Mon Sep 17 00:00:00 2001
From: Urgau <urgau@numericable.fr>
Date: Thu, 8 May 2025 22:13:13 +0200
Subject: [PATCH 11/14] Add intrinsic fallback for
 `{minimum,maximum}{16,32,64,128}`

---
 library/core/src/intrinsics/mod.rs | 124 +++++++++++++++++++++++------
 library/core/src/num/f128.rs       |  37 +--------
 library/core/src/num/f16.rs        |  37 +--------
 library/core/src/num/f32.rs        |  37 +--------
 library/core/src/num/f64.rs        |  37 +--------
 5 files changed, 108 insertions(+), 164 deletions(-)

diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index 002ef418ae237..d070892358360 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -3989,9 +3989,19 @@ pub const fn minnumf128(x: f128, y: f128) -> f128;
 /// Therefore, implementations must not require the user to uphold
 /// any safety invariants.
 #[rustc_nounwind]
-#[rustc_intrinsic]
-#[cfg(not(bootstrap))]
-pub const fn minimumf16(x: f16, y: f16) -> f16;
+#[cfg_attr(not(bootstrap), rustc_intrinsic)]
+pub const fn minimumf16(x: f16, y: f16) -> f16 {
+    if x < y {
+        x
+    } else if y < x {
+        y
+    } else if x == y {
+        if x.is_sign_negative() && y.is_sign_positive() { x } else { y }
+    } else {
+        // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
+        x + y
+    }
+}
 
 /// Returns the minimum (IEEE 754-2019 minimum) of two `f32` values.
 ///
@@ -4000,9 +4010,19 @@ pub const fn minimumf16(x: f16, y: f16) -> f16;
 /// Therefore, implementations must not require the user to uphold
 /// any safety invariants.
 #[rustc_nounwind]
-#[rustc_intrinsic]
-#[cfg(not(bootstrap))]
-pub const fn minimumf32(x: f32, y: f32) -> f32;
+#[cfg_attr(not(bootstrap), rustc_intrinsic)]
+pub const fn minimumf32(x: f32, y: f32) -> f32 {
+    if x < y {
+        x
+    } else if y < x {
+        y
+    } else if x == y {
+        if x.is_sign_negative() && y.is_sign_positive() { x } else { y }
+    } else {
+        // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
+        x + y
+    }
+}
 
 /// Returns the minimum (IEEE 754-2019 minimum) of two `f64` values.
 ///
@@ -4011,9 +4031,19 @@ pub const fn minimumf32(x: f32, y: f32) -> f32;
 /// Therefore, implementations must not require the user to uphold
 /// any safety invariants.
 #[rustc_nounwind]
-#[rustc_intrinsic]
-#[cfg(not(bootstrap))]
-pub const fn minimumf64(x: f64, y: f64) -> f64;
+#[cfg_attr(not(bootstrap), rustc_intrinsic)]
+pub const fn minimumf64(x: f64, y: f64) -> f64 {
+    if x < y {
+        x
+    } else if y < x {
+        y
+    } else if x == y {
+        if x.is_sign_negative() && y.is_sign_positive() { x } else { y }
+    } else {
+        // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
+        x + y
+    }
+}
 
 /// Returns the minimum (IEEE 754-2019 minimum) of two `f128` values.
 ///
@@ -4022,9 +4052,19 @@ pub const fn minimumf64(x: f64, y: f64) -> f64;
 /// Therefore, implementations must not require the user to uphold
 /// any safety invariants.
 #[rustc_nounwind]
-#[rustc_intrinsic]
-#[cfg(not(bootstrap))]
-pub const fn minimumf128(x: f128, y: f128) -> f128;
+#[cfg_attr(not(bootstrap), rustc_intrinsic)]
+pub const fn minimumf128(x: f128, y: f128) -> f128 {
+    if x < y {
+        x
+    } else if y < x {
+        y
+    } else if x == y {
+        if x.is_sign_negative() && y.is_sign_positive() { x } else { y }
+    } else {
+        // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
+        x + y
+    }
+}
 
 /// Returns the maximum (IEEE 754-2008 maxNum) of two `f16` values.
 ///
@@ -4087,9 +4127,18 @@ pub const fn maxnumf128(x: f128, y: f128) -> f128;
 /// Therefore, implementations must not require the user to uphold
 /// any safety invariants.
 #[rustc_nounwind]
-#[rustc_intrinsic]
-#[cfg(not(bootstrap))]
-pub const fn maximumf16(x: f16, y: f16) -> f16;
+#[cfg_attr(not(bootstrap), rustc_intrinsic)]
+pub const fn maximumf16(x: f16, y: f16) -> f16 {
+    if x > y {
+        x
+    } else if y > x {
+        y
+    } else if x == y {
+        if x.is_sign_positive() && y.is_sign_negative() { x } else { y }
+    } else {
+        x + y
+    }
+}
 
 /// Returns the maximum (IEEE 754-2019 maximum) of two `f32` values.
 ///
@@ -4098,9 +4147,18 @@ pub const fn maximumf16(x: f16, y: f16) -> f16;
 /// Therefore, implementations must not require the user to uphold
 /// any safety invariants.
 #[rustc_nounwind]
-#[rustc_intrinsic]
-#[cfg(not(bootstrap))]
-pub const fn maximumf32(x: f32, y: f32) -> f32;
+#[cfg_attr(not(bootstrap), rustc_intrinsic)]
+pub const fn maximumf32(x: f32, y: f32) -> f32 {
+    if x > y {
+        x
+    } else if y > x {
+        y
+    } else if x == y {
+        if x.is_sign_positive() && y.is_sign_negative() { x } else { y }
+    } else {
+        x + y
+    }
+}
 
 /// Returns the maximum (IEEE 754-2019 maximum) of two `f64` values.
 ///
@@ -4109,9 +4167,18 @@ pub const fn maximumf32(x: f32, y: f32) -> f32;
 /// Therefore, implementations must not require the user to uphold
 /// any safety invariants.
 #[rustc_nounwind]
-#[rustc_intrinsic]
-#[cfg(not(bootstrap))]
-pub const fn maximumf64(x: f64, y: f64) -> f64;
+#[cfg_attr(not(bootstrap), rustc_intrinsic)]
+pub const fn maximumf64(x: f64, y: f64) -> f64 {
+    if x > y {
+        x
+    } else if y > x {
+        y
+    } else if x == y {
+        if x.is_sign_positive() && y.is_sign_negative() { x } else { y }
+    } else {
+        x + y
+    }
+}
 
 /// Returns the maximum (IEEE 754-2019 maximum) of two `f128` values.
 ///
@@ -4120,9 +4187,18 @@ pub const fn maximumf64(x: f64, y: f64) -> f64;
 /// Therefore, implementations must not require the user to uphold
 /// any safety invariants.
 #[rustc_nounwind]
-#[rustc_intrinsic]
-#[cfg(not(bootstrap))]
-pub const fn maximumf128(x: f128, y: f128) -> f128;
+#[cfg_attr(not(bootstrap), rustc_intrinsic)]
+pub const fn maximumf128(x: f128, y: f128) -> f128 {
+    if x > y {
+        x
+    } else if y > x {
+        y
+    } else if x == y {
+        if x.is_sign_positive() && y.is_sign_negative() { x } else { y }
+    } else {
+        x + y
+    }
+}
 
 /// Returns the absolute value of an `f16`.
 ///
diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs
index 97e24a19ea614..8020b36c6fa6e 100644
--- a/library/core/src/num/f128.rs
+++ b/library/core/src/num/f128.rs
@@ -755,25 +755,9 @@ impl f128 {
     #[inline]
     #[unstable(feature = "f128", issue = "116909")]
     // #[unstable(feature = "float_minimum_maximum", issue = "91079")]
-    #[rustc_const_unstable(feature = "f128", issue = "116909")]
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     pub const fn maximum(self, other: f128) -> f128 {
-        #[cfg(not(bootstrap))]
-        {
-            intrinsics::maximumf128(self, other)
-        }
-        #[cfg(bootstrap)]
-        {
-            if self > other {
-                self
-            } else if other > self {
-                other
-            } else if self == other {
-                if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
-            } else {
-                self + other
-            }
-        }
+        intrinsics::maximumf128(self, other)
     }
 
     /// Returns the minimum of the two numbers, propagating NaN.
@@ -804,26 +788,9 @@ impl f128 {
     #[inline]
     #[unstable(feature = "f128", issue = "116909")]
     // #[unstable(feature = "float_minimum_maximum", issue = "91079")]
-    #[rustc_const_unstable(feature = "f128", issue = "116909")]
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     pub const fn minimum(self, other: f128) -> f128 {
-        #[cfg(not(bootstrap))]
-        {
-            intrinsics::minimumf128(self, other)
-        }
-        #[cfg(bootstrap)]
-        {
-            if self < other {
-                self
-            } else if other < self {
-                other
-            } else if self == other {
-                if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
-            } else {
-                // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
-                self + other
-            }
-        }
+        intrinsics::minimumf128(self, other)
     }
 
     /// Calculates the midpoint (average) between `self` and `rhs`.
diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs
index d3af78123c84e..68201400a1d5d 100644
--- a/library/core/src/num/f16.rs
+++ b/library/core/src/num/f16.rs
@@ -744,25 +744,9 @@ impl f16 {
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
     // #[unstable(feature = "float_minimum_maximum", issue = "91079")]
-    #[rustc_const_unstable(feature = "f16", issue = "116909")]
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     pub const fn maximum(self, other: f16) -> f16 {
-        #[cfg(not(bootstrap))]
-        {
-            intrinsics::maximumf16(self, other)
-        }
-        #[cfg(bootstrap)]
-        {
-            if self > other {
-                self
-            } else if other > self {
-                other
-            } else if self == other {
-                if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
-            } else {
-                self + other
-            }
-        }
+        intrinsics::maximumf16(self, other)
     }
 
     /// Returns the minimum of the two numbers, propagating NaN.
@@ -792,26 +776,9 @@ impl f16 {
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
     // #[unstable(feature = "float_minimum_maximum", issue = "91079")]
-    #[rustc_const_unstable(feature = "f16", issue = "116909")]
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     pub const fn minimum(self, other: f16) -> f16 {
-        #[cfg(not(bootstrap))]
-        {
-            intrinsics::minimumf16(self, other)
-        }
-        #[cfg(bootstrap)]
-        {
-            if self < other {
-                self
-            } else if other < self {
-                other
-            } else if self == other {
-                if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
-            } else {
-                // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
-                self + other
-            }
-        }
+        intrinsics::minimumf16(self, other)
     }
 
     /// Calculates the midpoint (average) between `self` and `rhs`.
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index 9ee6c3f5f990e..da241785d6427 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -942,25 +942,9 @@ impl f32 {
     /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     #[unstable(feature = "float_minimum_maximum", issue = "91079")]
-    #[rustc_const_unstable(feature = "float_minimum_maximum", issue = "91079")]
     #[inline]
     pub const fn maximum(self, other: f32) -> f32 {
-        #[cfg(not(bootstrap))]
-        {
-            intrinsics::maximumf32(self, other)
-        }
-        #[cfg(bootstrap)]
-        {
-            if self > other {
-                self
-            } else if other > self {
-                other
-            } else if self == other {
-                if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
-            } else {
-                self + other
-            }
-        }
+        intrinsics::maximumf32(self, other)
     }
 
     /// Returns the minimum of the two numbers, propagating NaN.
@@ -985,26 +969,9 @@ impl f32 {
     /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     #[unstable(feature = "float_minimum_maximum", issue = "91079")]
-    #[rustc_const_unstable(feature = "float_minimum_maximum", issue = "91079")]
     #[inline]
     pub const fn minimum(self, other: f32) -> f32 {
-        #[cfg(not(bootstrap))]
-        {
-            intrinsics::minimumf32(self, other)
-        }
-        #[cfg(bootstrap)]
-        {
-            if self < other {
-                self
-            } else if other < self {
-                other
-            } else if self == other {
-                if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
-            } else {
-                // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
-                self + other
-            }
-        }
+        intrinsics::minimumf32(self, other)
     }
 
     /// Calculates the midpoint (average) between `self` and `rhs`.
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 900b936268a5b..c8544771a9047 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -960,25 +960,9 @@ impl f64 {
     /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     #[unstable(feature = "float_minimum_maximum", issue = "91079")]
-    #[rustc_const_unstable(feature = "float_minimum_maximum", issue = "91079")]
     #[inline]
     pub const fn maximum(self, other: f64) -> f64 {
-        #[cfg(not(bootstrap))]
-        {
-            intrinsics::maximumf64(self, other)
-        }
-        #[cfg(bootstrap)]
-        {
-            if self > other {
-                self
-            } else if other > self {
-                other
-            } else if self == other {
-                if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
-            } else {
-                self + other
-            }
-        }
+        intrinsics::maximumf64(self, other)
     }
 
     /// Returns the minimum of the two numbers, propagating NaN.
@@ -1003,26 +987,9 @@ impl f64 {
     /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     #[unstable(feature = "float_minimum_maximum", issue = "91079")]
-    #[rustc_const_unstable(feature = "float_minimum_maximum", issue = "91079")]
     #[inline]
     pub const fn minimum(self, other: f64) -> f64 {
-        #[cfg(not(bootstrap))]
-        {
-            intrinsics::minimumf64(self, other)
-        }
-        #[cfg(bootstrap)]
-        {
-            if self < other {
-                self
-            } else if other < self {
-                other
-            } else if self == other {
-                if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
-            } else {
-                // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
-                self + other
-            }
-        }
+        intrinsics::minimumf64(self, other)
     }
 
     /// Calculates the midpoint (average) between `self` and `rhs`.

From 3fa98a1507b3ec7586b1c1fbdb51b5b55c71e0ed Mon Sep 17 00:00:00 2001
From: Michael Howell <michael@notriddle.com>
Date: Tue, 8 Apr 2025 11:18:08 -0700
Subject: [PATCH 12/14] rustdoc: add a handle that makes sidebar resizing more
 obvious

This change is based on some discussion on [lolbinarycat's idea],
but with a more "traditional" design. Specifically, this is the
closest thing I could find to a consensus across many systems I
looked at for inspiration:

- In Jira, resizable sidebars have a stack of four dots.
- In The GIMP, resizable sidebars have a stack of three dots.
- In [old Windows], "panes" are defined to have the same border
  style as a window, which has a raised appearance.
- In [NeXT], a drag point usually had an innie, whether the line in a
  slider or the circle in a scroller; I can also hide and show the
  favorites bar in Workspace by dragging on a circular "grip spot"
- In [old Mac], drag handles for things usually had a "grip track"
  of parallel lines.
- [OSX] kept that, but the "Source List" part of the Finder still had
  the circle grip for a time the same way Workspace did

[lolbinarycat's idea]: https://github.com/rust-lang/rust/pull/139420
[old Windows]: https://archive.org/details/windowsinterface00micr/page/n9/mode/2up
[old Mac]: https://archive.org/details/apple-hig/1996_Human_Interface_Guidelines_for_Mac_OS_8_%28WWDC_Release%29/page/16/mode/2up
[NeXT]: https://archive.org/details/apple-hig/1993%20NeXTSTEP%20User%20Interface%20Guidelines%20-%20Release%203/page/145/mode/2up
[OSX]: https://dn721903.ca.archive.org/0/items/apple-hig/MacOSX_HIG_2005_09_08.pdf#page=267
---
 src/librustdoc/html/static/css/noscript.css   |  6 +++
 src/librustdoc/html/static/css/rustdoc.css    | 54 ++++++++++++++++---
 .../sidebar-resize-close-popover.goml         |  4 +-
 tests/rustdoc-gui/sidebar-resize-setting.goml |  2 +-
 tests/rustdoc-gui/sidebar-resize.goml         |  6 +--
 tests/rustdoc-gui/sidebar.goml                | 18 +++----
 6 files changed, 68 insertions(+), 22 deletions(-)

diff --git a/src/librustdoc/html/static/css/noscript.css b/src/librustdoc/html/static/css/noscript.css
index 477a79d63e948..03201336cde85 100644
--- a/src/librustdoc/html/static/css/noscript.css
+++ b/src/librustdoc/html/static/css/noscript.css
@@ -43,6 +43,7 @@ nav.sub {
 	--settings-button-border-focus: #717171;
 	--sidebar-background-color: #f5f5f5;
 	--sidebar-background-color-hover: #e0e0e0;
+	--sidebar-border-color: #ddd;
 	--code-block-background-color: #f5f5f5;
 	--scrollbar-track-background-color: #dcdcdc;
 	--scrollbar-thumb-background-color: rgba(36, 37, 39, 0.6);
@@ -135,6 +136,8 @@ nav.sub {
 	--scrape-example-code-wrapper-background-end: rgba(255, 255, 255, 0);
 	--sidebar-resizer-hover: hsl(207, 90%, 66%);
 	--sidebar-resizer-active: hsl(207, 90%, 54%);
+	--sidebar-resizer-img-filter: opacity(66%);
+	--sidebar-resizer-img-hover-filter: none;
 }
 /* End theme: light */
 
@@ -149,6 +152,7 @@ nav.sub {
 		--settings-button-border-focus: #ffb900;
 		--sidebar-background-color: #505050;
 		--sidebar-background-color-hover: #676767;
+		--sidebar-border-color: #2A2A2A;
 		--code-block-background-color: #2A2A2A;
 		--scrollbar-track-background-color: #717171;
 		--scrollbar-thumb-background-color: rgba(32, 34, 37, .6);
@@ -244,6 +248,8 @@ nav.sub {
 		--scrape-example-code-wrapper-background-end: rgba(53, 53, 53, 0);
 		--sidebar-resizer-hover: hsl(207, 30%, 54%);
 		--sidebar-resizer-active: hsl(207, 90%, 54%);
+		--sidebar-resizer-img-filter: opacity(66%);
+		--sidebar-resizer-img-hover-filter: none;
 	}
 /* End theme: dark */
 }
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index f838f3f1106fd..a874b87dfe1f8 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1,4 +1,6 @@
-/* When static files are updated, their suffixes need to be updated.
+/*
+// ignore-tidy-filelength
+	When static files are updated, their suffixes need to be updated.
 	1. In the top directory run:
 		./x.py doc --stage 1 library/core
 	2. Find the directory containing files named with updated suffixes:
@@ -496,12 +498,13 @@ img {
 	top: 0;
 	left: 0;
 	z-index: var(--desktop-sidebar-z-index);
+	/* resize indicator: hide this when on touch or mobile */
+	border-right: solid 1px var(--sidebar-border-color);
 }
 
 .rustdoc.src .sidebar {
 	flex-basis: 50px;
 	width: 50px;
-	border-right: 1px solid;
 	overflow-x: hidden;
 	/* The sidebar is by default hidden  */
 	overflow-y: hidden;
@@ -515,12 +518,32 @@ img {
 .sidebar-resizer {
 	touch-action: none;
 	width: 9px;
-	cursor: col-resize;
+	cursor: ew-resize;
 	z-index: calc(var(--desktop-sidebar-z-index) + 1);
 	position: fixed;
 	height: 100%;
-	/* make sure there's a 1px gap between the scrollbar and resize handle */
-	left: calc(var(--desktop-sidebar-width) + 1px);
+	left: var(--desktop-sidebar-width);
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+
+.sidebar-resizer::after {
+	content: url('data:image/svg+xml,\
+		<svg xmlns="http://www.w3.org/2000/svg" width="8" height="24" viewBox="0 0 8 24"> \
+		<linearGradient id="x" x1="0" x2="0" y1="0" y2="1"> \
+		<stop offset="0.5" stop-color="%23666"/><stop offset="0.5" stop-color="%23ccc"/> \
+		</linearGradient> \
+		<circle r="2" fill="none" stroke-width="2" stroke="url(%23x)" cy="21" cx="3"/> \
+		<circle r="2" fill="none" stroke-width="2" stroke="url(%23x)" cy="15" cx="3"/> \
+		<circle r="2" fill="none" stroke-width="2" stroke="url(%23x)" cy="9" cx="3"/> \
+		<circle r="2" fill="none" stroke-width="2" stroke="url(%23x)" cy="3" cx="3"/></svg>');
+	width: 8px;
+	height: 24px;
+	filter: var(--sidebar-resizer-img-filter);
+}
+.sidebar-resizer:hover::after {
+	filter: var(--sidebar-resizer-img-hover-filter);
 }
 
 .rustdoc.src .sidebar-resizer {
@@ -543,7 +566,7 @@ img {
 }
 
 .sidebar-resizing * {
-	cursor: col-resize !important;
+	cursor: ew-resize !important;
 }
 
 .sidebar-resizing .sidebar {
@@ -561,7 +584,7 @@ img {
 	margin: 0;
 	/* when active or hovered, place resizer glow on top of the sidebar (right next to, or even
 	   on top of, the scrollbar) */
-	left: var(--desktop-sidebar-width);
+	left: calc(var(--desktop-sidebar-width) - 1px);
 	border-left: solid 1px var(--sidebar-resizer-hover);
 }
 
@@ -578,6 +601,10 @@ img {
 		/* too easy to hit the resizer while trying to hit the [-] toggle */
 		display: none !important;
 	}
+	.sidebar {
+		/* resize indicator: hide this when on touch or mobile */
+		border-right: none;
+	}
 }
 
 .sidebar-resizer.active {
@@ -590,6 +617,8 @@ img {
 }
 .sidebar-resizer.active::before {
 	border-left: solid 2px var(--sidebar-resizer-active);
+	margin-left: 8px;
+	padding-left: 1px;
 	display: block;
 	height: 100%;
 	content: "";
@@ -2509,6 +2538,8 @@ in src-script.js and main.js
 		/* Reduce height slightly to account for mobile topbar. */
 		height: calc(100vh - 45px);
 		width: 200px;
+		/* resize indicator: hide this when on touch or mobile */
+		border-right: none;
 	}
 
 	/* The source view uses a different design for the sidebar toggle, and doesn't have a topbar,
@@ -2897,6 +2928,7 @@ by default.
 	--settings-button-border-focus: #717171;
 	--sidebar-background-color: #f5f5f5;
 	--sidebar-background-color-hover: #e0e0e0;
+	--sidebar-border-color: #ddd;
 	--code-block-background-color: #f5f5f5;
 	--scrollbar-track-background-color: #dcdcdc;
 	--scrollbar-thumb-background-color: rgba(36, 37, 39, 0.6);
@@ -2989,6 +3021,8 @@ by default.
 	--scrape-example-code-wrapper-background-end: rgba(255, 255, 255, 0);
 	--sidebar-resizer-hover: hsl(207, 90%, 66%);
 	--sidebar-resizer-active: hsl(207, 90%, 54%);
+	--sidebar-resizer-img-filter: opacity(66%);
+	--sidebar-resizer-img-hover-filter: none;
 }
 /* End theme: light */
 
@@ -3002,6 +3036,7 @@ by default.
 	--settings-button-border-focus: #ffb900;
 	--sidebar-background-color: #505050;
 	--sidebar-background-color-hover: #676767;
+	--sidebar-border-color: #2A2A2A;
 	--code-block-background-color: #2A2A2A;
 	--scrollbar-track-background-color: #717171;
 	--scrollbar-thumb-background-color: rgba(32, 34, 37, .6);
@@ -3097,6 +3132,8 @@ by default.
 	--scrape-example-code-wrapper-background-end: rgba(53, 53, 53, 0);
 	--sidebar-resizer-hover: hsl(207, 30%, 54%);
 	--sidebar-resizer-active: hsl(207, 90%, 54%);
+	--sidebar-resizer-img-filter: opacity(66%);
+	--sidebar-resizer-img-hover-filter: none;
 }
 /* End theme: dark */
 
@@ -3114,6 +3151,7 @@ Original by Dempfi (https://github.com/dempfi/ayu)
 	--settings-button-border-focus: #e0e0e0;
 	--sidebar-background-color: #14191f;
 	--sidebar-background-color-hover: rgba(70, 70, 70, 0.33);
+	--sidebar-border-color: #000;
 	--code-block-background-color: #191f26;
 	--scrollbar-track-background-color: transparent;
 	--scrollbar-thumb-background-color: #5c6773;
@@ -3209,6 +3247,8 @@ Original by Dempfi (https://github.com/dempfi/ayu)
 	--scrape-example-code-wrapper-background-end: rgba(15, 20, 25, 0);
 	--sidebar-resizer-hover: hsl(34, 50%, 33%);
 	--sidebar-resizer-active: hsl(34, 100%, 66%);
+	--sidebar-resizer-img-filter: opacity(66%);
+	--sidebar-resizer-img-hover-filter: none;
 }
 
 :root[data-theme="ayu"] h1,
diff --git a/tests/rustdoc-gui/sidebar-resize-close-popover.goml b/tests/rustdoc-gui/sidebar-resize-close-popover.goml
index 2a8fbac855e97..2d26caf1a39ef 100644
--- a/tests/rustdoc-gui/sidebar-resize-close-popover.goml
+++ b/tests/rustdoc-gui/sidebar-resize-close-popover.goml
@@ -1,13 +1,13 @@
 // Checks sidebar resizing close the Settings popover
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
-assert-property: (".sidebar", {"clientWidth": "200"})
+assert-property: (".sidebar", {"clientWidth": "199"})
 show-text: true
 click: "#settings-menu"
 wait-for: "#settings"
 assert-css: ("#settings", {"display": "block"})
 // normal resizing
 drag-and-drop: ((205, 100), (185, 100))
-assert-property: (".sidebar", {"clientWidth": "182"})
+assert-property: (".sidebar", {"clientWidth": "181"})
 assert-css: ("#settings", {"display": "none"})
 
 // Now same thing, but for source code
diff --git a/tests/rustdoc-gui/sidebar-resize-setting.goml b/tests/rustdoc-gui/sidebar-resize-setting.goml
index 32471f9db4e26..e346fe6aeac0b 100644
--- a/tests/rustdoc-gui/sidebar-resize-setting.goml
+++ b/tests/rustdoc-gui/sidebar-resize-setting.goml
@@ -1,6 +1,6 @@
 // Checks sidebar resizing stays synced with the setting
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
-assert-property: (".sidebar", {"clientWidth": "200"})
+assert-property: (".sidebar", {"clientWidth": "199"})
 show-text: true
 
 // Verify that the "hide" option is unchecked
diff --git a/tests/rustdoc-gui/sidebar-resize.goml b/tests/rustdoc-gui/sidebar-resize.goml
index 543d5d390c720..64b0a23757ac3 100644
--- a/tests/rustdoc-gui/sidebar-resize.goml
+++ b/tests/rustdoc-gui/sidebar-resize.goml
@@ -1,13 +1,13 @@
 // Checks sidebar resizing
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
-assert-property: (".sidebar", {"clientWidth": "200"})
+assert-property: (".sidebar", {"clientWidth": "199"})
 show-text: true
 // normal resizing
 drag-and-drop: ((205, 100), (185, 100))
-assert-property: (".sidebar", {"clientWidth": "182"})
+assert-property: (".sidebar", {"clientWidth": "181"})
 // resize past maximum (don't grow past 500)
 drag-and-drop: ((185, 100), (600, 100))
-assert-property: (".sidebar", {"clientWidth": "500"})
+assert-property: (".sidebar", {"clientWidth": "499"})
 // resize past minimum (hide sidebar)
 drag-and-drop: ((501, 100), (5, 100))
 assert-property: (".sidebar", {"clientWidth": "0"})
diff --git a/tests/rustdoc-gui/sidebar.goml b/tests/rustdoc-gui/sidebar.goml
index 9c66b84165f88..c0fe240e2bed2 100644
--- a/tests/rustdoc-gui/sidebar.goml
+++ b/tests/rustdoc-gui/sidebar.goml
@@ -1,7 +1,7 @@
 // Checks multiple things on the sidebar display (width of its elements, colors, etc).
 include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
-assert-property: (".sidebar", {"clientWidth": "200"})
+assert-property: (".sidebar", {"clientWidth": "199"})
 show-text: true
 
 // First, check the sidebar colors.
@@ -84,13 +84,13 @@ assert-property: ("html", {"scrollTop": "0"})
 
 // We now go back to the crate page to click on the "lib2" crate link.
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
-assert-property: (".sidebar", {"clientWidth": "200"})
+assert-property: (".sidebar", {"clientWidth": "199"})
 assert-css: (".sidebar-elems ul.crate > li:first-child > a", {"color": "#356da4"})
 click: ".sidebar-elems ul.crate > li:first-child > a"
 
 // PAGE: lib2/index.html
 go-to: "file://" + |DOC_PATH| + "/lib2/index.html"
-assert-property: (".sidebar", {"clientWidth": "200"})
+assert-property: (".sidebar", {"clientWidth": "199"})
 assert-text: (".sidebar > .sidebar-crate > h2 > a", "lib2")
 assert-count: (".sidebar .location", 0)
 // We check that we have the crates list and that the "current" on is now "lib2".
@@ -116,7 +116,7 @@ assert-text: (".sidebar-elems ul.block > li.current > a", "foobar")
 assert-false: ".sidebar-elems > .crate"
 
 go-to: "./module/index.html"
-assert-property: (".sidebar", {"clientWidth": "200"})
+assert-property: (".sidebar", {"clientWidth": "199"})
 assert-text: (".sidebar > .sidebar-crate > h2 > a", "lib2")
 assert-text: (".sidebar .location", "Module module")
 assert-count: (".sidebar .location", 1)
@@ -134,7 +134,7 @@ assert-property: (".sidebar > .sidebar-elems > #rustdoc-modnav > h2 > a", {
 assert-false: ".sidebar-elems > .crate"
 
 go-to: "./sub_module/sub_sub_module/index.html"
-assert-property: (".sidebar", {"clientWidth": "200"})
+assert-property: (".sidebar", {"clientWidth": "199"})
 assert-text: (".sidebar > .sidebar-crate > h2 > a", "lib2")
 assert-text: (".sidebar .location", "Module sub_sub_module")
 assert-text: (".sidebar > .sidebar-elems > #rustdoc-modnav > h2", "In lib2::module::sub_module")
@@ -149,13 +149,13 @@ assert-text: ("#functions + .item-table dt > a", "foo")
 
 // Links to trait implementations in the sidebar should not wrap even if they are long.
 go-to: "file://" + |DOC_PATH| + "/lib2/struct.HasALongTraitWithParams.html"
-assert-property: (".sidebar", {"clientWidth": "200"})
+assert-property: (".sidebar", {"clientWidth": "199"})
 assert-property: (".sidebar-elems section .block li > a", {"offsetHeight": 29})
 
 // Test that clicking on of the "In <module>" headings in the sidebar links to the
 // appropriate anchor in index.html.
 go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
-assert-property: (".sidebar", {"clientWidth": "200"})
+assert-property: (".sidebar", {"clientWidth": "199"})
 click: "//ul[@class='block mod']/preceding-sibling::h3/a"
 // PAGE: index.html
 assert-css: ("#modules", {"background-color": "#fdffd3"})
@@ -163,10 +163,10 @@ assert-css: ("#modules", {"background-color": "#fdffd3"})
 // Finally, assert that the Summary toggle doesn't affect sidebar width.
 click: "#toggle-all-docs"
 assert-text: ("#toggle-all-docs", "Show all")
-assert-property: (".sidebar", {"clientWidth": "200"})
+assert-property: (".sidebar", {"clientWidth": "199"})
 click: "#toggle-all-docs"
 assert-text: ("#toggle-all-docs", "Summary")
-assert-property: (".sidebar", {"clientWidth": "200"})
+assert-property: (".sidebar", {"clientWidth": "199"})
 
 // Checks that all.html and index.html have their sidebar link in the same place.
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"

From 3c9e1f97b5e1a8c55adf7968194b9ce69c4c125a Mon Sep 17 00:00:00 2001
From: Michael Howell <michael@notriddle.com>
Date: Tue, 8 Apr 2025 18:01:23 -0700
Subject: [PATCH 13/14] rustdoc: add tooltip to resize track

---
 src/librustdoc/html/templates/page.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html
index 5ef376f4acbc9..7af99e7097c37 100644
--- a/src/librustdoc/html/templates/page.html
+++ b/src/librustdoc/html/templates/page.html
@@ -114,7 +114,7 @@ <h2>Files</h2> {# #}
         {% endif %}
         {{ sidebar|safe }}
     </nav> {# #}
-    <div class="sidebar-resizer"></div> {# #}
+    <div class="sidebar-resizer" title="Drag to resize sidebar"></div> {# #}
     <main>
         {% if page.css_class != "src" %}<div class="width-limiter">{% endif %}
             {# defined in storage.js to avoid duplicating complex UI across every page #}

From e6e52063dfb23a16a0217689613e83888b18ccf9 Mon Sep 17 00:00:00 2001
From: Michael Howell <michael@notriddle.com>
Date: Thu, 10 Apr 2025 21:44:35 -0700
Subject: [PATCH 14/14] rustdoc: use a different style of grip track

---
 src/librustdoc/html/static/css/noscript.css |  4 --
 src/librustdoc/html/static/css/rustdoc.css  | 54 ++++++++-------------
 2 files changed, 19 insertions(+), 39 deletions(-)

diff --git a/src/librustdoc/html/static/css/noscript.css b/src/librustdoc/html/static/css/noscript.css
index 03201336cde85..a3c6bf9816169 100644
--- a/src/librustdoc/html/static/css/noscript.css
+++ b/src/librustdoc/html/static/css/noscript.css
@@ -136,8 +136,6 @@ nav.sub {
 	--scrape-example-code-wrapper-background-end: rgba(255, 255, 255, 0);
 	--sidebar-resizer-hover: hsl(207, 90%, 66%);
 	--sidebar-resizer-active: hsl(207, 90%, 54%);
-	--sidebar-resizer-img-filter: opacity(66%);
-	--sidebar-resizer-img-hover-filter: none;
 }
 /* End theme: light */
 
@@ -248,8 +246,6 @@ nav.sub {
 		--scrape-example-code-wrapper-background-end: rgba(53, 53, 53, 0);
 		--sidebar-resizer-hover: hsl(207, 30%, 54%);
 		--sidebar-resizer-active: hsl(207, 90%, 54%);
-		--sidebar-resizer-img-filter: opacity(66%);
-		--sidebar-resizer-img-hover-filter: none;
 	}
 /* End theme: dark */
 }
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index a874b87dfe1f8..a81d5c9c49b4b 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1,5 +1,5 @@
+/* ignore-tidy-filelength */
 /*
-// ignore-tidy-filelength
 	When static files are updated, their suffixes need to be updated.
 	1. In the top directory run:
 		./x.py doc --stage 1 library/core
@@ -525,25 +525,20 @@ img {
 	left: var(--desktop-sidebar-width);
 	display: flex;
 	align-items: center;
-	justify-content: center;
+	justify-content: flex-start;
+	color: var(--right-side-color);
 }
-
-.sidebar-resizer::after {
-	content: url('data:image/svg+xml,\
-		<svg xmlns="http://www.w3.org/2000/svg" width="8" height="24" viewBox="0 0 8 24"> \
-		<linearGradient id="x" x1="0" x2="0" y1="0" y2="1"> \
-		<stop offset="0.5" stop-color="%23666"/><stop offset="0.5" stop-color="%23ccc"/> \
-		</linearGradient> \
-		<circle r="2" fill="none" stroke-width="2" stroke="url(%23x)" cy="21" cx="3"/> \
-		<circle r="2" fill="none" stroke-width="2" stroke="url(%23x)" cy="15" cx="3"/> \
-		<circle r="2" fill="none" stroke-width="2" stroke="url(%23x)" cy="9" cx="3"/> \
-		<circle r="2" fill="none" stroke-width="2" stroke="url(%23x)" cy="3" cx="3"/></svg>');
-	width: 8px;
-	height: 24px;
-	filter: var(--sidebar-resizer-img-filter);
+.sidebar-resizer::before {
+	content: "";
+	border-right: dotted 2px currentColor;
+	width: 2px;
+	height: 12px;
 }
-.sidebar-resizer:hover::after {
-	filter: var(--sidebar-resizer-img-hover-filter);
+.sidebar-resizer::after {
+	content: "";
+	border-right: dotted 2px currentColor;
+	width: 2px;
+	height: 16px;
 }
 
 .rustdoc.src .sidebar-resizer {
@@ -571,6 +566,7 @@ img {
 
 .sidebar-resizing .sidebar {
 	position: fixed;
+	border-right: solid 2px var(--sidebar-resizer-active);
 }
 .sidebar-resizing > body {
 	padding-left: var(--resizing-sidebar-width);
@@ -586,6 +582,7 @@ img {
 	   on top of, the scrollbar) */
 	left: calc(var(--desktop-sidebar-width) - 1px);
 	border-left: solid 1px var(--sidebar-resizer-hover);
+	color: var(--sidebar-resizer-hover);
 }
 
 .src-sidebar-expanded .rustdoc.src .sidebar-resizer:hover,
@@ -611,17 +608,10 @@ img {
 	/* make the resize tool bigger when actually resizing, to avoid :hover styles on other stuff
 		while resizing */
 	padding: 0 140px;
-	width: 2px;
+	width: calc(140px + 140px + 9px + 2px);
 	margin-left: -140px;
 	border-left: none;
-}
-.sidebar-resizer.active::before {
-	border-left: solid 2px var(--sidebar-resizer-active);
-	margin-left: 8px;
-	padding-left: 1px;
-	display: block;
-	height: 100%;
-	content: "";
+	color: var(--sidebar-resizer-active);
 }
 
 .sidebar, .mobile-topbar, .sidebar-menu-toggle,
@@ -3021,8 +3011,6 @@ by default.
 	--scrape-example-code-wrapper-background-end: rgba(255, 255, 255, 0);
 	--sidebar-resizer-hover: hsl(207, 90%, 66%);
 	--sidebar-resizer-active: hsl(207, 90%, 54%);
-	--sidebar-resizer-img-filter: opacity(66%);
-	--sidebar-resizer-img-hover-filter: none;
 }
 /* End theme: light */
 
@@ -3036,7 +3024,7 @@ by default.
 	--settings-button-border-focus: #ffb900;
 	--sidebar-background-color: #505050;
 	--sidebar-background-color-hover: #676767;
-	--sidebar-border-color: #2A2A2A;
+	--sidebar-border-color: #999;
 	--code-block-background-color: #2A2A2A;
 	--scrollbar-track-background-color: #717171;
 	--scrollbar-thumb-background-color: rgba(32, 34, 37, .6);
@@ -3132,8 +3120,6 @@ by default.
 	--scrape-example-code-wrapper-background-end: rgba(53, 53, 53, 0);
 	--sidebar-resizer-hover: hsl(207, 30%, 54%);
 	--sidebar-resizer-active: hsl(207, 90%, 54%);
-	--sidebar-resizer-img-filter: opacity(66%);
-	--sidebar-resizer-img-hover-filter: none;
 }
 /* End theme: dark */
 
@@ -3151,7 +3137,7 @@ Original by Dempfi (https://github.com/dempfi/ayu)
 	--settings-button-border-focus: #e0e0e0;
 	--sidebar-background-color: #14191f;
 	--sidebar-background-color-hover: rgba(70, 70, 70, 0.33);
-	--sidebar-border-color: #000;
+	--sidebar-border-color: #5c6773;
 	--code-block-background-color: #191f26;
 	--scrollbar-track-background-color: transparent;
 	--scrollbar-thumb-background-color: #5c6773;
@@ -3247,8 +3233,6 @@ Original by Dempfi (https://github.com/dempfi/ayu)
 	--scrape-example-code-wrapper-background-end: rgba(15, 20, 25, 0);
 	--sidebar-resizer-hover: hsl(34, 50%, 33%);
 	--sidebar-resizer-active: hsl(34, 100%, 66%);
-	--sidebar-resizer-img-filter: opacity(66%);
-	--sidebar-resizer-img-hover-filter: none;
 }
 
 :root[data-theme="ayu"] h1,