binaryen
binaryen copied to clipboard
[Unhoisted] [Unary] load & store order affects the constant propagation in unary
Given the following code:
(module
(import "External" "external_function" (func $external_function))
(func $_start (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
(local $4 i64) (local $5 i64) (local $6 i64)
call $foo
local.set $6
call $bar
i64.extend_i32_s
local.set $4
local.get $6
local.get $4
i64.and
local.set $4
local.get $4
i32.wrap_i64
local.set $1
block ;; label = @1
local.get $1
i32.eqz
br_if 0 (;@1;)
call $external_function
end)
(func $bar (result i32)
i32.const 0
i32.const 0
i32.store
i32.const 0)
(func $foo (result i64)
i32.const 0
i64.load)
(memory $0 258 258)
(export "_start" (func $_start)))
wasm-opt (755a8d0) can deduce the condition to constant by -all -O2 but cannot by -all -O3:
Below is optimized code by -all -O3:
(module
(type $0 (func))
(type $1 (func (param i32 i32 i32 i32)))
(import "External" "external_function" (func $external_function (type $0)))
(memory $0 258 258)
(export "_start" (func $_start))
(func $_start (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
(if
(i32.wrap_i64
(i64.and
(i64.load
(i32.const 0)
)
(block (result i64)
(i32.store
(i32.const 0)
(i32.const 0)
)
(i64.const 0)
)
)
)
(then
(call $external_function)
)
)
)
)
Obviously, due to the side effects of load and store instructions, reordering is not possible for merge-blocks. As a result, the constant zero within a block cannot be recognized, which affects constant propagation and, consequently, hinders dead code elimination.
Similar but different to #7455, this issue lies in unary operation. I think it would be best to resolve that issue first before returning to this one.