binaryen
binaryen copied to clipboard
RemoveUnusedBrs: optimize unreachable control flow mixed with side-effecting branches
Currently wasm-opt cannot optimize unused branch complexed with side-effect operations, such as
(func $_start
(local $0 i32)
(block $block
(br_if $block
(local.tee $0
(i32.const 1)
)
)
(br_if $block
(i32.load
(i32.const 0)
)
)
(local.set $0
(i32.const 0)
)
)
(i32.store
(i32.const 0)
(local.get $0)
)
)
Actually, the whole block can be removed. However, O3 cannot optimize it (while O2 could).
Fixes: #7637
The fuzzer found a bug here:
(module
(type (;0;) (func (param i64)))
(type (;1;) (func))
(import "fuzzing-support" "log-i64" (func (;0;) (type 0)))
(func (;1;) (type 1)
(local i64 i32)
block ;; label = @1
block ;; label = @2
global.get 0
if ;; label = @3
i32.const 1
local.tee 1
if ;; label = @4
br 3 (;@1;)
else
br 2 (;@2;)
end
unreachable
else
unreachable
end
unreachable
end
local.get 0
call 0
end)
(global (;0;) (mut i32) (i32.const 0)))
$ bin/wasm-opt b.wat -O1 -S -o -
wasm-opt: SimplifyLocals.cpp:666: void wasm::SimplifyLocals<allowTee, allowStructure, allowNesting>::optimizeIfElseReturn(wasm::If*, wasm::Expression**, Sinkables&) [with bool allowTee = true; bool allowStructure = true; bool allowNesting = true; Sinkables = std::map<unsigned int, wasm::SimplifyLocals<true, true>::SinkableInfo, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, wasm::SimplifyLocals<true, true>::SinkableInfo> > >]:
Assertion `iff->ifFalse->type != Type::unreachable' failed.
Aborted (core dumped)
(Work in progress)
BTW: fuzzing for about one hour, and no bad news.