about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-01-15 18:39:40 +0000
committerbors <bors@rust-lang.org>2023-01-15 18:39:40 +0000
commit9e75dddf609c0201d03f9792e850f95d6a283d11 (patch)
tree30f268196652356e492213e82503c7af99414f6b
parentae4d89dfb51535c1c43052ef848564bd2323c9ca (diff)
parent9db013401879a39df86c33552c8c092cf95ea20c (diff)
downloadrust-9e75dddf609c0201d03f9792e850f95d6a283d11.tar.gz
rust-9e75dddf609c0201d03f9792e850f95d6a283d11.zip
Auto merge of #106393 - the8472:use-ptr-sub, r=scottmcm
Simplify manual ptr arithmetic in slice::Iter with ptr_sub

The old code was introduced in #61885, which predates the ptr_sub method and underlying intrinsic. The codegen test still passes.

r? `@scottmcm`
-rw-r--r--library/core/src/slice/iter.rs8
-rw-r--r--library/core/src/slice/iter/macros.rs22
-rw-r--r--tests/codegen/issue-45964-bounds-check-slice-pos.rs1
3 files changed, 8 insertions, 23 deletions
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index c3e7f2eb302..90ab43d1289 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -6,7 +6,7 @@ mod macros;
 use crate::cmp;
 use crate::cmp::Ordering;
 use crate::fmt;
-use crate::intrinsics::{assume, exact_div, unchecked_sub};
+use crate::intrinsics::assume;
 use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
 use crate::marker::{PhantomData, Send, Sized, Sync};
 use crate::mem::{self, SizedTypeProperties};
@@ -35,12 +35,6 @@ impl<'a, T> IntoIterator for &'a mut [T] {
     }
 }
 
-// Macro helper functions
-#[inline(always)]
-fn size_from_ptr<T>(_: *const T) -> usize {
-    mem::size_of::<T>()
-}
-
 /// Immutable slice iterator
 ///
 /// This struct is created by the [`iter`] method on [slices].
diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs
index 55af4cb61dc..0fd57b197aa 100644
--- a/library/core/src/slice/iter/macros.rs
+++ b/library/core/src/slice/iter/macros.rs
@@ -9,30 +9,20 @@ macro_rules! is_empty {
     };
 }
 
-// To get rid of some bounds checks (see `position`), we compute the length in a somewhat
-// unexpected way. (Tested by `codegen/slice-position-bounds-check`.)
 macro_rules! len {
     ($self: ident) => {{
         #![allow(unused_unsafe)] // we're sometimes used within an unsafe block
 
         let start = $self.ptr;
-        let size = size_from_ptr(start.as_ptr());
-        if size == 0 {
-            // This _cannot_ use `unchecked_sub` because we depend on wrapping
+        if T::IS_ZST {
+            // This _cannot_ use `ptr_sub` because we depend on wrapping
             // to represent the length of long ZST slice iterators.
             $self.end.addr().wrapping_sub(start.as_ptr().addr())
         } else {
-            // We know that `start <= end`, so can do better than `offset_from`,
-            // which needs to deal in signed. By setting appropriate flags here
-            // we can tell LLVM this, which helps it remove bounds checks.
-            // SAFETY: By the type invariant, `start <= end`
-            let diff = unsafe { unchecked_sub($self.end.addr(), start.as_ptr().addr()) };
-            // By also telling LLVM that the pointers are apart by an exact
-            // multiple of the type size, it can optimize `len() == 0` down to
-            // `start == end` instead of `(end - start) < size`.
-            // SAFETY: By the type invariant, the pointers are aligned so the
-            //         distance between them must be a multiple of pointee size
-            unsafe { exact_div(diff, size) }
+            // To get rid of some bounds checks (see `position`), we use ptr_sub instead of
+            // offset_from (Tested by `codegen/slice-position-bounds-check`.)
+            // SAFETY: by the type invariant pointers are aligned and `start <= end`
+            unsafe { $self.end.sub_ptr(start.as_ptr()) }
         }
     }};
 }
diff --git a/tests/codegen/issue-45964-bounds-check-slice-pos.rs b/tests/codegen/issue-45964-bounds-check-slice-pos.rs
index aa59c713b78..1daa213fc82 100644
--- a/tests/codegen/issue-45964-bounds-check-slice-pos.rs
+++ b/tests/codegen/issue-45964-bounds-check-slice-pos.rs
@@ -2,6 +2,7 @@
 // prevent optimizing away bounds checks
 
 // compile-flags: -O
+// ignore-debug: the debug assertions get in the way
 
 #![crate_type="rlib"]