From 1387672b8449d0c97a9216cee9cd2021c72c4561 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 25 Dec 2024 10:49:23 +0100 Subject: [PATCH] =?UTF-8?q?rename=20typed=5Fswap=20=E2=86=92=20typed=5Fswa?= =?UTF-8?q?p=5Fnonoverlapping?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rustc_codegen_ssa/src/mir/intrinsic.rs | 2 +- .../rustc_codegen_ssa/src/traits/builder.rs | 2 +- .../src/interpret/intrinsics.rs | 2 +- .../rustc_hir_analysis/src/check/intrinsic.rs | 4 ++- compiler/rustc_span/src/symbol.rs | 2 +- library/core/src/intrinsics/mod.rs | 27 +++++++++++++++++++ library/core/src/mem/mod.rs | 2 +- .../intrinsics/typed-swap-invalid-array.rs | 4 +-- .../typed-swap-invalid-array.stderr | 4 +-- .../intrinsics/typed-swap-invalid-scalar.rs | 4 +-- .../typed-swap-invalid-scalar.stderr | 4 +-- .../fail/intrinsics/typed-swap-overlap.rs | 4 +-- .../fail/intrinsics/typed-swap-overlap.stderr | 4 +-- tests/codegen/intrinsics/typed_swap.rs | 12 ++++----- 14 files changed, 53 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 299b98c0a4f03..304ac4544ee43 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -75,7 +75,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // If we're swapping something that's *not* an `OperandValue::Ref`, // then we can do it directly and avoid the alloca. // Otherwise, we'll let the fallback MIR body take care of it. - if let sym::typed_swap = name { + if let sym::typed_swap_nonoverlapping = name { let pointee_ty = fn_args.type_at(0); let pointee_layout = bx.layout_of(pointee_ty); if !bx.is_backend_ref(pointee_layout) diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index b0138ac8bfed6..3ee13b19f665f 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -382,7 +382,7 @@ pub trait BuilderMethods<'a, 'tcx>: /// Avoids `alloca`s for Immediates and ScalarPairs. /// /// FIXME: Maybe do something smarter for Ref types too? - /// For now, the `typed_swap` intrinsic just doesn't call this for those + /// For now, the `typed_swap_nonoverlapping` intrinsic just doesn't call this for those /// cases (in non-debug), preferring the fallback body instead. fn typed_place_swap( &mut self, diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 44f6335dc7f2a..04346af41fc19 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -424,7 +424,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let result = self.raw_eq_intrinsic(&args[0], &args[1])?; self.write_scalar(result, dest)?; } - sym::typed_swap => { + sym::typed_swap_nonoverlapping => { self.typed_swap_intrinsic(&args[0], &args[1])?; } diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 394794019109d..0f329639cc16a 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -496,7 +496,9 @@ pub fn check_intrinsic_type( (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit) } - sym::typed_swap => (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)); 2], tcx.types.unit), + sym::typed_swap_nonoverlapping => { + (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)); 2], tcx.types.unit) + } sym::discriminant_value => { let assoc_items = tcx.associated_item_def_ids( diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 3d202f11722ed..b2c259cc5ca10 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2058,7 +2058,7 @@ symbols! { type_macros, type_name, type_privacy_lints, - typed_swap, + typed_swap_nonoverlapping, u128, u128_legacy_const_max, u128_legacy_const_min, diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 9844243d168e9..ed0ae0fb73c6d 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -3956,12 +3956,39 @@ pub const fn is_val_statically_known(_arg: T) -> bool { // Const-unstable because `swap_nonoverlapping` is const-unstable. #[rustc_intrinsic_const_stable_indirect] #[rustc_allow_const_fn_unstable(const_swap_nonoverlapping)] // this is anyway not called since CTFE implements the intrinsic +#[cfg(bootstrap)] pub const unsafe fn typed_swap(x: *mut T, y: *mut T) { // SAFETY: The caller provided single non-overlapping items behind // pointers, so swapping them with `count: 1` is fine. unsafe { ptr::swap_nonoverlapping(x, y, 1) }; } +#[cfg(bootstrap)] +pub use typed_swap as typed_swap_nonoverlapping; + +/// Non-overlapping *typed* swap of a single value. +/// +/// The codegen backends will replace this with a better implementation when +/// `T` is a simple type that can be loaded and stored as an immediate. +/// +/// The stabilized form of this intrinsic is [`crate::mem::swap`]. +/// +/// # Safety +/// +/// `x` and `y` are readable and writable as `T`, and non-overlapping. +#[rustc_nounwind] +#[inline] +#[rustc_intrinsic] +// Const-unstable because `swap_nonoverlapping` is const-unstable. +#[rustc_intrinsic_const_stable_indirect] +#[rustc_allow_const_fn_unstable(const_swap_nonoverlapping)] // this is anyway not called since CTFE implements the intrinsic +#[cfg(not(bootstrap))] +pub const unsafe fn typed_swap_nonoverlapping(x: *mut T, y: *mut T) { + // SAFETY: The caller provided single non-overlapping items behind + // pointers, so swapping them with `count: 1` is fine. + unsafe { ptr::swap_nonoverlapping(x, y, 1) }; +} + /// Returns whether we should perform some UB-checking at runtime. This eventually evaluates to /// `cfg!(ub_checks)`, but behaves different from `cfg!` when mixing crates built with different /// flags: if the crate has UB checks enabled or carries the `#[rustc_preserve_ub_checks]` diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 1576eb4315294..2d66e5c2f2a7a 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -730,7 +730,7 @@ pub unsafe fn uninitialized() -> T { pub const fn swap(x: &mut T, y: &mut T) { // SAFETY: `&mut` guarantees these are typed readable and writable // as well as non-overlapping. - unsafe { intrinsics::typed_swap(x, y) } + unsafe { intrinsics::typed_swap_nonoverlapping(x, y) } } /// Replaces `dest` with the default value of `T`, returning the previous `dest` value. diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.rs b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.rs index 89fdd2a01ebc2..de154d771a0c5 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.rs +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.rs @@ -1,7 +1,7 @@ #![feature(core_intrinsics)] #![feature(rustc_attrs)] -use std::intrinsics::typed_swap; +use std::intrinsics::typed_swap_nonoverlapping; use std::ptr::addr_of_mut; fn invalid_array() { @@ -10,7 +10,7 @@ fn invalid_array() { unsafe { let a = addr_of_mut!(a).cast::<[bool; 100]>(); let b = addr_of_mut!(b).cast::<[bool; 100]>(); - typed_swap(a, b); //~ERROR: constructing invalid value + typed_swap_nonoverlapping(a, b); //~ERROR: constructing invalid value } } diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr index 20b20412e75ab..5884d13a2adc3 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: constructing invalid value at [0]: encountered 0x02, but expected a boolean --> tests/fail/intrinsics/typed-swap-invalid-array.rs:LL:CC | -LL | typed_swap(a, b); - | ^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered 0x02, but expected a boolean +LL | typed_swap_nonoverlapping(a, b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered 0x02, but expected a boolean | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs index 9d014a523f8fd..3cc96e79fec5f 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs @@ -1,7 +1,7 @@ #![feature(core_intrinsics)] #![feature(rustc_attrs)] -use std::intrinsics::typed_swap; +use std::intrinsics::typed_swap_nonoverlapping; use std::ptr::addr_of_mut; fn invalid_scalar() { @@ -10,7 +10,7 @@ fn invalid_scalar() { unsafe { let a = addr_of_mut!(a).cast::(); let b = addr_of_mut!(b).cast::(); - typed_swap(a, b); //~ERROR: constructing invalid value + typed_swap_nonoverlapping(a, b); //~ERROR: constructing invalid value } } diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.stderr index 6062465f36a6f..9804233c7fa8b 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.stderr +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: constructing invalid value: encountered 0x02, but expected a boolean --> tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC | -LL | typed_swap(a, b); - | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x02, but expected a boolean +LL | typed_swap_nonoverlapping(a, b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x02, but expected a boolean | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs index 7a9ad63ad7b4e..7b1be4abb1534 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs @@ -1,13 +1,13 @@ #![feature(core_intrinsics)] #![feature(rustc_attrs)] -use std::intrinsics::typed_swap; +use std::intrinsics::typed_swap_nonoverlapping; use std::ptr::addr_of_mut; fn main() { let mut a = [0_u8; 100]; unsafe { let a = addr_of_mut!(a); - typed_swap(a, a); //~ERROR: called on overlapping ranges + typed_swap_nonoverlapping(a, a); //~ERROR: called on overlapping ranges } } diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr index 5c9cbb78c1ee3..6d578841fe5ec 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: `copy_nonoverlapping` called on overlapping ranges --> tests/fail/intrinsics/typed-swap-overlap.rs:LL:CC | -LL | typed_swap(a, a); - | ^^^^^^^^^^^^^^^^ `copy_nonoverlapping` called on overlapping ranges +LL | typed_swap_nonoverlapping(a, a); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `copy_nonoverlapping` called on overlapping ranges | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/codegen/intrinsics/typed_swap.rs b/tests/codegen/intrinsics/typed_swap.rs index e73931d1d547e..6b55078407a42 100644 --- a/tests/codegen/intrinsics/typed_swap.rs +++ b/tests/codegen/intrinsics/typed_swap.rs @@ -8,14 +8,14 @@ #![crate_type = "lib"] #![feature(core_intrinsics)] -use std::intrinsics::typed_swap; +use std::intrinsics::typed_swap_nonoverlapping; // CHECK-LABEL: @swap_unit( #[no_mangle] pub unsafe fn swap_unit(x: &mut (), y: &mut ()) { // CHECK: start // CHECK-NEXT: ret void - typed_swap(x, y) + typed_swap_nonoverlapping(x, y) } // CHECK-LABEL: @swap_i32( @@ -32,7 +32,7 @@ pub unsafe fn swap_i32(x: &mut i32, y: &mut i32) { // OPT3: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %x, ptr align 4 %y, i64 4, i1 false) // CHECK: store i32 %[[TEMP]], ptr %y, align 4 // CHECK: ret void - typed_swap(x, y) + typed_swap_nonoverlapping(x, y) } // CHECK-LABEL: @swap_pair( @@ -47,7 +47,7 @@ pub unsafe fn swap_pair(x: &mut (i32, u32), y: &mut (i32, u32)) { // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %x, ptr align 4 %y, i64 8, i1 false) // CHECK: store i32 // CHECK: store i32 - typed_swap(x, y) + typed_swap_nonoverlapping(x, y) } // CHECK-LABEL: @swap_str( @@ -63,7 +63,7 @@ pub unsafe fn swap_str<'a>(x: &mut &'a str, y: &mut &'a str) { // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %x, ptr align 8 %y, i64 16, i1 false) // CHECK: store ptr // CHECK: store i64 - typed_swap(x, y) + typed_swap_nonoverlapping(x, y) } // OPT0-LABEL: @swap_string( @@ -73,5 +73,5 @@ pub unsafe fn swap_string(x: &mut String, y: &mut String) { // OPT0: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[TEMP]], ptr align 8 %x, i64 24, i1 false) // OPT0: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %x, ptr align 8 %y, i64 24, i1 false) // OPT0: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %y, ptr align 8 %[[TEMP]], i64 24, i1 false) - typed_swap(x, y) + typed_swap_nonoverlapping(x, y) }