File tree 4 files changed +94
-3
lines changed
4 files changed +94
-3
lines changed Original file line number Diff line number Diff line change @@ -199,7 +199,8 @@ import {
199
199
isPowerOf2 ,
200
200
v128_zero ,
201
201
readI32 ,
202
- isIdentifier
202
+ isIdentifier ,
203
+ accuratePow64
203
204
} from "./util" ;
204
205
205
206
import {
@@ -5322,7 +5323,7 @@ export class Compiler extends DiagnosticEmitter {
5322
5323
let leftValue = getConstValueF32 ( leftExpr ) ;
5323
5324
let rightValue = getConstValueF32 ( rightExpr ) ;
5324
5325
this . currentType = type ;
5325
- return module . f32 ( f32 ( Math . pow ( leftValue , rightValue ) ) ) ;
5326
+ return module . f32 ( f32 ( accuratePow64 ( leftValue , rightValue ) ) ) ;
5326
5327
}
5327
5328
}
5328
5329
let instance = this . f32PowInstance ;
@@ -5364,7 +5365,7 @@ export class Compiler extends DiagnosticEmitter {
5364
5365
let leftValue = getConstValueF64 ( leftExpr ) ;
5365
5366
let rightValue = getConstValueF64 ( rightExpr ) ;
5366
5367
this . currentType = type ;
5367
- return module . f64 ( Math . pow ( leftValue , rightValue ) ) ;
5368
+ return module . f64 ( accuratePow64 ( leftValue , rightValue ) ) ;
5368
5369
}
5369
5370
}
5370
5371
let instance = this . f64PowInstance ;
Original file line number Diff line number Diff line change 7
7
export function isPowerOf2 ( x : i32 ) : bool {
8
8
return x != 0 && ( x & ( x - 1 ) ) == 0 ;
9
9
}
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 59299
59299
call $~lib/builtins/abort
59300
59300
unreachable
59301
59301
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
59302
59372
)
59303
59373
(func $~start
59304
59374
call $start:std/math
Original file line number Diff line number Diff line change @@ -4131,3 +4131,10 @@ assert(0 ** 0.5 == 0.0);
4131
4131
assert ( 0 ** - 1.0 == Infinity ) ;
4132
4132
assert ( 0.0 ** 0 == 1.0 ) ;
4133
4133
assert ( 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