File tree Expand file tree Collapse file tree 4 files changed +94
-3
lines changed
Expand file tree Collapse file tree 4 files changed +94
-3
lines changed Original file line number Diff line number Diff line change @@ -199,7 +199,8 @@ import {
199199 isPowerOf2 ,
200200 v128_zero ,
201201 readI32 ,
202- isIdentifier
202+ isIdentifier ,
203+ accuratePow64
203204} from "./util" ;
204205
205206import {
@@ -5322,7 +5323,7 @@ export class Compiler extends DiagnosticEmitter {
53225323 let leftValue = getConstValueF32 ( leftExpr ) ;
53235324 let rightValue = getConstValueF32 ( rightExpr ) ;
53245325 this . currentType = type ;
5325- return module . f32 ( f32 ( Math . pow ( leftValue , rightValue ) ) ) ;
5326+ return module . f32 ( f32 ( accuratePow64 ( leftValue , rightValue ) ) ) ;
53265327 }
53275328 }
53285329 let instance = this . f32PowInstance ;
@@ -5364,7 +5365,7 @@ export class Compiler extends DiagnosticEmitter {
53645365 let leftValue = getConstValueF64 ( leftExpr ) ;
53655366 let rightValue = getConstValueF64 ( rightExpr ) ;
53665367 this . currentType = type ;
5367- return module . f64 ( Math . pow ( leftValue , rightValue ) ) ;
5368+ return module . f64 ( accuratePow64 ( leftValue , rightValue ) ) ;
53685369 }
53695370 }
53705371 let instance = this . f64PowInstance ;
Original file line number Diff line number Diff line change 77export function isPowerOf2 ( x : i32 ) : bool {
88 return x != 0 && ( x & ( x - 1 ) ) == 0 ;
99}
10+
11+ export function accuratePow64 ( x : f64 , y : f64 ) : f64 {
12+ if ( ! ASC_TARGET ) { // ASC_TARGET == JS
13+ // Engines like V8, WebKit and SpiderMonkey uses powi fast path if exponent is integer
14+ // This speculative optimization leads to loose precisions like 10 ** 208 != 1e208
15+ // or/and 10 ** -5 != 1e-5 anymore. For avoid this behaviour we are forcing exponent
16+ // to fractional form and compensate this afterwards.
17+ if ( isFinite ( y ) && Math . abs ( y ) >= 2 && Math . trunc ( y ) == y ) {
18+ return Math . pow ( x , y - 0.5 ) * Math . pow ( x , 0.5 ) ;
19+ }
20+ }
21+ return Math . pow ( x , y ) ;
22+ }
Original file line number Diff line number Diff line change 5929959299 call $~lib/builtins/abort
5930059300 unreachable
5930159301 end
59302+ f64.const 10
59303+ f64.const 308
59304+ call $~lib/math/NativeMath.pow
59305+ f64.const 1.e+308
59306+ f64.eq
59307+ i32.eqz
59308+ if
59309+ i32.const 0
59310+ i32.const 32
59311+ i32.const 4136
59312+ i32.const 1
59313+ call $~lib/builtins/abort
59314+ unreachable
59315+ end
59316+ f64.const 10
59317+ f64.const 208
59318+ call $~lib/math/NativeMath.pow
59319+ f64.const 1.e+208
59320+ f64.eq
59321+ i32.eqz
59322+ if
59323+ i32.const 0
59324+ i32.const 32
59325+ i32.const 4137
59326+ i32.const 1
59327+ call $~lib/builtins/abort
59328+ unreachable
59329+ end
59330+ f64.const 10
59331+ f64.const -5
59332+ call $~lib/math/NativeMath.pow
59333+ f64.const 1e-05
59334+ f64.eq
59335+ i32.eqz
59336+ if
59337+ i32.const 0
59338+ i32.const 32
59339+ i32.const 4138
59340+ i32.const 1
59341+ call $~lib/builtins/abort
59342+ unreachable
59343+ end
59344+ f32.const 10
59345+ f32.const 38
59346+ call $~lib/math/NativeMathf.pow
59347+ f32.const 9999999680285692465065626e13
59348+ f32.eq
59349+ i32.eqz
59350+ if
59351+ i32.const 0
59352+ i32.const 32
59353+ i32.const 4139
59354+ i32.const 1
59355+ call $~lib/builtins/abort
59356+ unreachable
59357+ end
59358+ f32.const 10
59359+ f32.const -5
59360+ call $~lib/math/NativeMathf.pow
59361+ f32.const 9.999999747378752e-06
59362+ f32.eq
59363+ i32.eqz
59364+ if
59365+ i32.const 0
59366+ i32.const 32
59367+ i32.const 4140
59368+ i32.const 1
59369+ call $~lib/builtins/abort
59370+ unreachable
59371+ end
5930259372 )
5930359373 (func $~start
5930459374 call $start:std/math
Original file line number Diff line number Diff line change @@ -4131,3 +4131,10 @@ assert(0 ** 0.5 == 0.0);
41314131assert ( 0 ** - 1.0 == Infinity ) ;
41324132assert ( 0.0 ** 0 == 1.0 ) ;
41334133assert ( 1.0 ** 1 == 1.0 ) ;
4134+
4135+ // Special cases for test constant fold correctness
4136+ assert ( 10.0 ** 308 == 1e308 ) ;
4137+ assert ( 10.0 ** 208 == 1e208 ) ;
4138+ assert ( 10.0 ** - 5 == 1e-5 ) ;
4139+ assert ( f32 ( 10 ) ** 38 == f32 ( 1e38 ) ) ;
4140+ assert ( f32 ( 10 ) ** - 5 == f32 ( 1e-5 ) ) ;
You can’t perform that action at this time.
0 commit comments