about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-05-04 18:36:38 +0200
committerGitHub <noreply@github.com>2024-05-04 18:36:38 +0200
commita5cc1f663f197ffd1372148a232ab53c4afca557 (patch)
tree8816e25bc1efbd07c3575cbb717e5cdf23e935d6
parent9af1e8ce42e6a058bd4f36be587d2d9966adb452 (diff)
parentf1de4c16ee3dae0599efa64d6ebe601efbe23769 (diff)
Rollup merge of #124699 - scottmcm:split_at_unchecked_should_use_unchecked, r=Nilstrieb
Use `unchecked_sub` in `split_at`

LLVM currently isn't figuring it out on its own, even in the checked version where it hypothetically could.

Before: <https://rust.godbolt.org/z/PEY38YrKs>
```llvm
bb1:                                              ; preds = %start
  %4 = getelementptr inbounds float, ptr %x.0, i64 %n
  %5 = sub i64 %x.1, %n
```

After:
```llvm
bb1:                                              ; preds = %start
  %4 = getelementptr inbounds float, ptr %x.0, i64 %n
  %5 = sub nuw i64 %x.1, %n
```

This is not using the wrapper because there's already a ubcheck covering it, so I don't want this to get a second one once #121571 lands.

---

This is basically the same as #108763, since `split_at` is essentially doing two `get_unchecked`s.
-rw-r--r--library/core/src/slice/mod.rs11
1 files changed, 8 insertions, 3 deletions
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index de766a4b977..ed7bcec89b9 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -9,7 +9,7 @@
 use crate::cmp::Ordering::{self, Equal, Greater, Less};
 use crate::fmt;
 use crate::hint;
-use crate::intrinsics::exact_div;
+use crate::intrinsics::{exact_div, unchecked_sub};
 use crate::mem::{self, SizedTypeProperties};
 use crate::num::NonZero;
 use crate::ops::{Bound, OneSidedRange, Range, RangeBounds};
@@ -1983,7 +1983,7 @@ impl<T> [T] {
         );
 
         // SAFETY: Caller has to check that `0 <= mid <= self.len()`
-        unsafe { (from_raw_parts(ptr, mid), from_raw_parts(ptr.add(mid), len - mid)) }
+        unsafe { (from_raw_parts(ptr, mid), from_raw_parts(ptr.add(mid), unchecked_sub(len, mid))) }
     }
 
     /// Divides one mutable slice into two at an index, without doing bounds checking.
@@ -2035,7 +2035,12 @@ impl<T> [T] {
         //
         // `[ptr; mid]` and `[mid; len]` are not overlapping, so returning a mutable reference
         // is fine.
-        unsafe { (from_raw_parts_mut(ptr, mid), from_raw_parts_mut(ptr.add(mid), len - mid)) }
+        unsafe {
+            (
+                from_raw_parts_mut(ptr, mid),
+                from_raw_parts_mut(ptr.add(mid), unchecked_sub(len, mid)),
+            )
+        }
     }
 
     /// Divides one slice into two at an index, returning `None` if the slice is