WebAssembly / WebAssembly/binaryen
RemoveUnusedBrs causes ineffective code
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
(import "External" "external_function" (func $external_function))
(func $_start (param $0 i32) (param $1 i32)
(local $2 i32) (local $3 i32)
i32.const 587
i32.load8_u
local.set $0
i32.const 24
local.set $1
local.get $0
local.get $1
i32.shl
local.get $1
i32.shr_s
local.set $0
i32.const 587
i32.load8_u
local.set $1
i32.const 24
local.set $2
local.get $1
local.get $2
i32.shl
local.get $2
i32.shr_s
local.set $1
i32.const 587
i32.load8_u
local.set $2
i32.const 24
local.set $3
local.get $2
local.get $3
i32.shl
local.get $3
i32.shr_s
local.set $2
local.get $1
local.get $2
i32.ge_s
local.set $1
block ;; label = @1
local.get $1
br_if 0 (;@1;)
call $external_function
end
local.get $0
i32.const 0
call $foo
drop
unreachable)
(func $foo (param $0 i32) (param $1 i32) (result i32)
unreachable)
(memory $0 258 258)
(export "_start" (func $_start)))
For wasm-opt (c91c052), -O3 -sp=remove-unused-brs produces:
(func $_start (param $0 i32) (param $1 i32)
(drop
(i32.load8_u
(i32.const 587)
)
)
(unreachable)
)
while -O3 produces counter-intuitive code:
(func $_start (param $0 i32) (param $1 i32)
(if
(i32.lt_s
(local.tee $1
(i32.extend8_s
(i32.load8_s
(i32.const 587)
)
)
)
(local.get $1)
)
(then
(call $external_function)
)
)
(unreachable)
)
The RemoveUnusedBrs takes lots efforts to optimize the control flow. However, it causes poor code, which defies our expectations.
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
Reproduce the issue with wasm-opt c91c052 using the supplied WebAssembly and compare -O3 with -O3 -sp=remove-unused-brs. Start at the RemoveUnusedBrs pass and trace how it transforms the control flow; done means the optimizer no longer produces the reported ineffective result and regression coverage preserves the expected behavior.
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