Skip to content

Commit

Permalink
Do not sink blocks into ifs with unreachable conditions (#7129)
Browse files Browse the repository at this point in the history
RemoveUnusedBrs sinks blocks into If arms when those arms contain
branches to the blocks and the other arm and condition do not. Now that
we type Ifs with unreachable conditions as unreachable, it is possible
for the If arms to have a different type than the block that would be
sunk, so sinking the block would produce invalid IR. Fix the problem by
never sinking blocks into Ifs with unreachable conditions.

Fixes #7128.
  • Loading branch information
tlively authored Dec 2, 2024
1 parent 31c988b commit 74782d2
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 13 deletions.
6 changes: 6 additions & 0 deletions src/passes/RemoveUnusedBrs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,12 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
replaceCurrent(loop);
worked = true;
} else if (auto* iff = curr->list[0]->dynCast<If>()) {
if (iff->condition->type == Type::unreachable) {
// The block result type may not be compatible with the arm result
// types since the unreachable If can satisfy any type of block.
// Just leave this for DCE.
return;
}
// The label can't be used in the condition.
if (BranchUtils::BranchSeeker::count(iff->condition, curr->name) ==
0) {
Expand Down
30 changes: 30 additions & 0 deletions test/lit/passes/remove-unused-brs.wast
Original file line number Diff line number Diff line change
Expand Up @@ -594,4 +594,34 @@
)
)
)

;; CHECK: (func $unreachable-if (type $1)
;; CHECK-NEXT: (block $block
;; CHECK-NEXT: (if (result i32)
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: (then
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (else
;; CHECK-NEXT: (br $block)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $unreachable-if
;; Regression test for a problem where blocks were sunk into ifs with
;; unreachable conditions, causing validation errors when the block type was
;; incompatible with the if type.
(block $block
(if (result i32)
(unreachable)
(then
(i32.const 0)
)
(else
(br $block)
)
)
)
)
)
26 changes: 13 additions & 13 deletions test/passes/remove-unused-brs_enable-multivalue.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2389,12 +2389,12 @@
(loop $label$1
(br_if $label$1
(block $label$2
(if
(block $label$4
(unreachable)
)
(then
(block $label$3
(block $label$3
(if
(block $label$4
(unreachable)
)
(then
(br $label$3)
)
)
Expand All @@ -2405,15 +2405,15 @@
)
)
(func $if-arm-unreachable
(if
(unreachable)
(then
(block $label$1
(block $label$1
(if
(unreachable)
(then
(nop)
)
)
(else
(unreachable)
(else
(unreachable)
)
)
)
)
Expand Down

0 comments on commit 74782d2

Please sign in to comment.