@@ -728,10 +728,6 @@ pub const fn swap<T>(x: &mut T, y: &mut T) {
728728 // reinterpretation of values as (chunkable) byte arrays, and the loop in the
729729 // block optimization in `swap_slice` is hard to rewrite back
730730 // into the (unoptimized) direct swapping implementation, so we disable it.
731- // FIXME(eddyb) the block optimization also prevents MIR optimizations from
732- // understanding `mem::replace`, `Option::take`, etc. - a better overall
733- // solution might be to make `ptr::swap_nonoverlapping` into an intrinsic, which
734- // a backend can choose to implement using the block optimization, or not.
735731 #[ cfg( not( any( target_arch = "spirv" ) ) ) ]
736732 {
737733 // For types that are larger multiples of their alignment, the simple way
@@ -768,11 +764,14 @@ pub(crate) const fn swap_simple<T>(x: &mut T, y: &mut T) {
768764 // And LLVM actually optimizes it to 3×memcpy if called with
769765 // a type larger than it's willing to keep in a register.
770766 // Having typed reads and writes in MIR here is also good as
771- // it lets MIRI and CTFE understand them better, including things
767+ // it lets Miri and CTFE understand them better, including things
772768 // like enforcing type validity for them.
773769 // Importantly, read+copy_nonoverlapping+write introduces confusing
774770 // asymmetry to the behaviour where one value went through read+write
775771 // whereas the other was copied over by the intrinsic (see #94371).
772+ // Furthermore, using only read+write here benefits limited backends
773+ // such as SPIR-V that work on an underlying *typed* view of memory,
774+ // and thus have trouble with Rust's untyped memory operations.
776775
777776 // SAFETY: exclusive references are always valid to read/write,
778777 // including being aligned, and nothing here panics so it's drop-safe.
0 commit comments