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

``