-
Notifications
You must be signed in to change notification settings - Fork 810
Closed
Description
Given the following code:
(module
(import "External" "external_function" (func $external_function))
(func $_start
i32.const 0
i32.const 0
call $foo)
(func $foo (param $0 i32) (param $2 i32)
block ;; label = @1
i32.const 0
i32.load
drop
i32.const 1
i32.load
local.set $2
i32.const 1
local.set $0
local.get $2
br_if 0 (;@1;)
i32.const 1
local.set $0
local.get $0
br_if 0 (;@1;)
i32.const 0
local.set $0
end
block ;; label = @1
local.get $0
br_if 0 (;@1;)
call $external_function
end)
(memory $0 258 258)
(export "_start" (func $_start)))
wasm-opt (c528c7e) can deduce the condition of branch (in the second block) to true by -all -O2
, but cannot by -all -O3
.
Below is the optimized code by -all -O3
:
(if
(i32.eqz
(block $block (result i32)
(drop
(i32.load (i32.const 0))
)
(drop
(br_if $block
(i32.const 1)
(i32.load (i32.const 1))
)
)
(i32.const 1)
)
)
(then (call $external_function))
)
It appears that the constant 1 is "buried" within the blocks and should be hoisted out so it can be recognized by i32.eqz
.
This is similar to #7455 (where a constant value should be hoisted out in a binary operation). The same principle could be apply to unary operations. However, the key difference here is that these blocks here have names thus preventing them from being "fallthrough".
Here is the relevant code in getImmediateFallthroughPtr
:
Lines 288 to 292 in 93c541d
} else if (auto* block = curr->dynCast<Block>()) { | |
// if no name, we can't be broken to, and then can look at the fallthrough | |
if (!block->name.is() && block->list.size() > 0) { | |
return &block->list.back(); | |
} |
What do you think? Is there any better way to resolve it?
Metadata
Metadata
Assignees
Labels
No labels