Skip to content

Commit 25f556e

Browse files
committed
Auto merge of rust-lang#87827 - eddyb:wrapperless-mem-replace, r=m-ou-se
Avoid using the `copy_nonoverlapping` wrapper through `mem::replace`. This is a much simpler way to achieve the pre-rust-lang#86003 behavior of `mem::replace` not needing dynamically-sized `memcpy`s (at least before inlining), than re-doing rust-lang#81238 (which needs rust-lang#86699 or something similar). I didn't notice it until recently, but `ptr::write` already explicitly avoided using the wrapper, while `ptr::read` just called the wrapper (and was the reason for us observing any behavior change from rust-lang#86003 in Rust-GPU). <hr/> The codegen test I've added fails without the change to `core::ptr::read` like this (ignore the `v0` mangling, I was using a worktree with it turned on by default, for this): ```llvm 13: ; core::intrinsics::copy_nonoverlapping::<u8> 14: ; Function Attrs: inlinehint nonlazybind uwtable 15: define internal void `@_RINvNtCscK5tvALCJol_4core10intrinsics19copy_nonoverlappinghECsaS4X3EinRE8_25mem_replace_direct_memcpy(i8*` %src, i8* %dst, i64 %count) unnamed_addr #0 { 16: start: 17: %0 = mul i64 %count, 1 18: call void `@llvm.memcpy.p0i8.p0i8.i64(i8*` align 1 %dst, i8* align 1 %src, i64 %0, i1 false) not:17 !~~~~~~~~~~~~~~~~~~~~~ error: no match expected 19: ret void 20: } ``` With the `core::ptr::read` change, `core::intrinsics::copy_nonoverlapping` doesn't get instantiated and the test passes. <hr/> r? `@m-ou-se` cc `@nagisa` (codegen test) `@oli-obk` / `@RalfJung` (miri diagnostic changes)
2 parents add6103 + fc765aa commit 25f556e

File tree

1 file changed

+7
-0
lines changed

1 file changed

+7
-0
lines changed

core/src/ptr/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,13 @@ pub const unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
685685
#[stable(feature = "rust1", since = "1.0.0")]
686686
#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
687687
pub const unsafe fn read<T>(src: *const T) -> T {
688+
// We are calling the intrinsics directly to avoid function calls in the generated code
689+
// as `intrinsics::copy_nonoverlapping` is a wrapper function.
690+
extern "rust-intrinsic" {
691+
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
692+
fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
693+
}
694+
688695
let mut tmp = MaybeUninit::<T>::uninit();
689696
// SAFETY: the caller must guarantee that `src` is valid for reads.
690697
// `src` cannot overlap `tmp` because `tmp` was just allocated on

0 commit comments

Comments
 (0)