From e4bc79db7fe48fa539ca13f0c1ff6cb069f95581 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 22 Jun 2024 23:00:44 -0700 Subject: [PATCH] Also get `add nuw` from `uN::checked_add` --- core/src/num/uint_macros.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/core/src/num/uint_macros.rs b/core/src/num/uint_macros.rs index 00450c2cda3e6..42f23f7ed71a9 100644 --- a/core/src/num/uint_macros.rs +++ b/core/src/num/uint_macros.rs @@ -455,8 +455,19 @@ macro_rules! uint_impl { without modifying the original"] #[inline] pub const fn checked_add(self, rhs: Self) -> Option { - let (a, b) = self.overflowing_add(rhs); - if unlikely!(b) { None } else { Some(a) } + // This used to use `overflowing_add`, but that means it ends up being + // a `wrapping_add`, losing some optimization opportunities. Notably, + // phrasing it this way helps `.checked_add(1)` optimize to a check + // against `MAX` and a `add nuw`. + // Per , + // LLVM is happy to re-form the intrinsic later if useful. + + if unlikely!(intrinsics::add_with_overflow(self, rhs).1) { + None + } else { + // SAFETY: Just checked it doesn't overflow + Some(unsafe { intrinsics::unchecked_add(self, rhs) }) + } } /// Strict integer addition. Computes `self + rhs`, panicking