summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/RemoveUnusedBrs.cpp51
-rw-r--r--test/emcc_O2_hello_world.fromasm68
-rw-r--r--test/emcc_O2_hello_world.fromasm.imprecise68
-rw-r--r--test/emcc_hello_world.fromasm203
-rw-r--r--test/emcc_hello_world.fromasm.imprecise203
-rw-r--r--test/memorygrowth.fromasm68
-rw-r--r--test/memorygrowth.fromasm.imprecise68
-rw-r--r--test/passes/remove-unused-brs.txt79
-rw-r--r--test/passes/remove-unused-brs.wast36
-rw-r--r--test/passes/remove-unused-brs_shrink-level=1.txt78
-rw-r--r--test/passes/remove-unused-brs_shrink-level=1.wast39
11 files changed, 608 insertions, 353 deletions
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp
index 328ca275b..69a7c4ff1 100644
--- a/src/passes/RemoveUnusedBrs.cpp
+++ b/src/passes/RemoveUnusedBrs.cpp
@@ -393,6 +393,8 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<R
// perform some final optimizations
struct FinalOptimizer : public PostWalker<FinalOptimizer, Visitor<FinalOptimizer>> {
+ bool selectify;
+
void visitBlock(Block* curr) {
// if a block has an if br else br, we can un-conditionalize the latter, allowing
// the if to become a br_if.
@@ -422,10 +424,55 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<R
continue;
}
}
+ if (list.size() >= 2) {
+ if (selectify) {
+ // Join adjacent br_ifs to the same target, making one br_if with
+ // a "selectified" condition that executes both.
+ for (Index i = 0; i < list.size() - 1; i++) {
+ auto* br1 = list[i]->dynCast<Break>();
+ if (!br1 || !br1->condition) continue;
+ auto* br2 = list[i + 1]->dynCast<Break>();
+ if (!br2 || !br2->condition) continue;
+ if (br1->name == br2->name) {
+ assert(!br1->value && !br2->value);
+ if (!EffectAnalyzer(br2->condition).hasSideEffects()) {
+ // it's ok to execute them both, do it
+ Builder builder(*getModule());
+ br1->condition = builder.makeBinary(OrInt32, br1->condition, br2->condition);
+ ExpressionManipulator::nop(br2);
+ }
+ }
+ }
+ }
+ // Restructuring of ifs: if we have
+ // (block $x
+ // (br_if $x (cond))
+ // .., no other references to $x
+ // )
+ // then we can turn that into (if (!cond) ..).
+ // Code size wise, we turn the block into an if (no change), and
+ // lose the br_if (-2). .. turns into the body of the if in the binary
+ // format. We need to flip the condition, which at worst adds 1.
+ if (curr->name.is()) {
+ auto* br = list[0]->dynCast<Break>();
+ if (br && br->condition && br->name == curr->name) {
+ assert(!br->value); // can't, it would be dropped or last in the block
+ if (BreakSeeker::count(curr, curr->name) == 1) {
+ // no other breaks to that name, so we can do this
+ Builder builder(*getModule());
+ replaceCurrent(builder.makeIf(
+ builder.makeUnary(EqZInt32, br->condition),
+ curr
+ ));
+ curr->name = Name();
+ ExpressionManipulator::nop(br);
+ return;
+ }
+ }
+ }
+ }
}
- bool selectify;
-
void visitIf(If* curr) {
// we may have simplified ifs enough to turn them into selects
// this is helpful for code size, but can be a tradeoff with performance as we run both code paths
diff --git a/test/emcc_O2_hello_world.fromasm b/test/emcc_O2_hello_world.fromasm
index 632906543..e4cbfdce5 100644
--- a/test/emcc_O2_hello_world.fromasm
+++ b/test/emcc_O2_hello_world.fromasm
@@ -8987,48 +8987,46 @@
)
(block
(loop $while-in
- (block $while-out
- (br_if $while-out
- (i32.eqz
- (i32.and
- (get_local $0)
- (i32.const 3)
- )
- )
- )
- (if
- (i32.eqz
- (get_local $2)
- )
- (return
- (get_local $3)
- )
- )
- (i32.store8
+ (if
+ (i32.and
(get_local $0)
- (i32.load8_s
- (get_local $1)
- )
+ (i32.const 3)
)
- (set_local $0
- (i32.add
+ (block
+ (if
+ (i32.eqz
+ (get_local $2)
+ )
+ (return
+ (get_local $3)
+ )
+ )
+ (i32.store8
(get_local $0)
- (i32.const 1)
+ (i32.load8_s
+ (get_local $1)
+ )
)
- )
- (set_local $1
- (i32.add
- (get_local $1)
- (i32.const 1)
+ (set_local $0
+ (i32.add
+ (get_local $0)
+ (i32.const 1)
+ )
)
- )
- (set_local $2
- (i32.sub
- (get_local $2)
- (i32.const 1)
+ (set_local $1
+ (i32.add
+ (get_local $1)
+ (i32.const 1)
+ )
)
+ (set_local $2
+ (i32.sub
+ (get_local $2)
+ (i32.const 1)
+ )
+ )
+ (br $while-in)
)
- (br $while-in)
)
)
(loop $while-in1
diff --git a/test/emcc_O2_hello_world.fromasm.imprecise b/test/emcc_O2_hello_world.fromasm.imprecise
index 36a8a7099..684fa5a6b 100644
--- a/test/emcc_O2_hello_world.fromasm.imprecise
+++ b/test/emcc_O2_hello_world.fromasm.imprecise
@@ -8985,48 +8985,46 @@
)
(block
(loop $while-in
- (block $while-out
- (br_if $while-out
- (i32.eqz
- (i32.and
- (get_local $0)
- (i32.const 3)
- )
- )
- )
- (if
- (i32.eqz
- (get_local $2)
- )
- (return
- (get_local $3)
- )
- )
- (i32.store8
+ (if
+ (i32.and
(get_local $0)
- (i32.load8_s
- (get_local $1)
- )
+ (i32.const 3)
)
- (set_local $0
- (i32.add
+ (block
+ (if
+ (i32.eqz
+ (get_local $2)
+ )
+ (return
+ (get_local $3)
+ )
+ )
+ (i32.store8
(get_local $0)
- (i32.const 1)
+ (i32.load8_s
+ (get_local $1)
+ )
)
- )
- (set_local $1
- (i32.add
- (get_local $1)
- (i32.const 1)
+ (set_local $0
+ (i32.add
+ (get_local $0)
+ (i32.const 1)
+ )
)
- )
- (set_local $2
- (i32.sub
- (get_local $2)
- (i32.const 1)
+ (set_local $1
+ (i32.add
+ (get_local $1)
+ (i32.const 1)
+ )
)
+ (set_local $2
+ (i32.sub
+ (get_local $2)
+ (i32.const 1)
+ )
+ )
+ (br $while-in)
)
- (br $while-in)
)
)
(loop $while-in1
diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm
index 7443cdaff..904d73289 100644
--- a/test/emcc_hello_world.fromasm
+++ b/test/emcc_hello_world.fromasm
@@ -2050,8 +2050,8 @@
)
)
(loop $while-in3
- (block $while-out2
- (br_if $while-out2
+ (if
+ (i32.eqz
(i32.and
(i32.xor
(i32.and
@@ -2073,24 +2073,27 @@
)
)
)
- (set_local $2
- (i32.add
- (get_local $2)
- (i32.const 4)
+ (block
+ (nop)
+ (set_local $2
+ (i32.add
+ (get_local $2)
+ (i32.const 4)
+ )
)
- )
- (br_if $while-in3
- (i32.gt_u
- (tee_local $0
- (i32.add
- (get_local $0)
- (i32.const -4)
+ (br_if $while-in3
+ (i32.gt_u
+ (tee_local $0
+ (i32.add
+ (get_local $0)
+ (i32.const -4)
+ )
)
+ (i32.const 3)
)
- (i32.const 3)
)
+ (br $jumpthreading$inner$0)
)
- (br $jumpthreading$inner$0)
)
)
(br $jumpthreading$outer$0)
@@ -4828,29 +4831,30 @@
)
)
(loop $while-in68
- (block $while-out67
- (br_if $while-out67
- (i32.le_u
- (get_local $5)
- (get_local $6)
- )
+ (if
+ (i32.gt_u
+ (get_local $5)
+ (get_local $6)
)
- (if
- (i32.eqz
- (i32.load
- (tee_local $10
- (i32.add
- (get_local $5)
- (i32.const -4)
+ (block
+ (nop)
+ (if
+ (i32.eqz
+ (i32.load
+ (tee_local $10
+ (i32.add
+ (get_local $5)
+ (i32.const -4)
+ )
)
)
)
- )
- (block
- (set_local $5
- (get_local $10)
+ (block
+ (set_local $5
+ (get_local $10)
+ )
+ (br $while-in68)
)
- (br $while-in68)
)
)
)
@@ -7234,49 +7238,48 @@
(i32.const 1)
)
(loop $while-in130
- (block $while-out129
- (br_if $while-out129
- (i32.eqz
- (tee_local $1
- (i32.load
- (i32.add
- (get_local $4)
- (i32.shl
- (get_local $0)
- (i32.const 2)
- )
- )
+ (if
+ (tee_local $1
+ (i32.load
+ (i32.add
+ (get_local $4)
+ (i32.shl
+ (get_local $0)
+ (i32.const 2)
)
)
)
)
- (call $_pop_arg_336
- (i32.add
- (get_local $3)
- (i32.shl
- (get_local $0)
- (i32.const 3)
+ (block
+ (nop)
+ (call $_pop_arg_336
+ (i32.add
+ (get_local $3)
+ (i32.shl
+ (get_local $0)
+ (i32.const 3)
+ )
)
+ (get_local $1)
+ (get_local $2)
)
- (get_local $1)
- (get_local $2)
- )
- (br_if $while-in130
- (i32.lt_s
- (tee_local $0
- (i32.add
- (get_local $0)
- (i32.const 1)
+ (br_if $while-in130
+ (i32.lt_s
+ (tee_local $0
+ (i32.add
+ (get_local $0)
+ (i32.const 1)
+ )
)
+ (i32.const 10)
)
- (i32.const 10)
)
- )
- (block
- (set_local $16
- (i32.const 1)
+ (block
+ (set_local $16
+ (i32.const 1)
+ )
+ (br $label$break$L343)
)
- (br $label$break$L343)
)
)
)
@@ -15700,48 +15703,46 @@
)
(block
(loop $while-in
- (block $while-out
- (br_if $while-out
- (i32.eqz
- (i32.and
- (get_local $0)
- (i32.const 3)
- )
- )
- )
- (if
- (i32.eqz
- (get_local $2)
- )
- (return
- (get_local $3)
- )
- )
- (i32.store8
+ (if
+ (i32.and
(get_local $0)
- (i32.load8_s
- (get_local $1)
- )
+ (i32.const 3)
)
- (set_local $0
- (i32.add
+ (block
+ (if
+ (i32.eqz
+ (get_local $2)
+ )
+ (return
+ (get_local $3)
+ )
+ )
+ (i32.store8
(get_local $0)
- (i32.const 1)
+ (i32.load8_s
+ (get_local $1)
+ )
)
- )
- (set_local $1
- (i32.add
- (get_local $1)
- (i32.const 1)
+ (set_local $0
+ (i32.add
+ (get_local $0)
+ (i32.const 1)
+ )
)
- )
- (set_local $2
- (i32.sub
- (get_local $2)
- (i32.const 1)
+ (set_local $1
+ (i32.add
+ (get_local $1)
+ (i32.const 1)
+ )
+ )
+ (set_local $2
+ (i32.sub
+ (get_local $2)
+ (i32.const 1)
+ )
)
+ (br $while-in)
)
- (br $while-in)
)
)
(loop $while-in1
diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise
index b3ce6e84e..c8df16aa6 100644
--- a/test/emcc_hello_world.fromasm.imprecise
+++ b/test/emcc_hello_world.fromasm.imprecise
@@ -2043,8 +2043,8 @@
)
)
(loop $while-in3
- (block $while-out2
- (br_if $while-out2
+ (if
+ (i32.eqz
(i32.and
(i32.xor
(i32.and
@@ -2066,24 +2066,27 @@
)
)
)
- (set_local $2
- (i32.add
- (get_local $2)
- (i32.const 4)
+ (block
+ (nop)
+ (set_local $2
+ (i32.add
+ (get_local $2)
+ (i32.const 4)
+ )
)
- )
- (br_if $while-in3
- (i32.gt_u
- (tee_local $0
- (i32.add
- (get_local $0)
- (i32.const -4)
+ (br_if $while-in3
+ (i32.gt_u
+ (tee_local $0
+ (i32.add
+ (get_local $0)
+ (i32.const -4)
+ )
)
+ (i32.const 3)
)
- (i32.const 3)
)
+ (br $jumpthreading$inner$0)
)
- (br $jumpthreading$inner$0)
)
)
(br $jumpthreading$outer$0)
@@ -4820,29 +4823,30 @@
)
)
(loop $while-in68
- (block $while-out67
- (br_if $while-out67
- (i32.le_u
- (get_local $5)
- (get_local $6)
- )
+ (if
+ (i32.gt_u
+ (get_local $5)
+ (get_local $6)
)
- (if
- (i32.eqz
- (i32.load
- (tee_local $10
- (i32.add
- (get_local $5)
- (i32.const -4)
+ (block
+ (nop)
+ (if
+ (i32.eqz
+ (i32.load
+ (tee_local $10
+ (i32.add
+ (get_local $5)
+ (i32.const -4)
+ )
)
)
)
- )
- (block
- (set_local $5
- (get_local $10)
+ (block
+ (set_local $5
+ (get_local $10)
+ )
+ (br $while-in68)
)
- (br $while-in68)
)
)
)
@@ -7220,49 +7224,48 @@
(i32.const 1)
)
(loop $while-in130
- (block $while-out129
- (br_if $while-out129
- (i32.eqz
- (tee_local $1
- (i32.load
- (i32.add
- (get_local $4)
- (i32.shl
- (get_local $0)
- (i32.const 2)
- )
- )
+ (if
+ (tee_local $1
+ (i32.load
+ (i32.add
+ (get_local $4)
+ (i32.shl
+ (get_local $0)
+ (i32.const 2)
)
)
)
)
- (call $_pop_arg_336
- (i32.add
- (get_local $3)
- (i32.shl
- (get_local $0)
- (i32.const 3)
+ (block
+ (nop)
+ (call $_pop_arg_336
+ (i32.add
+ (get_local $3)
+ (i32.shl
+ (get_local $0)
+ (i32.const 3)
+ )
)
+ (get_local $1)
+ (get_local $2)
)
- (get_local $1)
- (get_local $2)
- )
- (br_if $while-in130
- (i32.lt_s
- (tee_local $0
- (i32.add
- (get_local $0)
- (i32.const 1)
+ (br_if $while-in130
+ (i32.lt_s
+ (tee_local $0
+ (i32.add
+ (get_local $0)
+ (i32.const 1)
+ )
)
+ (i32.const 10)
)
- (i32.const 10)
)
- )
- (block
- (set_local $16
- (i32.const 1)
+ (block
+ (set_local $16
+ (i32.const 1)
+ )
+ (br $label$break$L343)
)
- (br $label$break$L343)
)
)
)
@@ -15686,48 +15689,46 @@
)
(block
(loop $while-in
- (block $while-out
- (br_if $while-out
- (i32.eqz
- (i32.and
- (get_local $0)
- (i32.const 3)
- )
- )
- )
- (if
- (i32.eqz
- (get_local $2)
- )
- (return
- (get_local $3)
- )
- )
- (i32.store8
+ (if
+ (i32.and
(get_local $0)
- (i32.load8_s
- (get_local $1)
- )
+ (i32.const 3)
)
- (set_local $0
- (i32.add
+ (block
+ (if
+ (i32.eqz
+ (get_local $2)
+ )
+ (return
+ (get_local $3)
+ )
+ )
+ (i32.store8
(get_local $0)
- (i32.const 1)
+ (i32.load8_s
+ (get_local $1)
+ )
)
- )
- (set_local $1
- (i32.add
- (get_local $1)
- (i32.const 1)
+ (set_local $0
+ (i32.add
+ (get_local $0)
+ (i32.const 1)
+ )
)
- )
- (set_local $2
- (i32.sub
- (get_local $2)
- (i32.const 1)
+ (set_local $1
+ (i32.add
+ (get_local $1)
+ (i32.const 1)
+ )
+ )
+ (set_local $2
+ (i32.sub
+ (get_local $2)
+ (i32.const 1)
+ )
)
+ (br $while-in)
)
- (br $while-in)
)
)
(loop $while-in1
diff --git a/test/memorygrowth.fromasm b/test/memorygrowth.fromasm
index d2c814e8d..48b09d9c3 100644
--- a/test/memorygrowth.fromasm
+++ b/test/memorygrowth.fromasm
@@ -9052,48 +9052,46 @@
)
(block
(loop $while-in
- (block $while-out
- (br_if $while-out
- (i32.eqz
- (i32.and
- (get_local $0)
- (i32.const 3)
- )
- )
- )
- (if
- (i32.eqz
- (get_local $2)
- )
- (return
- (get_local $3)
- )
- )
- (i32.store8
+ (if
+ (i32.and
(get_local $0)
- (i32.load8_s
- (get_local $1)
- )
+ (i32.const 3)
)
- (set_local $0
- (i32.add
+ (block
+ (if
+ (i32.eqz
+ (get_local $2)
+ )
+ (return
+ (get_local $3)
+ )
+ )
+ (i32.store8
(get_local $0)
- (i32.const 1)
+ (i32.load8_s
+ (get_local $1)
+ )
)
- )
- (set_local $1
- (i32.add
- (get_local $1)
- (i32.const 1)
+ (set_local $0
+ (i32.add
+ (get_local $0)
+ (i32.const 1)
+ )
)
- )
- (set_local $2
- (i32.sub
- (get_local $2)
- (i32.const 1)
+ (set_local $1
+ (i32.add
+ (get_local $1)
+ (i32.const 1)
+ )
)
+ (set_local $2
+ (i32.sub
+ (get_local $2)
+ (i32.const 1)
+ )
+ )
+ (br $while-in)
)
- (br $while-in)
)
)
(loop $while-in1
diff --git a/test/memorygrowth.fromasm.imprecise b/test/memorygrowth.fromasm.imprecise
index f9fa51bce..f509f23f2 100644
--- a/test/memorygrowth.fromasm.imprecise
+++ b/test/memorygrowth.fromasm.imprecise
@@ -9050,48 +9050,46 @@
)
(block
(loop $while-in
- (block $while-out
- (br_if $while-out
- (i32.eqz
- (i32.and
- (get_local $0)
- (i32.const 3)
- )
- )
- )
- (if
- (i32.eqz
- (get_local $2)
- )
- (return
- (get_local $3)
- )
- )
- (i32.store8
+ (if
+ (i32.and
(get_local $0)
- (i32.load8_s
- (get_local $1)
- )
+ (i32.const 3)
)
- (set_local $0
- (i32.add
+ (block
+ (if
+ (i32.eqz
+ (get_local $2)
+ )
+ (return
+ (get_local $3)
+ )
+ )
+ (i32.store8
(get_local $0)
- (i32.const 1)
+ (i32.load8_s
+ (get_local $1)
+ )
)
- )
- (set_local $1
- (i32.add
- (get_local $1)
- (i32.const 1)
+ (set_local $0
+ (i32.add
+ (get_local $0)
+ (i32.const 1)
+ )
)
- )
- (set_local $2
- (i32.sub
- (get_local $2)
- (i32.const 1)
+ (set_local $1
+ (i32.add
+ (get_local $1)
+ (i32.const 1)
+ )
)
+ (set_local $2
+ (i32.sub
+ (get_local $2)
+ (i32.const 1)
+ )
+ )
+ (br $while-in)
)
- (br $while-in)
)
)
(loop $while-in1
diff --git a/test/passes/remove-unused-brs.txt b/test/passes/remove-unused-brs.txt
index ab3260a4b..b95ace90d 100644
--- a/test/passes/remove-unused-brs.txt
+++ b/test/passes/remove-unused-brs.txt
@@ -458,12 +458,15 @@
)
)
(loop $in39
- (block $out40
- (br_if $out40
+ (if
+ (i32.eqz
(i32.const 0)
)
- (br_if $in39
- (i32.const 1)
+ (block
+ (nop)
+ (br_if $in39
+ (i32.const 1)
+ )
)
)
)
@@ -595,13 +598,16 @@
)
)
(loop $in72
- (block $out73
- (br_if $out73
+ (if
+ (i32.eqz
(i32.const 0)
)
- (call $loops)
- (return)
- (br $in72)
+ (block
+ (nop)
+ (call $loops)
+ (return)
+ (br $in72)
+ )
)
)
(loop $in75
@@ -876,4 +882,59 @@
)
)
)
+ (func $iffify (type $1)
+ (if
+ (i32.eqz
+ (i32.const 0)
+ )
+ (block
+ (nop)
+ (drop
+ (i32.const 1)
+ )
+ (drop
+ (i32.const 2)
+ )
+ )
+ )
+ (block $no
+ (br_if $no
+ (i32.const 0)
+ )
+ (drop
+ (i32.const 1)
+ )
+ (br $no)
+ (drop
+ (i32.const 2)
+ )
+ )
+ (block $no2
+ (br_if $no2
+ (i32.const 0)
+ )
+ )
+ (block $no3
+ (br $no3)
+ (drop
+ (i32.const 1)
+ )
+ (drop
+ (i32.const 2)
+ )
+ )
+ (block $no5
+ (block $no4
+ (br_if $no5
+ (i32.const 0)
+ )
+ (drop
+ (i32.const 1)
+ )
+ (drop
+ (i32.const 2)
+ )
+ )
+ )
+ )
)
diff --git a/test/passes/remove-unused-brs.wast b/test/passes/remove-unused-brs.wast
index 7a401b893..8b0ad357b 100644
--- a/test/passes/remove-unused-brs.wast
+++ b/test/passes/remove-unused-brs.wast
@@ -795,5 +795,41 @@
)
)
)
+ (func $iffify
+ (block $yes
+ (br_if $yes
+ (i32.const 0)
+ )
+ (drop (i32.const 1))
+ (drop (i32.const 2))
+ )
+ (block $no
+ (br_if $no
+ (i32.const 0)
+ )
+ (drop (i32.const 1))
+ (br $no)
+ (drop (i32.const 2))
+ )
+ (block $no2
+ (br_if $no2
+ (i32.const 0)
+ )
+ )
+ (block $no3
+ (br $no3)
+ (drop (i32.const 1))
+ (drop (i32.const 2))
+ )
+ (block $no5
+ (block $no4
+ (br_if $no5
+ (i32.const 0)
+ )
+ (drop (i32.const 1))
+ (drop (i32.const 2))
+ )
+ )
+ )
)
diff --git a/test/passes/remove-unused-brs_shrink-level=1.txt b/test/passes/remove-unused-brs_shrink-level=1.txt
index 0356cc1da..68015f73f 100644
--- a/test/passes/remove-unused-brs_shrink-level=1.txt
+++ b/test/passes/remove-unused-brs_shrink-level=1.txt
@@ -16,4 +16,82 @@
)
)
)
+ (func $join-br_ifs (type $1)
+ (block $out
+ (br_if $out
+ (i32.or
+ (i32.const 1)
+ (i32.const 2)
+ )
+ )
+ (nop)
+ (br_if $out
+ (i32.const 3)
+ )
+ )
+ (block $out2
+ (block $out3
+ (br_if $out2
+ (i32.const 1)
+ )
+ (br_if $out3
+ (i32.const 2)
+ )
+ (br_if $out2
+ (i32.const 3)
+ )
+ )
+ (unreachable)
+ )
+ (block $out4
+ (block $out5
+ (br_if $out4
+ (i32.const 1)
+ )
+ (br_if $out5
+ (i32.or
+ (i32.const 2)
+ (i32.const 3)
+ )
+ )
+ (nop)
+ )
+ (unreachable)
+ )
+ (block $out6
+ (block $out7
+ (br_if $out6
+ (i32.or
+ (i32.const 1)
+ (i32.const 2)
+ )
+ )
+ (nop)
+ (br_if $out7
+ (i32.const 3)
+ )
+ )
+ (unreachable)
+ )
+ (if
+ (i32.eqz
+ (i32.or
+ (call $b14)
+ (i32.const 0)
+ )
+ )
+ (block
+ (nop)
+ (nop)
+ )
+ )
+ (block $out80
+ (br_if $out80
+ (i32.const 1)
+ )
+ (br_if $out80
+ (call $b14)
+ )
+ )
+ )
)
diff --git a/test/passes/remove-unused-brs_shrink-level=1.wast b/test/passes/remove-unused-brs_shrink-level=1.wast
index 9698bd899..5a2234de6 100644
--- a/test/passes/remove-unused-brs_shrink-level=1.wast
+++ b/test/passes/remove-unused-brs_shrink-level=1.wast
@@ -16,5 +16,44 @@
)
)
)
+ (func $join-br_ifs
+ (block $out
+ (br_if $out (i32.const 1))
+ (br_if $out (i32.const 2))
+ (br_if $out (i32.const 3))
+ )
+ (block $out2
+ (block $out3
+ (br_if $out2 (i32.const 1))
+ (br_if $out3 (i32.const 2))
+ (br_if $out2 (i32.const 3))
+ )
+ (unreachable)
+ )
+ (block $out4
+ (block $out5
+ (br_if $out4 (i32.const 1))
+ (br_if $out5 (i32.const 2))
+ (br_if $out5 (i32.const 3))
+ )
+ (unreachable)
+ )
+ (block $out6
+ (block $out7
+ (br_if $out6 (i32.const 1))
+ (br_if $out6 (i32.const 2))
+ (br_if $out7 (i32.const 3))
+ )
+ (unreachable)
+ )
+ (block $out8
+ (br_if $out8 (call $b14)) ;; side effect
+ (br_if $out8 (i32.const 0))
+ )
+ (block $out8
+ (br_if $out8 (i32.const 1))
+ (br_if $out8 (call $b14)) ;; side effect
+ )
+ )
)