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