Use is_val_statically_known to optimize pow · patricklam/verify-rust-std@20e64bd (original) (raw)
`@@ -2172,35 +2172,43 @@ macro_rules! int_impl {
`
2172
2172
` #[must_use = "this returns the result of the operation, \
`
2173
2173
` without modifying the original"]
`
2174
2174
` #[inline]
`
``
2175
`+
#[rustc_allow_const_fn_unstable(is_val_statically_known)]
`
2175
2176
`pub const fn wrapping_pow(self, mut exp: u32) -> Self {
`
2176
2177
`let mut base = self;
`
2177
2178
``
2178
``
`-
// 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
`+
_ => {}
`
2197
2205
`}
`
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;
`
2201
2209
`}
`
2202
``
`-
_ => {}
`
2203
2210
`}
`
``
2211
`+
debug_assert!(exp != 0);
`
2204
2212
``
2205
2213
`let mut acc: Self = 1;
`
2206
2214
``
`@@ -2743,35 +2751,43 @@ macro_rules! int_impl {
`
2743
2751
` without modifying the original"]
`
2744
2752
` #[inline]
`
2745
2753
` #[rustc_inherit_overflow_checks]
`
``
2754
`+
#[rustc_allow_const_fn_unstable(is_val_statically_known)]
`
2746
2755
`pub const fn pow(self, mut exp: u32) -> Self {
`
2747
2756
`let mut base = self;
`
2748
2757
``
2749
``
`-
// 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
`+
_ => {}
`
2768
2784
`}
`
2769
``
`-
6 => {
`
2770
``
`-
let cubed = base * base * base;
`
2771
``
`-
return cubed * cubed;
`
``
2785
`+
} else {
`
``
2786
`+
if exp == 0 {
`
``
2787
`+
return 1;
`
2772
2788
`}
`
2773
``
`-
_ => {}
`
2774
2789
`}
`
``
2790
`+
debug_assert!(exp != 0);
`
2775
2791
``
2776
2792
`let mut acc = 1;
`
2777
2793
``