@@ -1974,25 +1974,77 @@ macro_rules! uint_impl {
19741974 #[ inline]
19751975 #[ rustc_inherit_overflow_checks]
19761976 pub const fn pow( self , mut exp: u32 ) -> Self {
1977- if exp == 0 {
1978- return 1 ;
1977+ // LLVM now knows that `self` is a constant value, but not a
1978+ // constant in Rust. This allows us to compute the power used at
1979+ // compile-time.
1980+ //
1981+ // This will likely add a branch in debug builds, but this should
1982+ // be ok.
1983+ //
1984+ // This is a massive performance boost in release builds as you can
1985+ // get the power of a power of two and the exponent through a `shl`
1986+ // instruction, but we must add a couple more checks for parity with
1987+ // our own `pow`.
1988+ #[ cfg( not( bootstrap) ) ]
1989+ if intrinsics:: is_constant( self ) && self . is_power_of_two( ) {
1990+ let power_used = match self . checked_ilog2( ) {
1991+ Some ( v) => v,
1992+ // SAFETY: We just checked this is a power of two. `0` is not a
1993+ // power of two.
1994+ None => unsafe { core:: hint:: unreachable_unchecked( ) } ,
1995+ } ;
1996+ // So it panics. Have to use `overflowing_mul` to efficiently set the
1997+ // result to 0 if not.
1998+ #[ cfg( debug_assertions) ]
1999+ power_used * exp;
2000+ let ( num_shl, overflowed) = power_used. overflowing_mul( exp) ;
2001+ let fine = !overflowed
2002+ & ( power_used < ( mem:: size_of:: <Self >( ) * 8 ) as u32 ) ;
2003+ ( 1 << num_shl) * fine as Self
2004+ } else {
2005+ if exp == 0 {
2006+ return 1 ;
2007+ }
2008+ let mut base = self ;
2009+ let mut acc = 1 ;
2010+
2011+ while exp > 1 {
2012+ if ( exp & 1 ) == 1 {
2013+ acc = acc * base;
2014+ }
2015+ exp /= 2 ;
2016+ base = base * base;
2017+ }
2018+
2019+ // since exp!=0, finally the exp must be 1.
2020+ // Deal with the final bit of the exponent separately, since
2021+ // squaring the base afterwards is not necessary and may cause a
2022+ // needless overflow.
2023+ acc * base
19792024 }
1980- let mut base = self ;
1981- let mut acc = 1 ;
19822025
1983- while exp > 1 {
1984- if ( exp & 1 ) == 1 {
1985- acc = acc * base;
2026+ #[ cfg( bootstrap) ]
2027+ {
2028+ if exp == 0 {
2029+ return 1 ;
2030+ }
2031+ let mut base = self ;
2032+ let mut acc = 1 ;
2033+
2034+ while exp > 1 {
2035+ if ( exp & 1 ) == 1 {
2036+ acc = acc * base;
2037+ }
2038+ exp /= 2 ;
2039+ base = base * base;
19862040 }
1987- exp /= 2 ;
1988- base = base * base;
1989- }
19902041
1991- // since exp!=0, finally the exp must be 1.
1992- // Deal with the final bit of the exponent separately, since
1993- // squaring the base afterwards is not necessary and may cause a
1994- // needless overflow.
1995- acc * base
2042+ // since exp!=0, finally the exp must be 1.
2043+ // Deal with the final bit of the exponent separately, since
2044+ // squaring the base afterwards is not necessary and may cause a
2045+ // needless overflow.
2046+ acc * base
2047+ }
19962048 }
19972049
19982050 /// Returns the square root of the number, rounded down.
0 commit comments