Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve f64 to i32 conversion for Math.imul and Math.clz32 #779

Merged
merged 4 commits into from
Aug 23, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 26 additions & 16 deletions std/assembly/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,28 @@ function expo2(x: f64): f64 { // exp(x)/2 for x >= log(DBL_MAX)
return NativeMath.exp(x - kln2) * scale * scale;
}

// @ts-ignore: decorator
@inline
function dtoi32(x: f64): i32 {
if (ASC_SHRINK_LEVEL > 0) {
const inv32 = 1.0 / 4294967296;
return <i32><i64>(x - 4294967296 * floor(x * inv32));
} else {
let result = 0;
Copy link
Member Author

@MaxGraey MaxGraey Aug 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This path on 10% faster previous one but gen much bigger code so I separate it by ASC_SHRINK_LEVEL

let u = reinterpret<u64>(x);
let e = (u >> 52) & 0x7ff;
if (e <= (1023 + 30)) {
result = <i32>x;
} else if (e <= 1023 + 30 + 53) {
let v = (u & ((<u64>1 << 52) - 1)) | (<u64>1 << 52);
v = v << e - 1023 - 52 + 32;
result = <i32>(v >> 32);
result = select<i32>(-result, result, u >> 63);
}
return result;
}
}

// @ts-ignore: decorator
@lazy
var random_seeded = false;
Expand Down Expand Up @@ -398,9 +420,7 @@ export namespace NativeMath {
* For emulate JS conversion behavior and avoid trapping from wasm we should modulate by MAX_INT
* our float-point arguments before actual convertion to integers.
*/
return builtin_clz(
<i32><i64>(x - 4294967296 * builtin_floor(x * (1.0 / 4294967296)))
);
return builtin_clz(dtoi32(x));
}

export function cos(x: f64): f64 { // TODO
Expand Down Expand Up @@ -599,11 +619,7 @@ export namespace NativeMath {
* our float-point arguments before actual convertion to integers.
*/
if (!isFinite(x + y)) return 0;
const inv32 = 1.0 / 4294967296;
return (
<i32><i64>(x - 4294967296 * builtin_floor(x * inv32)) *
<i32><i64>(y - 4294967296 * builtin_floor(y * inv32))
);
return dtoi32(x) * dtoi32(y);
}

export function log(x: f64): f64 { // see: musl/src/math/log.c and SUN COPYRIGHT NOTICE above
Expand Down Expand Up @@ -1700,9 +1716,7 @@ export namespace NativeMathf {

export function clz32(x: f32): f32 {
if (!isFinite(x)) return 32;
return <f32>builtin_clz(
<i32><i64>(x - 4294967296 * builtin_floor(x * (1.0 / 4294967296)))
);
return <f32>builtin_clz(dtoi32(x));
}

export function cos(x: f32): f32 { // see: musl/src/math/cosf.c
Expand Down Expand Up @@ -1927,11 +1941,7 @@ export namespace NativeMathf {
* our float-point arguments before actual convertion to integers.
*/
if (!isFinite(x + y)) return 0;
const inv32 = 1.0 / 4294967296;
return <f32>(
<i32><i64>(x - 4294967296 * builtin_floor(x * inv32)) *
<i32><i64>(y - 4294967296 * builtin_floor(y * inv32))
);
return <f32>(dtoi32(x) * dtoi32(y));
}

export function log(x: f32): f32 { // see: musl/src/math/logf.c and SUN COPYRIGHT NOTICE above
Expand Down
4 changes: 2 additions & 2 deletions tests/compiler/std/array.optimized.wat
Original file line number Diff line number Diff line change
Expand Up @@ -4156,7 +4156,7 @@
if
i32.const 0
i32.const 3160
i32.const 1020
i32.const 1036
i32.const 4
call $~lib/builtins/abort
unreachable
Expand Down Expand Up @@ -5709,7 +5709,7 @@
if
i32.const 3936
i32.const 3160
i32.const 1029
i32.const 1045
i32.const 24
call $~lib/builtins/abort
unreachable
Expand Down
4 changes: 2 additions & 2 deletions tests/compiler/std/array.untouched.wat
Original file line number Diff line number Diff line change
Expand Up @@ -6534,7 +6534,7 @@
if
i32.const 0
i32.const 3160
i32.const 1020
i32.const 1036
i32.const 4
call $~lib/builtins/abort
unreachable
Expand Down Expand Up @@ -8842,7 +8842,7 @@
if
i32.const 3936
i32.const 3160
i32.const 1029
i32.const 1045
i32.const 24
call $~lib/builtins/abort
unreachable
Expand Down
28 changes: 16 additions & 12 deletions tests/compiler/std/libm.optimized.wat
Original file line number Diff line number Diff line change
Expand Up @@ -5250,6 +5250,7 @@
f32.eq
)
(func $~lib/math/NativeMathf.clz32 (; 85 ;) (type $FUNCSIG$ff) (param $0 f32) (result f32)
(local $1 f64)
local.get $0
call $~lib/number/isFinite<f32>
i32.eqz
Expand All @@ -5258,14 +5259,16 @@
return
end
local.get $0
f32.const 4294967296
local.get $0
f32.const 2.3283064365386963e-10
f32.mul
f32.floor
f32.mul
f32.sub
i64.trunc_f32_s
f64.promote_f32
local.tee $1
f64.const 4294967296
local.get $1
f64.const 2.3283064365386963e-10
f64.mul
f64.floor
f64.mul
f64.sub
i64.trunc_f64_s
i32.wrap_i64
i32.clz
f32.convert_i32_s
Expand Down Expand Up @@ -6204,6 +6207,7 @@
call $~lib/math/NativeMathf.hypot
)
(func $../../lib/libm/assembly/libmf/imul (; 101 ;) (type $FUNCSIG$fff) (param $0 f32) (param $1 f32) (result f32)
(local $2 f64)
block $~lib/math/NativeMathf.imul|inlined.0 (result f32)
f32.const 0
local.get $0
Expand All @@ -6215,9 +6219,9 @@
drop
local.get $0
f64.promote_f32
local.tee $2
f64.const 4294967296
local.get $0
f64.promote_f32
local.get $2
f64.const 2.3283064365386963e-10
f64.mul
f64.floor
Expand All @@ -6227,9 +6231,9 @@
i32.wrap_i64
local.get $1
f64.promote_f32
local.tee $2
f64.const 4294967296
local.get $1
f64.promote_f32
local.get $2
f64.const 2.3283064365386963e-10
f64.mul
f64.floor
Expand Down
Loading