diff options
| author | bors <bors@rust-lang.org> | 2021-10-03 10:34:57 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-10-03 10:34:57 +0000 |
| commit | 4479cb82e52989480a238e0cf8c67e04b655b36d (patch) | |
| tree | 280d3ac19e09d225644b96007748a417eacebd25 | |
| parent | c24c9067eec3aec8dd2013d24f6cd0dff3ecec4c (diff) | |
| parent | 1139ee32aa803401198c02d5541accbf3fddfc94 (diff) | |
| download | rust-4479cb82e52989480a238e0cf8c67e04b655b36d.tar.gz rust-4479cb82e52989480a238e0cf8c67e04b655b36d.zip | |
Auto merge of #89459 - tspiteri:idiv-overflow-bitand, r=kennytm
Use bitand when checking for signed integer division overflow For `self == Self::MIN && rhs == -1`, LLVM does not realize that this is the same check made by `self / rhs`, so the code generated may have some unnecessary duplication. For `(self == Self::MIN) & (rhs == -1)`, LLVM realizes it is the same check.
| -rw-r--r-- | library/core/src/num/int_macros.rs | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index daef5c98967..526e0c37188 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -543,7 +543,8 @@ macro_rules! int_impl { without modifying the original"] #[inline] pub const fn checked_div(self, rhs: Self) -> Option<Self> { - if unlikely!(rhs == 0 || (self == Self::MIN && rhs == -1)) { + // Using `&` helps LLVM see that it is the same check made in division. + if unlikely!(rhs == 0 || ((self == Self::MIN) & (rhs == -1))) { None } else { // SAFETY: div by zero and by INT_MIN have been checked above @@ -569,7 +570,8 @@ macro_rules! int_impl { without modifying the original"] #[inline] pub const fn checked_div_euclid(self, rhs: Self) -> Option<Self> { - if unlikely!(rhs == 0 || (self == Self::MIN && rhs == -1)) { + // Using `&` helps LLVM see that it is the same check made in division. + if unlikely!(rhs == 0 || ((self == Self::MIN) & (rhs == -1))) { None } else { Some(self.div_euclid(rhs)) @@ -595,7 +597,8 @@ macro_rules! int_impl { without modifying the original"] #[inline] pub const fn checked_rem(self, rhs: Self) -> Option<Self> { - if unlikely!(rhs == 0 || (self == Self::MIN && rhs == -1)) { + // Using `&` helps LLVM see that it is the same check made in division. + if unlikely!(rhs == 0 || ((self == Self::MIN) & (rhs == -1))) { None } else { // SAFETY: div by zero and by INT_MIN have been checked above @@ -621,7 +624,8 @@ macro_rules! int_impl { without modifying the original"] #[inline] pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> { - if unlikely!(rhs == 0 || (self == Self::MIN && rhs == -1)) { + // Using `&` helps LLVM see that it is the same check made in division. + if unlikely!(rhs == 0 || ((self == Self::MIN) & (rhs == -1))) { None } else { Some(self.rem_euclid(rhs)) @@ -1466,7 +1470,8 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) { - if unlikely!(self == Self::MIN && rhs == -1) { + // Using `&` helps LLVM see that it is the same check made in division. + if unlikely!((self == Self::MIN) & (rhs == -1)) { (self, true) } else { (self / rhs, false) @@ -1496,7 +1501,8 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) { - if unlikely!(self == Self::MIN && rhs == -1) { + // Using `&` helps LLVM see that it is the same check made in division. + if unlikely!((self == Self::MIN) & (rhs == -1)) { (self, true) } else { (self.div_euclid(rhs), false) @@ -1527,7 +1533,8 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) { - if unlikely!(self == Self::MIN && rhs == -1) { + // Using `&` helps LLVM see that it is the same check made in division. + if unlikely!((self == Self::MIN) & (rhs == -1)) { (0, true) } else { (self % rhs, false) @@ -1558,7 +1565,8 @@ macro_rules! int_impl { without modifying the original"] #[inline] pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) { - if unlikely!(self == Self::MIN && rhs == -1) { + // Using `&` helps LLVM see that it is the same check made in division. + if unlikely!((self == Self::MIN) & (rhs == -1)) { (0, true) } else { (self.rem_euclid(rhs), false) |
