Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 5563fb3

Browse files
committedOct 11, 2024
Avoid superfluous UB checks in IndexRange
`IndexRange::len` is justified as an overall invariant, and `take_prefix` and `take_suffix` are justified by local branch conditions. A few more UB-checked calls remain in cases that are only supported locally by `debug_assert!`, which won't do anything in distributed builds, so those UB checks may still be useful. We generally expect core's `#![rustc_preserve_ub_checks]` to optimize away in user's release builds, but the mere presence of that extra code can sometimes inhibit optimization, as seen in rust-lang#131563.
1 parent f496659 commit 5563fb3

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-4
lines changed
 

‎library/core/src/ops/index_range.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ impl IndexRange {
4545
#[inline]
4646
pub const fn len(&self) -> usize {
4747
// SAFETY: By invariant, this cannot wrap
48-
unsafe { self.end.unchecked_sub(self.start) }
48+
// Using the intrinsic avoids a superfluous UB check.
49+
unsafe { crate::intrinsics::unchecked_sub(self.end, self.start) }
4950
}
5051

5152
/// # Safety
@@ -82,7 +83,8 @@ impl IndexRange {
8283
let mid = if n <= self.len() {
8384
// SAFETY: We just checked that this will be between start and end,
8485
// and thus the addition cannot overflow.
85-
unsafe { self.start.unchecked_add(n) }
86+
// Using the intrinsic avoids a superfluous UB check.
87+
unsafe { crate::intrinsics::unchecked_add(self.start, n) }
8688
} else {
8789
self.end
8890
};
@@ -100,8 +102,9 @@ impl IndexRange {
100102
pub fn take_suffix(&mut self, n: usize) -> Self {
101103
let mid = if n <= self.len() {
102104
// SAFETY: We just checked that this will be between start and end,
103-
// and thus the addition cannot overflow.
104-
unsafe { self.end.unchecked_sub(n) }
105+
// and thus the subtraction cannot overflow.
106+
// Using the intrinsic avoids a superfluous UB check.
107+
unsafe { crate::intrinsics::unchecked_sub(self.end, n) }
105108
} else {
106109
self.start
107110
};

‎tests/codegen/issues/issue-101082.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
//@ compile-flags: -O
2+
//@ revisions: host x86-64-v3
3+
4+
// This particular CPU regressed in #131563
5+
//@[x86-64-v3] only-x86_64
6+
//@[x86-64-v3] compile-flags: -Ctarget-cpu=x86-64-v3
27

38
#![crate_type = "lib"]
49

0 commit comments

Comments
 (0)
Failed to load comments.