Change:
let (val, ok) = unsafe { match (success, failure) { (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed_relaxed(dst, old, new), <del> //(Relaxed, Acquire) => intrinsics::atomic_cxchg_relaxed_acquire(dst, old, new), //(Relaxed, SeqCst) => intrinsics::atomic_cxchg_relaxed_seqcst(dst, old, new), </del> <ins> #[cfg(not(bootstrap))] (Relaxed, Acquire) => intrinsics::atomic_cxchg_relaxed_acquire(dst, old, new), #[cfg(not(bootstrap))] (Relaxed, SeqCst) => intrinsics::atomic_cxchg_relaxed_seqcst(dst, old, new), </ins> (Acquire, Relaxed) => intrinsics::atomic_cxchg_acquire_relaxed(dst, old, new), (Acquire, Acquire) => intrinsics::atomic_cxchg_acquire_acquire(dst, old, new), <del> //(Acquire, SeqCst) => intrinsics::atomic_cxchg_acquire_seqcst(dst, old, new), </del> <ins> #[cfg(not(bootstrap))] (Acquire, SeqCst) => intrinsics::atomic_cxchg_acquire_seqcst(dst, old, new), </ins> (Release, Relaxed) => intrinsics::atomic_cxchg_release_relaxed(dst, old, new), <del> //(Release, Acquire) => intrinsics::atomic_cxchg_release_acquire(dst, old, new), //(Release, SeqCst) => intrinsics::atomic_cxchg_release_seqcst(dst, old, new), </del> <ins> #[cfg(not(bootstrap))] (Release, Acquire) => intrinsics::atomic_cxchg_release_acquire(dst, old, new), #[cfg(not(bootstrap))] (Release, SeqCst) => intrinsics::atomic_cxchg_release_seqcst(dst, old, new), </ins> (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_relaxed(dst, old, new), (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel_acquire(dst, old, new), <del> //(AcqRel, SeqCst) => intrinsics::atomic_cxchg_acqrel_seqcst(dst, old, new), </del> <ins> #[cfg(not(bootstrap))] (AcqRel, SeqCst) => intrinsics::atomic_cxchg_acqrel_seqcst(dst, old, new), </ins> (SeqCst, Relaxed) => intrinsics::atomic_cxchg_seqcst_relaxed(dst, old, new), (SeqCst, Acquire) => intrinsics::atomic_cxchg_seqcst_acquire(dst, old, new), (SeqCst, SeqCst) => intrinsics::atomic_cxchg_seqcst_seqcst(dst, old, new), (_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"), (_, Release) => panic!("there is no such thing as a release failure ordering"), <ins> #[cfg(bootstrap)] </ins> _ => panic!("a failure ordering can't be stronger than a success ordering"), } };

Discussion:
Currently requires the failure ordering to "be equivalent to or weaker than a success ordering". On the other hand C11/C++11 requires only that "failure shall be no stronger than the success", which arguably means that one can write e.g. in C/C++ but not in Rust. Arguably, because neither C11 standard nor C++11 standard defines what it means for an ordering to be stronger from another. When the issue was raised in [LWG2445], the proposed and accepted resolution was to lift those restrictions altogether, leaving only requirement that "the failure argument shall not be nor ". It would be beneficial to remove success/failure ordering restrictions for reasons described in C++ proposal [P0418r2]. [LWG2445]: [P0418r2]: EDIT: Restrictions were lifted in clang & LLVM:
Blocked on The cmpxchg release acquire is accepted by LLVM but miscompiled on AArch64.
I'm about to send a PR that implements this.
I do have implementation ready as well, but that's fine, I can review instead :-).
I split it in a PR that renames the intrinsics first, and a separate PR for exposing the new ordering combinations afterwards.
Looks like llvm 12 doesn't support this: Can we make things conditionally fall back to a stronger ordering depending on the llvm version? I don't think we do anything like that in the library right now, but maybe the compiler already does things differently for different llvm versions?
Ah yes, some code checks . I suppose Builder::atomic_cmpxchg could check the same, and upgrade the ordering if necessary in that case.
Did exactly that in
To do: [x] Add codegen test. [x] Publicly expose the new orderings. [x] Update memory order lint to accept the new orderings.