From fa9a911a57eff5d2cd59eacbffb4e41bc721db2e Mon Sep 17 00:00:00 2001 From: joboet Date: Sat, 13 Jan 2024 20:10:00 +0100 Subject: [PATCH 1/2] libs: use `assert_unchecked` instead of intrinsic --- library/alloc/src/alloc.rs | 6 +++--- library/alloc/src/lib.rs | 1 + library/alloc/src/raw_vec.rs | 8 ++++---- library/alloc/src/rc.rs | 5 +++-- library/alloc/src/vec/mod.rs | 2 +- library/core/src/alloc/global.rs | 2 +- library/core/src/lib.rs | 1 + library/core/src/num/mod.rs | 1 + library/core/src/num/uint_macros.rs | 4 ++-- library/core/src/slice/index.rs | 2 +- library/core/src/slice/iter.rs | 2 +- library/core/src/slice/iter/macros.rs | 4 ++-- library/core/src/slice/mod.rs | 5 +++-- library/std/src/alloc.rs | 6 +++--- library/std/src/lib.rs | 1 + 15 files changed, 28 insertions(+), 22 deletions(-) diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 1663aa84921..0b142939755 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -3,7 +3,7 @@ #![stable(feature = "alloc_module", since = "1.28.0")] #[cfg(not(test))] -use core::intrinsics; +use core::hint; #[cfg(not(test))] use core::ptr::{self, NonNull}; @@ -208,7 +208,7 @@ unsafe fn grow_impl( let new_size = new_layout.size(); // `realloc` probably checks for `new_size >= old_layout.size()` or something similar. - intrinsics::assume(new_size >= old_layout.size()); + hint::assert_unchecked(new_size >= old_layout.size()); let raw_ptr = realloc(ptr.as_ptr(), old_layout, new_size); let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?; @@ -299,7 +299,7 @@ unsafe fn shrink( // SAFETY: `new_size` is non-zero. Other conditions must be upheld by the caller new_size if old_layout.align() == new_layout.align() => unsafe { // `realloc` probably checks for `new_size <= old_layout.size()` or something similar. - intrinsics::assume(new_size <= old_layout.size()); + hint::assert_unchecked(new_size <= old_layout.size()); let raw_ptr = realloc(ptr.as_ptr(), old_layout, new_size); let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?; diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 78629b39d34..02ecbe22b3e 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -129,6 +129,7 @@ #![feature(fmt_internals)] #![feature(fn_traits)] #![feature(hasher_prefixfree_extras)] +#![feature(hint_assert_unchecked)] #![feature(inline_const)] #![feature(inplace_iteration)] #![feature(iter_advance_by)] diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index 45e82240164..94e6924f41a 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -2,7 +2,7 @@ use core::alloc::LayoutError; use core::cmp; -use core::intrinsics; +use core::hint; use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties}; use core::ptr::{self, NonNull, Unique}; use core::slice; @@ -325,7 +325,7 @@ pub fn try_reserve(&mut self, len: usize, additional: usize) -> Result<(), TryRe } unsafe { // Inform the optimizer that the reservation has succeeded or wasn't needed - core::intrinsics::assume(!self.needs_to_grow(len, additional)); + hint::assert_unchecked(!self.needs_to_grow(len, additional)); } Ok(()) } @@ -363,7 +363,7 @@ pub fn try_reserve_exact( } unsafe { // Inform the optimizer that the reservation has succeeded or wasn't needed - core::intrinsics::assume(!self.needs_to_grow(len, additional)); + hint::assert_unchecked(!self.needs_to_grow(len, additional)); } Ok(()) } @@ -514,7 +514,7 @@ fn finish_grow( debug_assert_eq!(old_layout.align(), new_layout.align()); unsafe { // The allocator checks for alignment equality - intrinsics::assume(old_layout.align() == new_layout.align()); + hint::assert_unchecked(old_layout.align() == new_layout.align()); alloc.grow(ptr, old_layout, new_layout) } } else { diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 263b1449de1..1eab681e956 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -252,6 +252,7 @@ use core::cmp::Ordering; use core::fmt; use core::hash::{Hash, Hasher}; +use core::hint; use core::intrinsics::abort; #[cfg(not(no_global_oom_handling))] use core::iter; @@ -3268,7 +3269,7 @@ fn inc_strong(&self) { // SAFETY: The reference count will never be zero when this is // called. unsafe { - core::intrinsics::assume(strong != 0); + hint::assert_unchecked(strong != 0); } let strong = strong.wrapping_add(1); @@ -3301,7 +3302,7 @@ fn inc_weak(&self) { // SAFETY: The reference count will never be zero when this is // called. unsafe { - core::intrinsics::assume(weak != 0); + hint::assert_unchecked(weak != 0); } let weak = weak.wrapping_add(1); diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 8aa0c6e7ed6..5504af28e88 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1993,7 +1993,7 @@ pub fn pop(&mut self) -> Option { } else { unsafe { self.len -= 1; - core::intrinsics::assume(self.len < self.capacity()); + core::hint::assert_unchecked(self.len < self.capacity()); Some(ptr::read(self.as_ptr().add(self.len()))) } } diff --git a/library/core/src/alloc/global.rs b/library/core/src/alloc/global.rs index c582111701a..a1fff6707bd 100644 --- a/library/core/src/alloc/global.rs +++ b/library/core/src/alloc/global.rs @@ -110,7 +110,7 @@ /// ```rust,ignore (unsound and has placeholders) /// drop(Box::new(42)); /// let number_of_heap_allocs = /* call private allocator API */; -/// unsafe { std::intrinsics::assume(number_of_heap_allocs > 0); } +/// unsafe { std::hint::assert_unchecked(number_of_heap_allocs > 0); } /// ``` /// /// Note that the optimizations mentioned above are not the only diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 1a8f245c8be..d0f89efa518 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -131,6 +131,7 @@ #![feature(const_fmt_arguments_new)] #![feature(const_hash)] #![feature(const_heap)] +#![feature(const_hint_assert_unchecked)] #![feature(const_index_range_slice_index)] #![feature(const_int_unchecked_arith)] #![feature(const_intrinsic_forget)] diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 695e87aaabf..2e683592b46 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -3,6 +3,7 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::ascii; +use crate::hint; use crate::intrinsics; use crate::mem; use crate::ops::{Add, Mul, Sub}; diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 11a53aaf122..62d6015fafe 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -2036,8 +2036,8 @@ pub const fn isqrt(self) -> Self { // SAFETY: the result is positive and fits in an integer with half as many bits. // Inform the optimizer about it. unsafe { - intrinsics::assume(0 < res); - intrinsics::assume(res < 1 << (Self::BITS / 2)); + hint::assert_unchecked(0 < res); + hint::assert_unchecked(res < 1 << (Self::BITS / 2)); } res diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 373b4aee47a..fb9be396eab 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -234,7 +234,7 @@ unsafe fn get_unchecked(self, slice: *const [T]) -> *const T { // `self` is in bounds of `slice` so `self` cannot overflow an `isize`, // so the call to `add` is safe. unsafe { - crate::intrinsics::assume(self < slice.len()); + crate::hint::assert_unchecked(self < slice.len()); slice.as_ptr().add(self) } } diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 3d58afd26ea..e1d19fef35f 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -6,7 +6,7 @@ use crate::cmp; use crate::cmp::Ordering; use crate::fmt; -use crate::intrinsics::assume; +use crate::hint::assert_unchecked; use crate::iter::{ FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, UncheckedIterator, }; diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index 95bcd123b82..fc6af45fb90 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -338,7 +338,7 @@ fn position

(&mut self, mut predicate: P) -> Option where if predicate(x) { // SAFETY: we are guaranteed to be in bounds by the loop invariant: // when `i >= n`, `self.next()` returns `None` and the loop breaks. - unsafe { assume(i < n) }; + unsafe { assert_unchecked(i < n) }; return Some(i); } i += 1; @@ -361,7 +361,7 @@ fn rposition

(&mut self, mut predicate: P) -> Option where if predicate(x) { // SAFETY: `i` must be lower than `n` since it starts at `n` // and is only decreasing. - unsafe { assume(i < n) }; + unsafe { assert_unchecked(i < n) }; return Some(i); } } diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 5edc89e4cb5..e971f933570 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -8,6 +8,7 @@ use crate::cmp::Ordering::{self, Equal, Greater, Less}; use crate::fmt; +use crate::hint; use crate::intrinsics::exact_div; use crate::mem::{self, SizedTypeProperties}; use crate::num::NonZeroUsize; @@ -2850,7 +2851,7 @@ pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result right = if cmp == Greater { mid } else { right }; if cmp == Equal { // SAFETY: same as the `get_unchecked` above - unsafe { crate::intrinsics::assume(mid < self.len()) }; + unsafe { hint::assert_unchecked(mid < self.len()) }; return Ok(mid); } @@ -2859,7 +2860,7 @@ pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result // SAFETY: directly true from the overall invariant. // Note that this is `<=`, unlike the assume in the `Ok` path. - unsafe { crate::intrinsics::assume(left <= self.len()) }; + unsafe { hint::assert_unchecked(left <= self.len()) }; Err(left) } diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index bb786bd59dc..a834b36697c 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -56,7 +56,7 @@ #![deny(unsafe_op_in_unsafe_fn)] #![stable(feature = "alloc_module", since = "1.28.0")] -use core::intrinsics; +use core::hint; use core::ptr::NonNull; use core::sync::atomic::{AtomicPtr, Ordering}; use core::{mem, ptr}; @@ -172,7 +172,7 @@ unsafe fn grow_impl( let new_size = new_layout.size(); // `realloc` probably checks for `new_size >= old_layout.size()` or something similar. - intrinsics::assume(new_size >= old_layout.size()); + hint::assert_unchecked(new_size >= old_layout.size()); let raw_ptr = GlobalAlloc::realloc(self, ptr.as_ptr(), old_layout, new_size); let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?; @@ -264,7 +264,7 @@ unsafe fn shrink( // SAFETY: `new_size` is non-zero. Other conditions must be upheld by the caller new_size if old_layout.align() == new_layout.align() => unsafe { // `realloc` probably checks for `new_size <= old_layout.size()` or something similar. - intrinsics::assume(new_size <= old_layout.size()); + hint::assert_unchecked(new_size <= old_layout.size()); let raw_ptr = GlobalAlloc::realloc(self, ptr.as_ptr(), old_layout, new_size); let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?; diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 7a8d9d0ceec..29ef26113ce 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -325,6 +325,7 @@ #![feature(float_next_up_down)] #![feature(hasher_prefixfree_extras)] #![feature(hashmap_internals)] +#![feature(hint_assert_unchecked)] #![feature(ip)] #![feature(maybe_uninit_slice)] #![feature(maybe_uninit_uninit_array)] From 638439a4404d9ef2da4027585134487875787e1d Mon Sep 17 00:00:00 2001 From: joboet Date: Mon, 22 Jan 2024 15:46:32 +0100 Subject: [PATCH 2/2] update codegen tests --- tests/codegen/vec-reserve-extend.rs | 2 ++ tests/codegen/vec_pop_push_noop.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/codegen/vec-reserve-extend.rs b/tests/codegen/vec-reserve-extend.rs index d95220104c2..395373ff4f1 100644 --- a/tests/codegen/vec-reserve-extend.rs +++ b/tests/codegen/vec-reserve-extend.rs @@ -1,4 +1,6 @@ // compile-flags: -O +// ignore-debug +// (with debug assertions turned on, `assert_unchecked` generates a real assertion) #![crate_type = "lib"] diff --git a/tests/codegen/vec_pop_push_noop.rs b/tests/codegen/vec_pop_push_noop.rs index 8bc7b68a816..d9293f2b75d 100644 --- a/tests/codegen/vec_pop_push_noop.rs +++ b/tests/codegen/vec_pop_push_noop.rs @@ -1,4 +1,6 @@ // compile-flags: -O +// ignore-debug +// (with debug assertions turned on, `assert_unchecked` generates a real assertion) #![crate_type = "lib"]