Skip to content

Commit 74782d2

Browse files
authored
Do not sink blocks into ifs with unreachable conditions (#7129)
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.
1 parent 31c988b commit 74782d2

3 files changed

Lines changed: 49 additions & 13 deletions

File tree

src/passes/RemoveUnusedBrs.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,12 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
757757
replaceCurrent(loop);
758758
worked = true;
759759
} else if (auto* iff = curr->list[0]->dynCast<If>()) {
760+
if (iff->condition->type == Type::unreachable) {
761+
// The block result type may not be compatible with the arm result
762+
// types since the unreachable If can satisfy any type of block.
763+
// Just leave this for DCE.
764+
return;
765+
}
760766
// The label can't be used in the condition.
761767
if (BranchUtils::BranchSeeker::count(iff->condition, curr->name) ==
762768
0) {

test/lit/passes/remove-unused-brs.wast

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,4 +594,34 @@
594594
)
595595
)
596596
)
597+
598+
;; CHECK: (func $unreachable-if (type $1)
599+
;; CHECK-NEXT: (block $block
600+
;; CHECK-NEXT: (if (result i32)
601+
;; CHECK-NEXT: (unreachable)
602+
;; CHECK-NEXT: (then
603+
;; CHECK-NEXT: (i32.const 0)
604+
;; CHECK-NEXT: )
605+
;; CHECK-NEXT: (else
606+
;; CHECK-NEXT: (br $block)
607+
;; CHECK-NEXT: )
608+
;; CHECK-NEXT: )
609+
;; CHECK-NEXT: )
610+
;; CHECK-NEXT: )
611+
(func $unreachable-if
612+
;; Regression test for a problem where blocks were sunk into ifs with
613+
;; unreachable conditions, causing validation errors when the block type was
614+
;; incompatible with the if type.
615+
(block $block
616+
(if (result i32)
617+
(unreachable)
618+
(then
619+
(i32.const 0)
620+
)
621+
(else
622+
(br $block)
623+
)
624+
)
625+
)
626+
)
597627
)

test/passes/remove-unused-brs_enable-multivalue.txt

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2389,12 +2389,12 @@
23892389
(loop $label$1
23902390
(br_if $label$1
23912391
(block $label$2
2392-
(if
2393-
(block $label$4
2394-
(unreachable)
2395-
)
2396-
(then
2397-
(block $label$3
2392+
(block $label$3
2393+
(if
2394+
(block $label$4
2395+
(unreachable)
2396+
)
2397+
(then
23982398
(br $label$3)
23992399
)
24002400
)
@@ -2405,15 +2405,15 @@
24052405
)
24062406
)
24072407
(func $if-arm-unreachable
2408-
(if
2409-
(unreachable)
2410-
(then
2411-
(block $label$1
2408+
(block $label$1
2409+
(if
2410+
(unreachable)
2411+
(then
24122412
(nop)
24132413
)
2414-
)
2415-
(else
2416-
(unreachable)
2414+
(else
2415+
(unreachable)
2416+
)
24172417
)
24182418
)
24192419
)

0 commit comments

Comments
 (0)