Skip to content

Commit 9f5f8dd

Browse files
authored
RemoveUnusedBrs: Avoid an error on loops with unreachable ifs (#7156)
We normally like to move brs after ifs into the if, when in a loop: (loop $loop (if .. (unreachable) (code) ) (br $loop) ) => (loop $loop (if .. (unreachable) (block (code) (br $loop) ;; moved in ) ) ) However this may be invalid to do if the if condition is unreachable, as then one arm may be concrete (`code` in the example could be an `i32`, for example). As this is dead code anyhow, leave it for DCE.
1 parent c930094 commit 9f5f8dd

File tree

2 files changed

+57
-19
lines changed

2 files changed

+57
-19
lines changed

src/passes/RemoveUnusedBrs.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -621,9 +621,13 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
621621
block->finalize();
622622
return true;
623623
}
624-
} else {
625-
// this is already an if-else. if one side is a dead end, we can
626-
// append to the other, if there is no returned value to concern us
624+
} else if (iff->condition->type != Type::unreachable) {
625+
// This is already an if-else. If one side is a dead end, we can
626+
// append to the other, if there is no returned value to concern us.
627+
// Note that we skip ifs with unreachable conditions, as they are dead
628+
// code that DCE can remove, and modifying them can lead to errors
629+
// (one of the arms may still be concrete, in which case appending to
630+
// it would be invalid).
627631

628632
// can't be, since in the middle of a block
629633
assert(!iff->type.isConcrete());

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

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
)
3131
)
3232

33-
;; CHECK: (func $selectify-simple (type $0) (param $0 i32) (result i32)
33+
;; CHECK: (func $selectify-simple (type $1) (param $0 i32) (result i32)
3434
;; CHECK-NEXT: (select
3535
;; CHECK-NEXT: (i32.const 1)
3636
;; CHECK-NEXT: (i32.lt_u
@@ -73,7 +73,7 @@
7373
)
7474
)
7575

76-
;; CHECK: (func $restructure-br_if (type $0) (param $x i32) (result i32)
76+
;; CHECK: (func $restructure-br_if (type $1) (param $x i32) (result i32)
7777
;; CHECK-NEXT: (if (result i32)
7878
;; CHECK-NEXT: (local.get $x)
7979
;; CHECK-NEXT: (then
@@ -104,12 +104,12 @@
104104
)
105105
)
106106

107-
;; CHECK: (func $nothing (type $1)
107+
;; CHECK: (func $nothing (type $0)
108108
;; CHECK-NEXT: )
109109
(func $nothing)
110110

111111

112-
;; CHECK: (func $restructure-br_if-condition-reorderable (type $0) (param $x i32) (result i32)
112+
;; CHECK: (func $restructure-br_if-condition-reorderable (type $1) (param $x i32) (result i32)
113113
;; CHECK-NEXT: (if (result i32)
114114
;; CHECK-NEXT: (block (result i32)
115115
;; CHECK-NEXT: (call $nothing)
@@ -146,7 +146,7 @@
146146
)
147147
)
148148

149-
;; CHECK: (func $restructure-br_if-value-effectful (type $0) (param $x i32) (result i32)
149+
;; CHECK: (func $restructure-br_if-value-effectful (type $1) (param $x i32) (result i32)
150150
;; CHECK-NEXT: (select
151151
;; CHECK-NEXT: (block (result i32)
152152
;; CHECK-NEXT: (call $nothing)
@@ -188,7 +188,7 @@
188188
)
189189
)
190190

191-
;; CHECK: (func $restructure-br_if-value-effectful-corner-case-1 (type $0) (param $x i32) (result i32)
191+
;; CHECK: (func $restructure-br_if-value-effectful-corner-case-1 (type $1) (param $x i32) (result i32)
192192
;; CHECK-NEXT: (block $x (result i32)
193193
;; CHECK-NEXT: (drop
194194
;; CHECK-NEXT: (br_if $x
@@ -233,7 +233,7 @@
233233
(i32.const 400)
234234
)
235235

236-
;; CHECK: (func $restructure-br_if-value-effectful-corner-case-2 (type $0) (param $x i32) (result i32)
236+
;; CHECK: (func $restructure-br_if-value-effectful-corner-case-2 (type $1) (param $x i32) (result i32)
237237
;; CHECK-NEXT: (block $x (result i32)
238238
;; CHECK-NEXT: (drop
239239
;; CHECK-NEXT: (br_if $x
@@ -272,7 +272,7 @@
272272
(call $get-i32)
273273
)
274274
)
275-
;; CHECK: (func $restructure-br_if-value-effectful-corner-case-3 (type $0) (param $x i32) (result i32)
275+
;; CHECK: (func $restructure-br_if-value-effectful-corner-case-3 (type $1) (param $x i32) (result i32)
276276
;; CHECK-NEXT: (block $x (result i32)
277277
;; CHECK-NEXT: (drop
278278
;; CHECK-NEXT: (br_if $x
@@ -305,7 +305,7 @@
305305
)
306306
)
307307

308-
;; CHECK: (func $restructure-br_if-value-effectful-corner-case-4 (type $0) (param $x i32) (result i32)
308+
;; CHECK: (func $restructure-br_if-value-effectful-corner-case-4 (type $1) (param $x i32) (result i32)
309309
;; CHECK-NEXT: (block $x (result i32)
310310
;; CHECK-NEXT: (drop
311311
;; CHECK-NEXT: (br_if $x
@@ -340,7 +340,7 @@
340340
)
341341
)
342342

343-
;; CHECK: (func $restructure-select-no-multivalue (type $1)
343+
;; CHECK: (func $restructure-select-no-multivalue (type $0)
344344
;; CHECK-NEXT: (tuple.drop 2
345345
;; CHECK-NEXT: (block $block (type $2) (result i32 i32)
346346
;; CHECK-NEXT: (tuple.drop 2
@@ -387,7 +387,7 @@
387387
)
388388
)
389389

390-
;; CHECK: (func $if-of-if (type $1)
390+
;; CHECK: (func $if-of-if (type $0)
391391
;; CHECK-NEXT: (local $x i32)
392392
;; CHECK-NEXT: (if
393393
;; CHECK-NEXT: (select
@@ -421,7 +421,7 @@
421421
)
422422
)
423423

424-
;; CHECK: (func $if-of-if-but-side-effects (type $1)
424+
;; CHECK: (func $if-of-if-but-side-effects (type $0)
425425
;; CHECK-NEXT: (local $x i32)
426426
;; CHECK-NEXT: (if
427427
;; CHECK-NEXT: (local.tee $x
@@ -460,7 +460,7 @@
460460
)
461461
)
462462

463-
;; CHECK: (func $if-of-if-but-too-costly (type $1)
463+
;; CHECK: (func $if-of-if-but-too-costly (type $0)
464464
;; CHECK-NEXT: (local $x i32)
465465
;; CHECK-NEXT: (if
466466
;; CHECK-NEXT: (local.tee $x
@@ -515,7 +515,7 @@
515515
)
516516
)
517517

518-
;; CHECK: (func $if-of-if-but-inner-else (type $1)
518+
;; CHECK: (func $if-of-if-but-inner-else (type $0)
519519
;; CHECK-NEXT: (local $x i32)
520520
;; CHECK-NEXT: (if
521521
;; CHECK-NEXT: (local.tee $x
@@ -555,7 +555,7 @@
555555
)
556556
)
557557

558-
;; CHECK: (func $if-of-if-but-outer-else (type $1)
558+
;; CHECK: (func $if-of-if-but-outer-else (type $0)
559559
;; CHECK-NEXT: (local $x i32)
560560
;; CHECK-NEXT: (if
561561
;; CHECK-NEXT: (local.tee $x
@@ -595,7 +595,7 @@
595595
)
596596
)
597597

598-
;; CHECK: (func $unreachable-if (type $1)
598+
;; CHECK: (func $unreachable-if (type $0)
599599
;; CHECK-NEXT: (block $block
600600
;; CHECK-NEXT: (if (result i32)
601601
;; CHECK-NEXT: (unreachable)
@@ -624,4 +624,38 @@
624624
)
625625
)
626626
)
627+
628+
;; CHECK: (func $loop-with-unreachable-if (type $0)
629+
;; CHECK-NEXT: (loop $label
630+
;; CHECK-NEXT: (if (result i32)
631+
;; CHECK-NEXT: (unreachable)
632+
;; CHECK-NEXT: (then
633+
;; CHECK-NEXT: (unreachable)
634+
;; CHECK-NEXT: )
635+
;; CHECK-NEXT: (else
636+
;; CHECK-NEXT: (i32.const 0)
637+
;; CHECK-NEXT: )
638+
;; CHECK-NEXT: )
639+
;; CHECK-NEXT: (br $label)
640+
;; CHECK-NEXT: )
641+
;; CHECK-NEXT: )
642+
(func $loop-with-unreachable-if
643+
;; We normally move brs right after an if into one of the if arms, when
644+
;; possible. That is almost possible here, but the if condition is
645+
;; unreachable, which allows one of the arms to have a concrete type. It is
646+
;; invalid to append to such an arm, so we should do nothing (leaving this
647+
;; for DCE).
648+
(loop $label
649+
(if (result i32)
650+
(unreachable)
651+
(then
652+
(unreachable)
653+
)
654+
(else
655+
(i32.const 0)
656+
)
657+
)
658+
(br $label)
659+
)
660+
)
627661
)

0 commit comments

Comments
 (0)