WebAssembly / WebAssembly/binaryen
local-cse introduces side effects via local.tee, blocking DCE in O3
Nobody has claimed this yet.
- Dominant language
- WebAssembly
- Stars
- 8.6k
- Forks
- 885
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 69
Description
Given the following code:
(module
(type $0 (func))
(type $1 (func (param i32 i32) (result i32)))
(import "External" "external_function" (func $external_function (type $0)))
(func $_start (type $1) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32) (local $4 i32) (local $7 i32) (local $8 i32) (local $11 i32) (local $13 i32)
global.get $__stack_pointer
local.set $2
local.get $2
i64.const 0
i64.store offset=1752
i32.const 4058
local.set $4
local.get $2
local.get $4
i32.add
i32.const 1
i32.add
local.set $7
i32.const 4058
local.set $8
local.get $2
local.get $8
i32.add
i32.const 1
i32.add
local.set $11
local.get $7
local.get $11
i32.ne
local.set $13
block ;; label = @1
local.get $13
i32.eqz
br_if 0 (;@1;)
call $external_function
end
unreachable)
(memory $0 259 259)
(global $__stack_pointer (mut i32) (i32.const 0))
(export "_start" (func $_start)))
wasm-opt (862aeb9) eliminates the dead br_if body by -all -O2 but can not do that by -all -O3.
After analysis, O3 performs one more local-cse than O2, thus introducing local.tee (e.g., combining local.set + local.get). However, it also introduces side effect, which blocks constant propagation and then finally blocks DCE
Specifically, through local-cse, wasm-opt transforms the condition (always false) of br_if statements from
(i32.ne
(i32.add
(i32.add
(local.get $0)
(i32.const 4058)
)
(i32.const 1)
)
(i32.add
(i32.add
(local.get $0)
(i32.const 4058)
)
(i32.const 1)
)
)
to
(i32.ne
(local.tee $2
(i32.add
(i32.add
(local.get $0)
(i32.const 4058)
)
(i32.const 1)
)
)
(local.get $2)
)
thus blocking the constant propagation, leading to DCE missed optimization.
Overall, I think it is a missed optimization.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the wasm-opt behavior from the issue with the supplied WebAssembly, comparing -all -O2 and -all -O3. Trace the extra local-cse pass and its local.tee transformation, then verify that the always-false br_if body is removed after the optimization pipeline.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- wasm
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100