File tree Expand file tree Collapse file tree 4 files changed +52
-2
lines changed Expand file tree Collapse file tree 4 files changed +52
-2
lines changed Original file line number Diff line number Diff line change @@ -3252,6 +3252,20 @@ macro_rules! uint_impl {
32523252 let mut base = self ;
32533253 let mut acc = 1 ;
32543254
3255+ if intrinsics:: is_val_statically_known( base) && base. is_power_of_two( ) {
3256+ // change of base:
3257+ // if base == 2 ** k, then
3258+ // (2 ** k) ** n
3259+ // == 2 ** (k * n)
3260+ // == 1 << (k * n)
3261+ let k = base. ilog2( ) ;
3262+ let shift = k * exp;
3263+ // Panic on overflow if `-C overflow-checks` is enabled.
3264+ // Otherwise will be optimized out
3265+ let _overflow_check = ( 1 as Self ) << shift;
3266+ return ( 1 as Self ) . unbounded_shl( shift)
3267+ }
3268+
32553269 if intrinsics:: is_val_statically_known( exp) {
32563270 while exp > 1 {
32573271 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+ }
Original file line number Diff line number Diff line change 11//@ run-fail
22//@ regex-error-pattern: thread 'main'.*panicked
3- //@ error-pattern: attempt to multiply with overflow
3+ //@ regex- error-pattern: attempt to ( multiply|shift left) with overflow
44//@ needs-subprocess
55//@ compile-flags: -C debug-assertions
66
Original file line number Diff line number Diff line change 11//@ run-fail
22//@ regex-error-pattern: thread 'main'.*panicked
3- //@ error-pattern: attempt to multiply with overflow
3+ //@ regex- error-pattern: attempt to ( multiply|shift left) with overflow
44//@ needs-subprocess
55//@ compile-flags: -C debug-assertions
66
You can’t perform that action at this time.
0 commit comments