Repository: rust-lang/rust
Pull request #138398: atomic intrinsics: clarify which types are supported and (if applicable) what happens with provenance
Author: login: RalfJung
Labels: name: T-compiler
description: Relevant to the compiler team, which will review and decide on the PR/issue.
name: S-waiting-on-bors
description: Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
name: T-libs
description: Relevant to the library team, which will review and decide on the PR/issue.
Created: 2025-03-12T11:43:49Z | Merged: 2025-03-14T10:07:06Z

The provenance semantics match what Miri implements and what the `AtomicPtr` API expects.


Diff:
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
index 6735ae024d1c5..75f3a3c19724f 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
@@ -1031,7 +1031,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
 
             let layout = src.layout();
             match layout.ty.kind() {
-                ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
+                ty::Int(_) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
                     return Ok(());
@@ -1052,7 +1052,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
 
             let layout = src.layout();
             match layout.ty.kind() {
-                ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
+                ty::Uint(_) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
                     return Ok(());
@@ -1073,7 +1073,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
 
             let layout = src.layout();
             match layout.ty.kind() {
-                ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
+                ty::Int(_) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
                     return Ok(());
@@ -1094,7 +1094,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
 
             let layout = src.layout();
             match layout.ty.kind() {
-                ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
+                ty::Uint(_) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
                     return Ok(());
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
index b34e966ba6ce6..5c062dff2fa74 100644
--- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
@@ -441,6 +441,40 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     }
 
                     // These are all AtomicRMW ops
+                    "max" | "min" => {
+                        let atom_op = if instruction == "max" {
+                            AtomicRmwBinOp::AtomicMax
+                        } else {
+                            AtomicRmwBinOp::AtomicMin
+                        };
+
+                        let ty = fn_args.type_at(0);
+                        if matches!(ty.kind(), ty::Int(_)) {
+                            let ptr = args[0].immediate();
+                            let val = args[1].immediate();
+                            bx.atomic_rmw(atom_op, ptr, val, parse_ordering(bx, ordering))
+                        } else {
+                            invalid_monomorphization(ty);
+                            return Ok(());
+                        }
+                    }
+                    "umax" | "umin" => {
+                        let atom_op = if instruction == "umax" {
+                            AtomicRmwBinOp::AtomicUMax
+                        } else {
+                            AtomicRmwBinOp::AtomicUMin
+                        };
+
+                        let ty = fn_args.type_at(0);
+                        if matches!(ty.kind(), ty::Uint(_)) {
+                            let ptr = args[0].immediate();
+                            let val = args[1].immediate();
+                            bx.atomic_rmw(atom_op, ptr, val, parse_ordering(bx, ordering))
+                        } else {
+                            invalid_monomorphization(ty);
+                            return Ok(());
+                        }
+                    }
                     op => {
                         let atom_op = match op {
                             "xchg" => AtomicRmwBinOp::AtomicXchg,
@@ -450,10 +484,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             "nand" => AtomicRmwBinOp::AtomicNand,
                             "or" => AtomicRmwBinOp::AtomicOr,
                             "xor" => AtomicRmwBinOp::AtomicXor,
-                            "max" => AtomicRmwBinOp::AtomicMax,
-                            "min" => AtomicRmwBinOp::AtomicMin,
-                            "umax" => AtomicRmwBinOp::AtomicUMax,
-                            "umin" => AtomicRmwBinOp::AtomicUMin,
                             _ => bx.sess().dcx().emit_fatal(errors::UnknownAtomicOperation),
                         };
 
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index ead7b2d29655b..48b265fabc70c 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -90,6 +90,7 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
 // memory, which is not valid for either `&` or `&mut`.
 
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -99,6 +100,7 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_relaxed_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -108,6 +110,7 @@ pub unsafe fn atomic_cxchg_relaxed_relaxed<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_relaxed_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -117,6 +120,7 @@ pub unsafe fn atomic_cxchg_relaxed_acquire<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_relaxed_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -126,6 +130,7 @@ pub unsafe fn atomic_cxchg_relaxed_seqcst<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_acquire_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -135,6 +140,7 @@ pub unsafe fn atomic_cxchg_acquire_relaxed<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_acquire_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -144,6 +150,7 @@ pub unsafe fn atomic_cxchg_acquire_acquire<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_acquire_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -153,6 +160,7 @@ pub unsafe fn atomic_cxchg_acquire_seqcst<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_release_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -162,6 +170,7 @@ pub unsafe fn atomic_cxchg_release_relaxed<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_release_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -171,6 +180,7 @@ pub unsafe fn atomic_cxchg_release_acquire<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_release_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -180,6 +190,7 @@ pub unsafe fn atomic_cxchg_release_seqcst<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_acqrel_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -189,6 +200,7 @@ pub unsafe fn atomic_cxchg_acqrel_relaxed<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_acqrel_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -198,6 +210,7 @@ pub unsafe fn atomic_cxchg_acqrel_acquire<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_acqrel_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -207,6 +220,7 @@ pub unsafe fn atomic_cxchg_acqrel_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_seqcst_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -216,6 +230,7 @@ pub unsafe fn atomic_cxchg_seqcst_relaxed<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_seqcst_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -226,6 +241,7 @@ pub unsafe fn atomic_cxchg_seqcst_acquire<T: Copy>(dst: *mut T, old: T, src: T)
 pub unsafe fn atomic_cxchg_seqcst_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -239,6 +255,7 @@ pub unsafe fn atomic_cxchgweak_relaxed_relaxed<T: Copy>(
     _src: T,
 ) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -252,6 +269,7 @@ pub unsafe fn atomic_cxchgweak_relaxed_acquire<T: Copy>(
     _src: T,
 ) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -261,6 +279,7 @@ pub unsafe fn atomic_cxchgweak_relaxed_acquire<T: Copy>(
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchgweak_relaxed_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -274,6 +293,7 @@ pub unsafe fn atomic_cxchgweak_acquire_relaxed<T: Copy>(
     _src: T,
 ) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -287,6 +307,7 @@ pub unsafe fn atomic_cxchgweak_acquire_acquire<T: Copy>(
     _src: T,
 ) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -296,6 +317,7 @@ pub unsafe fn atomic_cxchgweak_acquire_acquire<T: Copy>(
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchgweak_acquire_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -309,6 +331,7 @@ pub unsafe fn atomic_cxchgweak_release_relaxed<T: Copy>(
     _src: T,
 ) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -322,6 +345,7 @@ pub unsafe fn atomic_cxchgweak_release_acquire<T: Copy>(
     _src: T,
 ) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -331,6 +355,7 @@ pub unsafe fn atomic_cxchgweak_release_acquire<T: Copy>(
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchgweak_release_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -340,6 +365,7 @@ pub unsafe fn atomic_cxchgweak_release_seqcst<T: Copy>(dst: *mut T, old: T, src:
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchgweak_acqrel_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -349,6 +375,7 @@ pub unsafe fn atomic_cxchgweak_acqrel_relaxed<T: Copy>(dst: *mut T, old: T, src:
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchgweak_acqrel_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -358,6 +385,7 @@ pub unsafe fn atomic_cxchgweak_acqrel_acquire<T: Copy>(dst: *mut T, old: T, src:
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchgweak_acqrel_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -367,6 +395,7 @@ pub unsafe fn atomic_cxchgweak_acqrel_seqcst<T: Copy>(dst: *mut T, old: T, src:
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchgweak_seqcst_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -376,6 +405,7 @@ pub unsafe fn atomic_cxchgweak_seqcst_relaxed<T: Copy>(dst: *mut T, old: T, src:
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchgweak_seqcst_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -386,6 +416,7 @@ pub unsafe fn atomic_cxchgweak_seqcst_acquire<T: Copy>(dst: *mut T, old: T, src:
 pub unsafe fn atomic_cxchgweak_seqcst_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 
 /// Loads the current value of the pointer.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `load` method by passing
@@ -394,6 +425,7 @@ pub unsafe fn atomic_cxchgweak_seqcst_seqcst<T: Copy>(dst: *mut T, old: T, src:
 #[rustc_nounwind]
 pub unsafe fn atomic_load_seqcst<T: Copy>(src: *const T) -> T;
 /// Loads the current value of the pointer.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `load` method by passing
@@ -402,6 +434,7 @@ pub unsafe fn atomic_load_seqcst<T: Copy>(src: *const T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_load_acquire<T: Copy>(src: *const T) -> T;
 /// Loads the current value of the pointer.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `load` method by passing
@@ -417,6 +450,7 @@ pub unsafe fn atomic_load_relaxed<T: Copy>(src: *const T) -> T;
 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.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `store` method by passing
@@ -425,6 +459,7 @@ pub unsafe fn atomic_load_unordered<T: Copy>(src: *const T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_store_seqcst<T: Copy>(dst: *mut T, val: T);
 /// Stores the value at the specified memory location.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `store` method by passing
@@ -433,6 +468,7 @@ pub unsafe fn atomic_store_seqcst<T: Copy>(dst: *mut T, val: T);
 #[rustc_nounwind]
 pub unsafe fn atomic_store_release<T: Copy>(dst: *mut T, val: T);
 /// Stores the value at the specified memory location.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `store` method by passing
@@ -448,6 +484,7 @@ pub unsafe fn atomic_store_relaxed<T: Copy>(dst: *mut T, val: T);
 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.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `swap` method by passing
@@ -456,6 +493,7 @@ pub unsafe fn atomic_store_unordered<T: Copy>(dst: *mut T, val: T);
 #[rustc_nounwind]
 pub unsafe fn atomic_xchg_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Stores the value at the specified memory location, returning the old value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `swap` method by passing
@@ -464,6 +502,7 @@ pub unsafe fn atomic_xchg_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xchg_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Stores the value at the specified memory location, returning the old value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `swap` method by passing
@@ -472,6 +511,7 @@ pub unsafe fn atomic_xchg_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xchg_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Stores the value at the specified memory location, returning the old value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `swap` method by passing
@@ -480,6 +520,7 @@ pub unsafe fn atomic_xchg_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xchg_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 /// Stores the value at the specified memory location, returning the old value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `swap` method by passing
@@ -489,6 +530,9 @@ pub unsafe fn atomic_xchg_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 pub unsafe fn atomic_xchg_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
 /// Adds to the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_add` method by passing
@@ -497,6 +541,9 @@ pub unsafe fn atomic_xchg_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xadd_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Adds to the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_add` method by passing
@@ -505,6 +552,9 @@ pub unsafe fn atomic_xadd_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xadd_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Adds to the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_add` method by passing
@@ -513,6 +563,9 @@ pub unsafe fn atomic_xadd_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xadd_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Adds to the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_add` method by passing
@@ -521,6 +574,9 @@ pub unsafe fn atomic_xadd_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xadd_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 /// Adds to the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_add` method by passing
@@ -530,6 +586,9 @@ pub unsafe fn atomic_xadd_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 pub unsafe fn atomic_xadd_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
 /// Subtract from the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_sub` method by passing
@@ -538,6 +597,9 @@ pub unsafe fn atomic_xadd_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xsub_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Subtract from the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_sub` method by passing
@@ -546,6 +608,9 @@ pub unsafe fn atomic_xsub_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xsub_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Subtract from the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_sub` method by passing
@@ -554,6 +619,9 @@ pub unsafe fn atomic_xsub_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xsub_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Subtract from the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_sub` method by passing
@@ -562,6 +630,9 @@ pub unsafe fn atomic_xsub_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xsub_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 /// Subtract from the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_sub` method by passing
@@ -571,6 +642,9 @@ pub unsafe fn atomic_xsub_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 pub unsafe fn atomic_xsub_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
 /// Bitwise and with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_and` method by passing
@@ -579,6 +653,9 @@ pub unsafe fn atomic_xsub_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_and_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise and with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_and` method by passing
@@ -587,6 +664,9 @@ pub unsafe fn atomic_and_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_and_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise and with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_and` method by passing
@@ -595,6 +675,9 @@ pub unsafe fn atomic_and_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_and_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise and with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_and` method by passing
@@ -603,6 +686,9 @@ pub unsafe fn atomic_and_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_and_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise and with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_and` method by passing
@@ -612,6 +698,9 @@ pub unsafe fn atomic_and_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 pub unsafe fn atomic_and_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
 /// Bitwise nand with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`AtomicBool`] type via the `fetch_nand` method by passing
@@ -620,6 +709,9 @@ pub unsafe fn atomic_and_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_nand_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise nand with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`AtomicBool`] type via the `fetch_nand` method by passing
@@ -628,6 +720,9 @@ pub unsafe fn atomic_nand_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_nand_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise nand with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`AtomicBool`] type via the `fetch_nand` method by passing
@@ -636,6 +731,9 @@ pub unsafe fn atomic_nand_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_nand_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise nand with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`AtomicBool`] type via the `fetch_nand` method by passing
@@ -644,6 +742,9 @@ pub unsafe fn atomic_nand_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_nand_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise nand with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`AtomicBool`] type via the `fetch_nand` method by passing
@@ -653,6 +754,9 @@ pub unsafe fn atomic_nand_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 pub unsafe fn atomic_nand_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
 /// Bitwise or with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_or` method by passing
@@ -661,6 +765,9 @@ pub unsafe fn atomic_nand_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_or_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise or with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_or` method by passing
@@ -669,6 +776,9 @@ pub unsafe fn atomic_or_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_or_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise or with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_or` method by passing
@@ -677,6 +787,9 @@ pub unsafe fn atomic_or_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_or_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise or with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_or` method by passing
@@ -685,6 +798,9 @@ pub unsafe fn atomic_or_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_or_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise or with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_or` method by passing
@@ -694,6 +810,9 @@ pub unsafe fn atomic_or_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 pub unsafe fn atomic_or_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
 /// Bitwise xor with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_xor` method by passing
@@ -702,6 +821,9 @@ pub unsafe fn atomic_or_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xor_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise xor with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_xor` method by passing
@@ -710,6 +832,9 @@ pub unsafe fn atomic_xor_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xor_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise xor with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_xor` method by passing
@@ -718,6 +843,9 @@ pub unsafe fn atomic_xor_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xor_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise xor with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_xor` method by passing
@@ -726,6 +854,9 @@ pub unsafe fn atomic_xor_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xor_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise xor with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_xor` method by passing
@@ -735,6 +866,7 @@ pub unsafe fn atomic_xor_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 pub unsafe fn atomic_xor_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
 /// Maximum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_max` method by passing
@@ -743,6 +875,7 @@ pub unsafe fn atomic_xor_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_max_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Maximum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_max` method by passing
@@ -751,6 +884,7 @@ pub unsafe fn atomic_max_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_max_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Maximum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_max` method by passing
@@ -759,6 +893,7 @@ pub unsafe fn atomic_max_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_max_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Maximum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_max` method by passing
@@ -766,7 +901,8 @@ pub unsafe fn atomic_max_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_intrinsic]
 #[rustc_nounwind]
 pub unsafe fn atomic_max_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-/// Maximum with the current value.
+/// Maximum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_max` method by passing
@@ -776,6 +912,7 @@ pub unsafe fn atomic_max_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 pub unsafe fn atomic_max_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
 /// Minimum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_min` method by passing
@@ -784,6 +921,7 @@ pub unsafe fn atomic_max_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_min_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Minimum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_min` method by passing
@@ -792,6 +930,7 @@ pub unsafe fn atomic_min_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_min_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Minimum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_min` method by passing
@@ -800,6 +939,7 @@ pub unsafe fn atomic_min_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_min_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Minimum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_min` method by passing
@@ -808,6 +948,7 @@ pub unsafe fn atomic_min_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_min_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 /// Minimum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_min` method by passing
@@ -817,6 +958,7 @@ pub unsafe fn atomic_min_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 pub unsafe fn atomic_min_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
 /// Minimum with the current value using an unsigned comparison.
+/// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
@@ -825,6 +967,7 @@ pub unsafe fn atomic_min_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_umin_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Minimum with the current value using an unsigned comparison.
+/// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
@@ -833,6 +976,7 @@ pub unsafe fn atomic_umin_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_umin_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Minimum with the current value using an unsigned comparison.
+/// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
@@ -841,6 +985,7 @@ pub unsafe fn atomic_umin_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_umin_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Minimum with the current value using an unsigned comparison.
+/// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
@@ -849,6 +994,7 @@ pub unsafe fn atomic_umin_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_umin_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 /// Minimum with the current value using an unsigned comparison.
+/// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
@@ -858,6 +1004,7 @@ pub unsafe fn atomic_umin_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 pub unsafe fn atomic_umin_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
 /// Maximum with the current value using an unsigned comparison.
+/// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
@@ -866,6 +1013,7 @@ pub unsafe fn atomic_umin_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_umax_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Maximum with the current value using an unsigned comparison.
+/// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
@@ -874,6 +1022,7 @@ pub unsafe fn atomic_umax_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_umax_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Maximum with the current value using an unsigned comparison.
+/// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
@@ -882,6 +1031,7 @@ pub unsafe fn atomic_umax_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_umax_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Maximum with the current value using an unsigned comparison.
+/// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
@@ -890,6 +1040,7 @@ pub unsafe fn atomic_umax_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_umax_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 /// Maximum with the current value using an unsigned comparison.
+/// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] unsigned integer types via the `fetch_max` method by passing


Reviews:
user: login: RalfJung
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-12T11:44:23Z
user: login: nnethercote
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T02:23:24Z
user: login: RalfJung
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-13T07:09:23Z

Review comments:
diff_hunk: @@ -766,14 +900,16 @@ pub unsafe fn atomic_max_acquire<T: Copy>(_dst: *mut T, _src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_max_release<T: Copy>(_dst: *mut T, _src: T) -> T;
 /// Maximum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_max` method by passing
 /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicI32::fetch_max`].
 #[rustc_intrinsic]
 #[rustc_nounwind]
 pub unsafe fn atomic_max_acqrel<T: Copy>(_dst: *mut T, _src: T) -> T;
-/// Maximum with the current value.
+/// Maximum with the current value using a signed comparison.
path: library/core/src/intrinsics/mod.rs
user: login: RalfJung
body: It seems when "using a signed comparison" was added everywhere, `atomic_max_relaxed` was forgotten.
created_at: 2025-03-12T11:44:23Z
author_association: MEMBER
diff_hunk: @@ -90,6 +90,7 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
 // memory, which is not valid for either `&` or `&mut`.
 
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
path: library/core/src/intrinsics/mod.rs
user: login: nnethercote
body: Not relevant for this PR, but I can't help but wonder if macros could be used to reduce the massive amounts of repetition in this file.
created_at: 2025-03-13T02:23:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -90,6 +90,7 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
 // memory, which is not valid for either `&` or `&mut`.
 
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
path: library/core/src/intrinsics/mod.rs
user: login: RalfJung
body: I think that would make the file harder to read. I'd rather see the atomic intrinsics refactored so that the "ordering" becomes a const generic argument, so that we don't need 5 intrinsics for each individual operation any more.
created_at: 2025-03-13T07:09:23Z
author_association: MEMBER

PR comments:
user: login: rustbot
created_at: 2025-03-12T11:43:54Z
body: r? @thomcc

rustbot has assigned @thomcc.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use `r?` to explicitly pick a reviewer
author_association: COLLABORATOR
user: login: rustbot
created_at: 2025-03-12T11:43:57Z
body: Some changes occurred to the intrinsics. Make sure the CTFE / Miri interpreter
gets adapted for the changes, if necessary.


cc @rust-lang/miri, @RalfJung, @oli-obk, @lcnr

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin
author_association: COLLABORATOR
user: login: bors
created_at: 2025-03-12T21:41:17Z
body: :umbrella: The latest upstream changes (presumably #138414) made this pull request unmergeable. Please [resolve the merge conflicts](https://rustc-dev-guide.rust-lang.org/git.html#rebasing-and-conflicts).
author_association: COLLABORATOR
user: login: thomcc
created_at: 2025-03-13T01:46:27Z
body: Doesn't seem like a libs review really. r? compiler
author_association: MEMBER
user: login: nnethercote
created_at: 2025-03-13T02:23:51Z
body: I don't know much about this, but seems reasonable. r=me once the conflicts are resolved.
author_association: CONTRIBUTOR
user: login: RalfJung
created_at: 2025-03-13T07:15:01Z
body: @bors r=nnethercote rollup
author_association: MEMBER
user: login: bors
created_at: 2025-03-13T07:15:05Z
body: :pushpin: Commit 88b206d582235d62bad6246c130ff8c23e41ee65 has been approved by `nnethercote`

It is now in the [queue](https://bors.rust-lang.org/homu/queue/rust) for this repository.

<!-- @bors r=nnethercote 88b206d582235d62bad6246c130ff8c23e41ee65 -->
<!-- homu: {"type":"Approved","sha":"88b206d582235d62bad6246c130ff8c23e41ee65","approver":"nnethercote","queue":"https://bors.rust-lang.org/homu/queue/rust"} -->
author_association: COLLABORATOR