File tree Expand file tree Collapse file tree 2 files changed +48
-0
lines changed Expand file tree Collapse file tree 2 files changed +48
-0
lines changed Original file line number Diff line number Diff line change @@ -3314,6 +3314,18 @@ macro_rules! uint_impl {
33143314 let mut base = self ;
33153315 let mut acc = 1 ;
33163316
3317+ if intrinsics:: is_val_statically_known( base) {
3318+ // change of base:
3319+ // if base == 2 ** k, then
3320+ // (2 ** k) ** n
3321+ // == 2 ** (k * n)
3322+ // == 1 << (k * n)
3323+ if base. is_power_of_two( ) {
3324+ let k = base. ilog2( ) ;
3325+ return 1 << ( k * exp)
3326+ }
3327+ }
3328+
33173329 if intrinsics:: is_val_statically_known( exp) {
33183330 while exp > 1 {
33193331 if ( exp & 1 ) == 1 {
Original file line number Diff line number Diff line change 1+ //@ compile-flags: -Copt-level=3
2+ // Test that `pow` can use a faster implementation when `base` is a
3+ // known power of two
4+
5+ #![ crate_type = "lib" ]
6+
7+ // CHECK-LABEL: @pow2
8+ #[ no_mangle]
9+ pub fn pow2 ( exp : u32 ) -> u32 {
10+ // CHECK: %[[SHIFT_AMOUNT:.+]] = and i32 %exp, 31
11+ // CHECK: %[[POW2:.+]] = shl nuw i32 1, %[[SHIFT_AMOUNT]]
12+ // CHECK: ret i32 %[[POW2]]
13+ 2u32 . pow ( exp)
14+ }
15+
16+ // 4 ** n == 2 ** (2 * n) == 1 << (2 * n)
17+ // CHECK-LABEL: @pow4
18+ #[ no_mangle]
19+ pub fn pow4 ( exp : u32 ) -> u32 {
20+ // CHECK: %[[EXP2:.+]] = shl i32 %exp, 1
21+ // CHECK: %[[SHIFT_AMOUNT:.+]] = and i32 %[[EXP2]], 30
22+ // CHECK: %[[POW4:.+]] = shl nuw nsw i32 1, %[[SHIFT_AMOUNT]]
23+ // CHECK: ret i32 %[[POW4]]
24+ 4u32 . pow ( exp)
25+ }
26+
27+ // 16 ** n == 2 ** (4 * n) == 1 << (4 * n)
28+ // CHECK-LABEL: @pow16
29+ #[ no_mangle]
30+ pub fn pow16 ( exp : u32 ) -> u32 {
31+ // CHECK: %[[EXP2:.+]] = shl i32 %exp, 2
32+ // CHECK: %[[SHIFT_AMOUNT:.+]] = and i32 %[[EXP2]], 28
33+ // CHECK: %[[POW16:.+]] = shl nuw nsw i32 1, %[[SHIFT_AMOUNT]]
34+ // CHECK: ret i32 %[[POW16]]
35+ 16u32 . pow ( exp)
36+ }
You can’t perform that action at this time.
0 commit comments