Use is_val_statically_known to optimize pow · patricklam/verify-rust-std@20e64bd

@@ -2172,35 +2172,43 @@ macro_rules! int_impl {

21722172

#[must_use = "this returns the result of the operation, \

21732173

without modifying the original"]

21742174

#[inline]

2175+

#[rustc_allow_const_fn_unstable(is_val_statically_known)]

21752176

pub const fn wrapping_pow(self, mut exp: u32) -> Self {

21762177

let mut base = self;

217721782178-

// Unroll multiplications for small exponent values.

2179-

// This gives the optimizer a way to efficiently inline call sites

2180-

// for the most common use cases with constant exponents.

2181-

// Currently, LLVM is unable to unroll the loop below.

2182-

match exp {

2183-

0 => return 1,

2184-

1 => return base,

2185-

2 => return base.wrapping_mul(base),

2186-

3 => {

2187-

let squared = base.wrapping_mul(base);

2188-

return squared.wrapping_mul(base);

2189-

}

2190-

4 => {

2191-

let squared = base.wrapping_mul(base);

2192-

return squared.wrapping_mul(squared);

2193-

}

2194-

5 => {

2195-

let squared = base.wrapping_mul(base);

2196-

return squared.wrapping_mul(squared).wrapping_mul(base);

2179+

if intrinsics::is_val_statically_known(exp) {

2180+

// Unroll multiplications for small exponent values.

2181+

// This gives the optimizer a way to efficiently inline call sites

2182+

// for the most common use cases with constant exponents.

2183+

// Currently, LLVM is unable to unroll the loop below.

2184+

match exp {

2185+

0 => return 1,

2186+

1 => return base,

2187+

2 => return base.wrapping_mul(base),

2188+

3 => {

2189+

let squared = base.wrapping_mul(base);

2190+

return squared.wrapping_mul(base);

2191+

}

2192+

4 => {

2193+

let squared = base.wrapping_mul(base);

2194+

return squared.wrapping_mul(squared);

2195+

}

2196+

5 => {

2197+

let squared = base.wrapping_mul(base);

2198+

return squared.wrapping_mul(squared).wrapping_mul(base);

2199+

}

2200+

6 => {

2201+

let cubed = base.wrapping_mul(base).wrapping_mul(base);

2202+

return cubed.wrapping_mul(cubed);

2203+

}

2204+

_ => {}

21972205

}

2198-

6 => {

2199-

let cubed = base.wrapping_mul(base).wrapping_mul(base);

2200-

return cubed.wrapping_mul(cubed);

2206+

} else {

2207+

if exp == 0 {

2208+

return 1;

22012209

}

2202-

_ => {}

22032210

}

2211+

debug_assert!(exp != 0);

2204221222052213

let mut acc: Self = 1;

22062214

@@ -2743,35 +2751,43 @@ macro_rules! int_impl {

27432751

without modifying the original"]

27442752

#[inline]

27452753

#[rustc_inherit_overflow_checks]

2754+

#[rustc_allow_const_fn_unstable(is_val_statically_known)]

27462755

pub const fn pow(self, mut exp: u32) -> Self {

27472756

let mut base = self;

274827572749-

// Unroll multiplications for small exponent values.

2750-

// This gives the optimizer a way to efficiently inline call sites

2751-

// for the most common use cases with constant exponents.

2752-

// Currently, LLVM is unable to unroll the loop below.

2753-

match exp {

2754-

0 => return 1,

2755-

1 => return base,

2756-

2 => return base * base,

2757-

3 => {

2758-

let squared = base * base;

2759-

return squared * base;

2760-

}

2761-

4 => {

2762-

let squared = base * base;

2763-

return squared * squared;

2764-

}

2765-

5 => {

2766-

let squared = base * base;

2767-

return squared * squared * base;

2758+

if intrinsics::is_val_statically_known(exp) {

2759+

// Unroll multiplications for small exponent values.

2760+

// This gives the optimizer a way to efficiently inline call sites

2761+

// for the most common use cases with constant exponents.

2762+

// Currently, LLVM is unable to unroll the loop below.

2763+

match exp {

2764+

0 => return 1,

2765+

1 => return base,

2766+

2 => return base * base,

2767+

3 => {

2768+

let squared = base * base;

2769+

return squared * base;

2770+

}

2771+

4 => {

2772+

let squared = base * base;

2773+

return squared * squared;

2774+

}

2775+

5 => {

2776+

let squared = base * base;

2777+

return squared * squared * base;

2778+

}

2779+

6 => {

2780+

let cubed = base * base * base;

2781+

return cubed * cubed;

2782+

}

2783+

_ => {}

27682784

}

2769-

6 => {

2770-

let cubed = base * base * base;

2771-

return cubed * cubed;

2785+

} else {

2786+

if exp == 0 {

2787+

return 1;

27722788

}

2773-

_ => {}

27742789

}

2790+

debug_assert!(exp != 0);

2775279127762792

let mut acc = 1;

27772793