Closed
Description
Consider this snippet:
let w = 42 >> 1;
w = (w & 0xFC) | (w >> 1);
export const x = w;
The only exported value is x
and it's a constant, so the compiled output should likely be
(global $module/x i32 (i32.const 30))
(export "x" (global $module/x))
Instead, the compiler produces the following (with -O3
):
(global $module/w (mut i32) (i32.const 0))
(global $module/x (mut i32) (i32.const 0))
(export "x" (global $module/x))
(start $~start)
(func $~start
i32.const 21
global.set $module/w
i32.const 30
global.set $module/w
i32.const 30
global.set $module/x
)
This output shows several issues:
x
is exported as a mutable global;w
exists as an internal global despite being used only for setting thex
value once (fixed by-O3z
);- two consecutive
global.set
calls are used onw
(also fixed by-O3z
).
What's more interesting is that simplifying the first line leads to even more complex output.
let w = 21;
w = (w & 0xFC) | (w >> 1);
export const x = w;
(global $module/w (mut i32) (i32.const 21))
(global $module/x (mut i32) (i32.const 0))
(export "x" (global $module/x))
(start $~start)
(func $~start
(local $0 i32)
global.get $module/w
local.tee $0
i32.const 252
i32.and
local.get $0
i32.const 1
i32.shr_s
i32.or
global.set $module/w
global.get $module/w
global.set $module/x
)
Metadata
Metadata
Assignees
Labels
No labels