@@ -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,19 @@ 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 Some ( shift) = k. checked_mul( exp) else {
3268+ return ( 0 , true )
3269+ } ;
3270+ return ( ( 1 as Self ) . unbounded_shl( shift) , shift >= Self :: BITS )
3271+ }
3272+
32493273 if intrinsics:: is_val_statically_known( exp) {
32503274 while exp > 1 {
32513275 if ( exp & 1 ) == 1 {
@@ -3301,6 +3325,20 @@ macro_rules! uint_impl {
33013325 let mut base = self ;
33023326 let mut acc = 1 ;
33033327
3328+ if intrinsics:: is_val_statically_known( base) && base. is_power_of_two( ) {
3329+ // change of base:
3330+ // if base == 2 ** k, then
3331+ // (2 ** k) ** n
3332+ // == 2 ** (k * n)
3333+ // == 1 << (k * n)
3334+ let k = base. ilog2( ) ;
3335+ let shift = k * exp;
3336+ // Panic on overflow if `-C overflow-checks` is enabled.
3337+ // Otherwise will be optimized out
3338+ let _overflow_check = ( 1 as Self ) << shift;
3339+ return ( 1 as Self ) . unbounded_shl( shift)
3340+ }
3341+
33043342 if intrinsics:: is_val_statically_known( exp) {
33053343 while exp > 1 {
33063344 if ( exp & 1 ) == 1 {
0 commit comments