diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index 38a60338e74..81087c5417a 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -2528,13 +2528,15 @@ pub const fn bswap<T: Copy>(_x: T) -> T;
 #[rustc_intrinsic]
 pub const fn bitreverse<T: Copy>(_x: T) -> T;
 
-/// Does a three-way comparison between the two integer arguments.
+/// Does a three-way comparison between the two arguments,
+/// which must be of character or integer (signed or unsigned) type.
 ///
-/// This is included as an intrinsic as it's useful to let it be one thing
-/// in MIR, rather than the multiple checks and switches that make its IR
-/// large and difficult to optimize.
+/// This was originally added because it greatly simplified the MIR in `cmp`
+/// implementations, and then LLVM 20 added a backend intrinsic for it too.
 ///
 /// The stabilized version of this intrinsic is [`Ord::cmp`].
+#[rustc_intrinsic_const_stable_indirect]
+#[rustc_nounwind]
 #[rustc_intrinsic]
 pub const fn three_way_compare<T: Copy>(_lhs: T, _rhss: T) -> crate::cmp::Ordering;
 
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 7d99aaa1731..273db46e4b4 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -3571,10 +3571,7 @@ macro_rules! int_impl {
             // so delegate it to `Ord` which is already producing -1/0/+1
             // exactly like we need and can be the place to deal with the complexity.
 
-            // FIXME(const-hack): replace with cmp
-            if self < 0 { -1 }
-            else if self == 0 { 0 }
-            else { 1 }
+            crate::intrinsics::three_way_compare(self, 0) as Self
         }
 
         /// Returns `true` if `self` is positive and `false` if the number is zero or
diff --git a/tests/mir-opt/lower_intrinsics.three_way_compare_char.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.three_way_compare_char.LowerIntrinsics.panic-unwind.diff
index 596ad70b3bf..f29bc5dfc6e 100644
--- a/tests/mir-opt/lower_intrinsics.three_way_compare_char.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.three_way_compare_char.LowerIntrinsics.panic-unwind.diff
@@ -18,7 +18,7 @@
           _4 = copy _1;
           StorageLive(_5);
           _5 = copy _2;
--         _3 = three_way_compare::<char>(move _4, move _5) -> [return: bb1, unwind continue];
+-         _3 = three_way_compare::<char>(move _4, move _5) -> [return: bb1, unwind unreachable];
 +         _3 = Cmp(move _4, move _5);
 +         goto -> bb1;
       }
diff --git a/tests/mir-opt/lower_intrinsics.three_way_compare_signed.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.three_way_compare_signed.LowerIntrinsics.panic-unwind.diff
index 987c2166692..654cb2503df 100644
--- a/tests/mir-opt/lower_intrinsics.three_way_compare_signed.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.three_way_compare_signed.LowerIntrinsics.panic-unwind.diff
@@ -15,7 +15,7 @@
           _4 = copy _1;
           StorageLive(_5);
           _5 = copy _2;
--         _3 = three_way_compare::<i16>(move _4, move _5) -> [return: bb1, unwind continue];
+-         _3 = three_way_compare::<i16>(move _4, move _5) -> [return: bb1, unwind unreachable];
 +         _3 = Cmp(move _4, move _5);
 +         goto -> bb1;
       }
diff --git a/tests/mir-opt/lower_intrinsics.three_way_compare_unsigned.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.three_way_compare_unsigned.LowerIntrinsics.panic-unwind.diff
index d7ec6dcfa2c..82c89b7ce54 100644
--- a/tests/mir-opt/lower_intrinsics.three_way_compare_unsigned.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.three_way_compare_unsigned.LowerIntrinsics.panic-unwind.diff
@@ -18,7 +18,7 @@
           _4 = copy _1;
           StorageLive(_5);
           _5 = copy _2;
--         _3 = three_way_compare::<u32>(move _4, move _5) -> [return: bb1, unwind continue];
+-         _3 = three_way_compare::<u32>(move _4, move _5) -> [return: bb1, unwind unreachable];
 +         _3 = Cmp(move _4, move _5);
 +         goto -> bb1;
       }