Revert to original loop for const pow exponents · rust-lang/rust@ac88b33 (original) (raw)

`@@ -2174,54 +2174,41 @@ macro_rules! int_impl {

`

2174

2174

` #[inline]

`

2175

2175

` #[rustc_allow_const_fn_unstable(is_val_statically_known)]

`

2176

2176

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

`

``

2177

`+

if exp == 0 {

`

``

2178

`+

return 1;

`

``

2179

`+

}

`

2177

2180

`let mut base = self;

`

``

2181

`+

let mut acc: Self = 1;

`

2178

2182

``

2179

2183

`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);

`

``

2184

`+

while exp > 1 {

`

``

2185

`+

if (exp & 1) == 1 {

`

``

2186

`+

acc = acc.wrapping_mul(base);

`

2195

2187

`}

`

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

``

`-

_ => {}

`

``

2188

`+

exp /= 2;

`

``

2189

`+

base = base.wrapping_mul(base);

`

2205

2190

`}

`

2206

``

`-

} else {

`

2207

``

`-

if exp == 0 {

`

2208

``

`-

return 1;

`

2209

``

`-

}

`

2210

``

`-

}

`

2211

``

`-

debug_assert!(exp != 0);

`

2212

2191

``

2213

``

`-

let mut acc: Self = 1;

`

2214

``

-

2215

``

`-

loop {

`

2216

``

`-

if (exp & 1) == 1 {

`

2217

``

`-

acc = acc.wrapping_mul(base);

`

2218

``

`-

// since exp!=0, finally the exp must be 1.

`

2219

``

`-

if exp == 1 {

`

2220

``

`-

return acc;

`

``

2192

`+

// since exp!=0, finally the exp must be 1.

`

``

2193

`+

// Deal with the final bit of the exponent separately, since

`

``

2194

`+

// squaring the base afterwards is not necessary.

`

``

2195

`+

acc.wrapping_mul(base)

`

``

2196

`+

} else {

`

``

2197

`+

// This is faster than the above when the exponent is not known

`

``

2198

`+

// at compile time. We can't use the same code for the constant

`

``

2199

`+

// exponent case because LLVM is currently unable to unroll

`

``

2200

`+

// this loop.

`

``

2201

`+

loop {

`

``

2202

`+

if (exp & 1) == 1 {

`

``

2203

`+

acc = acc.wrapping_mul(base);

`

``

2204

`+

// since exp!=0, finally the exp must be 1.

`

``

2205

`+

if exp == 1 {

`

``

2206

`+

return acc;

`

``

2207

`+

}

`

2221

2208

`}

`

``

2209

`+

exp /= 2;

`

``

2210

`+

base = base.wrapping_mul(base);

`

2222

2211

`}

`

2223

``

`-

exp /= 2;

`

2224

``

`-

base = base.wrapping_mul(base);

`

2225

2212

`}

`

2226

2213

`}

`

2227

2214

``

`@@ -2753,54 +2740,42 @@ macro_rules! int_impl {

`

2753

2740

` #[rustc_inherit_overflow_checks]

`

2754

2741

` #[rustc_allow_const_fn_unstable(is_val_statically_known)]

`

2755

2742

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

`

``

2743

`+

if exp == 0 {

`

``

2744

`+

return 1;

`

``

2745

`+

}

`

2756

2746

`let mut base = self;

`

``

2747

`+

let mut acc = 1;

`

2757

2748

``

2758

2749

`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;

`

``

2750

`+

while exp > 1 {

`

``

2751

`+

if (exp & 1) == 1 {

`

``

2752

`+

acc = acc * base;

`

2774

2753

`}

`

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

``

`-

_ => {}

`

``

2754

`+

exp /= 2;

`

``

2755

`+

base = base * base;

`

2784

2756

`}

`

2785

``

`-

} else {

`

2786

``

`-

if exp == 0 {

`

2787

``

`-

return 1;

`

2788

``

`-

}

`

2789

``

`-

}

`

2790

``

`-

debug_assert!(exp != 0);

`

2791

2757

``

2792

``

`-

let mut acc = 1;

`

2793

``

-

2794

``

`-

loop {

`

2795

``

`-

if (exp & 1) == 1 {

`

2796

``

`-

acc = acc * base;

`

2797

``

`-

// since exp!=0, finally the exp must be 1.

`

2798

``

`-

if exp == 1 {

`

2799

``

`-

return acc;

`

``

2758

`+

// since exp!=0, finally the exp must be 1.

`

``

2759

`+

// Deal with the final bit of the exponent separately, since

`

``

2760

`+

// squaring the base afterwards is not necessary and may cause a

`

``

2761

`+

// needless overflow.

`

``

2762

`+

acc * base

`

``

2763

`+

} else {

`

``

2764

`+

// This is faster than the above when the exponent is not known

`

``

2765

`+

// at compile time. We can't use the same code for the constant

`

``

2766

`+

// exponent case because LLVM is currently unable to unroll

`

``

2767

`+

// this loop.

`

``

2768

`+

loop {

`

``

2769

`+

if (exp & 1) == 1 {

`

``

2770

`+

acc = acc * base;

`

``

2771

`+

// since exp!=0, finally the exp must be 1.

`

``

2772

`+

if exp == 1 {

`

``

2773

`+

return acc;

`

``

2774

`+

}

`

2800

2775

`}

`

``

2776

`+

exp /= 2;

`

``

2777

`+

base = base * base;

`

2801

2778

`}

`

2802

``

`-

exp /= 2;

`

2803

``

`-

base = base * base;

`

2804

2779

`}

`

2805

2780

`}

`

2806

2781

``