@@ -2078,6 +2078,17 @@ macro_rules! uint_impl {
20782078 let mut base = self ;
20792079 let mut acc: Self = 1 ;
20802080
2081+ if intrinsics:: is_val_statically_known( base) && base. is_power_of_two( ) {
2082+ // change of base:
2083+ // if base == 2 ** k, then
2084+ // (2 ** k) ** n
2085+ // == 2 ** (k * n)
2086+ // == 1 << (k * n)
2087+ let k = base. ilog2( ) ;
2088+ let shift = try_opt!( k. checked_mul( exp) ) ;
2089+ return ( 1 as Self ) . checked_shl( shift) ;
2090+ }
2091+
20812092 if intrinsics:: is_val_statically_known( exp) {
20822093 while exp > 1 {
20832094 if ( exp & 1 ) == 1 {
@@ -3246,6 +3257,18 @@ macro_rules! uint_impl {
32463257 let mut overflow = false ;
32473258 let mut tmp_overflow;
32483259
3260+ if intrinsics:: is_val_statically_known( base) && base. is_power_of_two( ) {
3261+ // change of base:
3262+ // if base == 2 ** k, then
3263+ // (2 ** k) ** n
3264+ // == 2 ** (k * n)
3265+ // == 1 << (k * n)
3266+ let k = base. ilog2( ) ;
3267+ let ( shift, overflow1) = k. overflowing_mul( exp) ;
3268+ let ( ret, overflow2) = ( ( 1 as Self ) . unbounded_shl( shift) , shift >= Self :: BITS ) ;
3269+ return ( ret, overflow1 | overflow2)
3270+ }
3271+
32493272 if intrinsics:: is_val_statically_known( exp) {
32503273 while exp > 1 {
32513274 if ( exp & 1 ) == 1 {
@@ -3301,6 +3324,20 @@ macro_rules! uint_impl {
33013324 let mut base = self ;
33023325 let mut acc = 1 ;
33033326
3327+ if intrinsics:: is_val_statically_known( base) && base. is_power_of_two( ) {
3328+ // change of base:
3329+ // if base == 2 ** k, then
3330+ // (2 ** k) ** n
3331+ // == 2 ** (k * n)
3332+ // == 1 << (k * n)
3333+ let k = base. ilog2( ) ;
3334+ let shift = k * exp;
3335+ // Panic on overflow if `-C overflow-checks` is enabled.
3336+ // Otherwise will be optimized out
3337+ let _overflow_check = ( 1 as Self ) << shift;
3338+ return ( 1 as Self ) . unbounded_shl( shift)
3339+ }
3340+
33043341 if intrinsics:: is_val_statically_known( exp) {
33053342 while exp > 1 {
33063343 if ( exp & 1 ) == 1 {
0 commit comments