Skip to content

Commit 75a6517

Browse files
committed
Auto merge of rust-lang#119452 - AngelicosPhosphoros:make_nonzeroint_get_assume_nonzero, r=scottmcm
Add assume into `NonZeroIntX::get` LLVM currently don't support range metadata for function arguments so it fails to optimize non zero integers using their invariant if they are provided using by-value function arguments. Related to rust-lang#119422 Related to llvm/llvm-project#76628 Related to rust-lang#49572
2 parents c6a3eaf + 9af3b71 commit 75a6517

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

core/src/num/nonzero.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,18 @@ macro_rules! nonzero_integers {
104104
#[inline]
105105
#[rustc_const_stable(feature = "const_nonzero_get", since = "1.34.0")]
106106
pub const fn get(self) -> $Int {
107+
// FIXME: Remove this after LLVM supports `!range` metadata for function
108+
// arguments https://github.com/llvm/llvm-project/issues/76628
109+
//
110+
// Rustc can set range metadata only if it loads `self` from
111+
// memory somewhere. If the value of `self` was from by-value argument
112+
// of some not-inlined function, LLVM don't have range metadata
113+
// to understand that the value cannot be zero.
114+
115+
// SAFETY: It is an invariant of this type.
116+
unsafe {
117+
intrinsics::assume(self.0 != 0);
118+
}
107119
self.0
108120
}
109121

@@ -114,7 +126,9 @@ macro_rules! nonzero_integers {
114126
#[doc = concat!("Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`")]
115127
#[inline]
116128
fn from(nonzero: $Ty) -> Self {
117-
nonzero.0
129+
// Call nonzero to keep information range information
130+
// from get method.
131+
nonzero.get()
118132
}
119133
}
120134

@@ -233,7 +247,7 @@ macro_rules! nonzero_leading_trailing_zeros {
233247
#[inline]
234248
pub const fn leading_zeros(self) -> u32 {
235249
// SAFETY: since `self` cannot be zero, it is safe to call `ctlz_nonzero`.
236-
unsafe { intrinsics::ctlz_nonzero(self.0 as $Uint) as u32 }
250+
unsafe { intrinsics::ctlz_nonzero(self.get() as $Uint) as u32 }
237251
}
238252

239253
/// Returns the number of trailing zeros in the binary representation
@@ -257,7 +271,7 @@ macro_rules! nonzero_leading_trailing_zeros {
257271
#[inline]
258272
pub const fn trailing_zeros(self) -> u32 {
259273
// SAFETY: since `self` cannot be zero, it is safe to call `cttz_nonzero`.
260-
unsafe { intrinsics::cttz_nonzero(self.0 as $Uint) as u32 }
274+
unsafe { intrinsics::cttz_nonzero(self.get() as $Uint) as u32 }
261275
}
262276

263277
}
@@ -515,7 +529,7 @@ macro_rules! nonzero_unsigned_operations {
515529
without modifying the original"]
516530
#[inline]
517531
pub const fn ilog10(self) -> u32 {
518-
super::int_log10::$Int(self.0)
532+
super::int_log10::$Int(self.get())
519533
}
520534

521535
/// Calculates the middle point of `self` and `rhs`.

0 commit comments

Comments
 (0)