summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ast_utils.h15
-rw-r--r--src/passes/RemoveUnusedBrs.cpp42
-rw-r--r--test/emcc_O2_hello_world.fromasm39
-rw-r--r--test/emcc_O2_hello_world.fromasm.imprecise39
-rw-r--r--test/emcc_hello_world.fromasm216
-rw-r--r--test/emcc_hello_world.fromasm.imprecise216
-rw-r--r--test/example/c-api-kitchen-sink.txt20
-rw-r--r--test/example/c-api-kitchen-sink.txt.txt10
-rw-r--r--test/example/relooper-fuzz.txt56
-rw-r--r--test/memorygrowth.fromasm39
-rw-r--r--test/memorygrowth.fromasm.imprecise39
-rw-r--r--test/passes/remove-unused-brs.txt57
-rw-r--r--test/passes/remove-unused-brs.wast13
13 files changed, 426 insertions, 375 deletions
diff --git a/src/ast_utils.h b/src/ast_utils.h
index 6b76dd61d..e785a8daa 100644
--- a/src/ast_utils.h
+++ b/src/ast_utils.h
@@ -364,6 +364,21 @@ struct ExpressionManipulator {
} copier;
return flexibleCopy(original, wasm, copier);
}
+
+ // Splice an item into the middle of a block's list
+ static void spliceIntoBlock(Block* block, Index index, Expression* add) {
+ auto& list = block->list;
+ if (index == list.size()) {
+ list.push_back(add); // simple append
+ } else {
+ // we need to make room
+ list.push_back(nullptr);
+ for (Index i = list.size() - 1; i > index; i--) {
+ list[i] = list[i - 1];
+ }
+ list[index] = add;
+ }
+ }
};
struct ExpressionAnalyzer {
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp
index a7eb09669..519f0c5a8 100644
--- a/src/passes/RemoveUnusedBrs.cpp
+++ b/src/passes/RemoveUnusedBrs.cpp
@@ -274,7 +274,8 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<R
assert(ifStack.empty());
// flows may contain returns, which are flowing out and so can be optimized
for (size_t i = 0; i < flows.size(); i++) {
- auto* flow = (*flows[i])->cast<Return>(); // cannot be a break
+ auto* flow = (*flows[i])->dynCast<Return>();
+ if (!flow) continue;
if (!flow->value) {
// return => nop
ExpressionManipulator::nop(flow);
@@ -293,9 +294,38 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<R
loops.clear();
if (anotherCycle) worked = true;
} while (anotherCycle);
- // finally, we may have simplified ifs enough to turn them into selects
- struct Selectifier : public WalkerPass<PostWalker<Selectifier, Visitor<Selectifier>>> {
+ // perform some final optimizations
+ struct FinalOptimizer : public WalkerPass<PostWalker<FinalOptimizer, Visitor<FinalOptimizer>>> {
+ 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.
+ // * note that if not in a block already, then we need to create a block for this, so not useful otherwise
+ // * note that this only happens at the end of a block, as code after the if is dead
+ // * note that we do this at the end, because un-conditionalizing can interfere with optimizeLoop()ing.
+ auto& list = curr->list;
+ for (Index i = 0; i < list.size(); i++) {
+ auto* iff = list[i]->dynCast<If>();
+ if (!iff || !iff->ifFalse || isConcreteWasmType(iff->type)) continue; // if it lacked an if-false, it would already be a br_if, as that's the easy case
+ auto* ifTrueBreak = iff->ifTrue->dynCast<Break>();
+ if (ifTrueBreak && !ifTrueBreak->condition) {
+ // we are an if-else where the ifTrue is a break without a condition, so we can do this
+ list[i] = ifTrueBreak;
+ ifTrueBreak->condition = iff->condition;
+ ExpressionManipulator::spliceIntoBlock(curr, i + 1, iff->ifFalse);
+ continue;
+ }
+ // otherwise, perhaps we can flip the if
+ auto* ifFalseBreak = iff->ifFalse->dynCast<Break>();
+ if (ifFalseBreak && !ifFalseBreak->condition) {
+ list[i] = ifFalseBreak;
+ ifFalseBreak->condition = Builder(*getModule()).makeUnary(EqZInt32, iff->condition);
+ ExpressionManipulator::spliceIntoBlock(curr, i + 1, iff->ifTrue);
+ continue;
+ }
+ }
+ }
void visitIf(If* curr) {
+ // we may have simplified ifs enough to turn them into selects
if (curr->ifFalse && isConcreteWasmType(curr->ifTrue->type) && isConcreteWasmType(curr->ifFalse->type)) {
// if with else, consider turning it into a select if there is no control flow
// TODO: estimate cost
@@ -317,9 +347,9 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<R
}
}
};
- Selectifier selectifier;
- selectifier.setModule(getModule());
- selectifier.walkFunction(func);
+ FinalOptimizer finalOptimizer;
+ finalOptimizer.setModule(getModule());
+ finalOptimizer.walkFunction(func);
if (worked) {
// Our work may alter block and if types, they may now return
struct TypeUpdater : public WalkerPass<PostWalker<TypeUpdater, Visitor<TypeUpdater>>> {
diff --git a/test/emcc_O2_hello_world.fromasm b/test/emcc_O2_hello_world.fromasm
index b90dd4b5a..4966ce28a 100644
--- a/test/emcc_O2_hello_world.fromasm
+++ b/test/emcc_O2_hello_world.fromasm
@@ -3222,20 +3222,17 @@
(br $while-out$37)
)
)
- (if
+ (br_if $while-in$38
(tee_local $14
(i32.load offset=8
(get_local $14)
)
)
- (br $while-in$38)
- (block
- (set_local $6
- (i32.const 173)
- )
- (br $label$break$L259)
- )
)
+ (set_local $6
+ (i32.const 173)
+ )
+ (br $label$break$L259)
)
)
(if
@@ -3861,16 +3858,15 @@
(br $while-out$48)
)
)
- (if
+ (br_if $while-in$49
(tee_local $1
(i32.load offset=8
(get_local $1)
)
)
- (br $while-in$49)
- (set_local $28
- (i32.const 624)
- )
+ )
+ (set_local $28
+ (i32.const 624)
)
)
)
@@ -8569,7 +8565,7 @@
(br $label$break$L1)
)
)
- (if
+ (br_if $while-in$2
(i32.and
(tee_local $4
(tee_local $0
@@ -8581,14 +8577,13 @@
)
(i32.const 3)
)
- (br $while-in$2)
- (block
- (set_local $1
- (get_local $0)
- )
- (set_local $2
- (i32.const 4)
- )
+ )
+ (block
+ (set_local $1
+ (get_local $0)
+ )
+ (set_local $2
+ (i32.const 4)
)
)
)
diff --git a/test/emcc_O2_hello_world.fromasm.imprecise b/test/emcc_O2_hello_world.fromasm.imprecise
index 78f5a5548..e0f340478 100644
--- a/test/emcc_O2_hello_world.fromasm.imprecise
+++ b/test/emcc_O2_hello_world.fromasm.imprecise
@@ -3220,20 +3220,17 @@
(br $while-out$37)
)
)
- (if
+ (br_if $while-in$38
(tee_local $14
(i32.load offset=8
(get_local $14)
)
)
- (br $while-in$38)
- (block
- (set_local $6
- (i32.const 173)
- )
- (br $label$break$L259)
- )
)
+ (set_local $6
+ (i32.const 173)
+ )
+ (br $label$break$L259)
)
)
(if
@@ -3859,16 +3856,15 @@
(br $while-out$48)
)
)
- (if
+ (br_if $while-in$49
(tee_local $1
(i32.load offset=8
(get_local $1)
)
)
- (br $while-in$49)
- (set_local $28
- (i32.const 624)
- )
+ )
+ (set_local $28
+ (i32.const 624)
)
)
)
@@ -8567,7 +8563,7 @@
(br $label$break$L1)
)
)
- (if
+ (br_if $while-in$2
(i32.and
(tee_local $4
(tee_local $0
@@ -8579,14 +8575,13 @@
)
(i32.const 3)
)
- (br $while-in$2)
- (block
- (set_local $1
- (get_local $0)
- )
- (set_local $2
- (i32.const 4)
- )
+ )
+ (block
+ (set_local $1
+ (get_local $0)
+ )
+ (set_local $2
+ (i32.const 4)
)
)
)
diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm
index 06b48ffd6..575a33d1c 100644
--- a/test/emcc_hello_world.fromasm
+++ b/test/emcc_hello_world.fromasm
@@ -402,28 +402,29 @@
(br $while-out$0)
)
)
- (if
- (i32.eq
- (tee_local $2
- (i32.add
- (get_local $2)
- (i32.const 1)
+ (br_if $while-in$1
+ (i32.eqz
+ (i32.eq
+ (tee_local $2
+ (i32.add
+ (get_local $2)
+ (i32.const 1)
+ )
)
+ (i32.const 87)
)
+ )
+ )
+ (block
+ (set_local $3
(i32.const 87)
)
- (block
- (set_local $3
- (i32.const 87)
- )
- (set_local $1
- (i32.const 775)
- )
- (set_local $0
- (i32.const 5)
- )
+ (set_local $1
+ (i32.const 775)
+ )
+ (set_local $0
+ (i32.const 5)
)
- (br $while-in$1)
)
)
)
@@ -2134,7 +2135,7 @@
(br $label$break$L1)
)
)
- (if
+ (br_if $while-in$2
(i32.and
(tee_local $3
(i32.ne
@@ -2160,20 +2161,19 @@
(i32.const 0)
)
)
- (br $while-in$2)
- (block
- (set_local $13
- (get_local $2)
- )
- (set_local $10
- (get_local $0)
- )
- (set_local $14
- (get_local $3)
- )
- (set_local $3
- (i32.const 5)
- )
+ )
+ (block
+ (set_local $13
+ (get_local $2)
+ )
+ (set_local $10
+ (get_local $0)
+ )
+ (set_local $14
+ (get_local $3)
+ )
+ (set_local $3
+ (i32.const 5)
)
)
)
@@ -2298,7 +2298,7 @@
(i32.const 4)
)
)
- (if
+ (br_if $while-in$6
(i32.gt_u
(tee_local $5
(i32.add
@@ -2308,19 +2308,18 @@
)
(i32.const 3)
)
- (br $while-in$6)
- (block
- (set_local $11
- (get_local $5)
- )
- (set_local $12
- (get_local $4)
- )
- (set_local $3
- (i32.const 11)
- )
- (br $label$break$L11)
+ )
+ (block
+ (set_local $11
+ (get_local $5)
+ )
+ (set_local $12
+ (get_local $4)
+ )
+ (set_local $3
+ (i32.const 11)
)
+ (br $label$break$L11)
)
)
)
@@ -3545,7 +3544,7 @@
(get_local $5)
)
)
- (if
+ (br_if $while-in$18
(i32.lt_u
(tee_local $5
(i32.add
@@ -3562,10 +3561,9 @@
)
(i32.const 10)
)
- (br $while-in$18)
- (br $label$break$L46
- (get_local $10)
- )
+ )
+ (br $label$break$L46
+ (get_local $10)
)
)
)
@@ -5294,15 +5292,14 @@
)
)
)
- (if
+ (br_if $while-in$69
(i32.gt_s
(get_local $8)
(i32.const 0)
)
- (br $while-in$69)
- (set_local $6
- (get_local $5)
- )
+ )
+ (set_local $6
+ (get_local $5)
)
)
)
@@ -5552,7 +5549,7 @@
(i32.const 9)
)
)
- (if
+ (br_if $do-once$82
(i32.lt_u
(tee_local $8
(i32.load
@@ -5561,10 +5558,9 @@
)
(i32.const 10)
)
- (br $do-once$82)
- (set_local $7
- (i32.const 10)
- )
+ )
+ (set_local $7
+ (i32.const 10)
)
(loop $while-in$85
(set_local $6
@@ -5954,25 +5950,26 @@
(i32.const 1)
)
)
- (if
- (i32.lt_u
- (get_local $13)
- (tee_local $8
- (i32.mul
- (get_local $8)
- (i32.const 10)
+ (br_if $while-in$95
+ (i32.eqz
+ (i32.lt_u
+ (get_local $13)
+ (tee_local $8
+ (i32.mul
+ (get_local $8)
+ (i32.const 10)
+ )
)
)
)
- (block
- (set_local $8
- (get_local $5)
- )
- (set_local $5
- (get_local $6)
- )
+ )
+ (block
+ (set_local $8
+ (get_local $5)
+ )
+ (set_local $5
+ (get_local $6)
)
- (br $while-in$95)
)
)
)
@@ -7543,19 +7540,18 @@
)
)
)
- (if
+ (br_if $while-in$134
(i32.lt_u
(get_local $7)
(get_local $9)
)
- (br $while-in$134)
- (block
- (set_local $35
- (get_local $9)
- )
- (set_local $12
- (i32.const 98)
- )
+ )
+ (block
+ (set_local $35
+ (get_local $9)
+ )
+ (set_local $12
+ (i32.const 98)
)
)
)
@@ -7863,7 +7859,7 @@
(get_local $1)
(get_local $2)
)
- (if
+ (br_if $while-in$137
(i32.lt_s
(tee_local $0
(i32.add
@@ -7873,13 +7869,12 @@
)
(i32.const 10)
)
- (br $while-in$137)
- (block
- (set_local $22
- (i32.const 1)
- )
- (br $label$break$L343)
+ )
+ (block
+ (set_local $22
+ (i32.const 1)
)
+ (br $label$break$L343)
)
)
)
@@ -10487,20 +10482,19 @@
(br $while-in$20)
)
)
- (if
+ (br_if $while-in$20
(tee_local $5
(i32.load offset=20
(get_local $5)
)
)
- (br $while-in$20)
- (block
- (set_local $13
- (get_local $7)
- )
- (set_local $12
- (get_local $1)
- )
+ )
+ (block
+ (set_local $13
+ (get_local $7)
+ )
+ (set_local $12
+ (get_local $1)
)
)
)
@@ -11746,19 +11740,18 @@
)
)
)
- (if
+ (br_if $while-in$38
(tee_local $1
(i32.load offset=8
(get_local $1)
)
)
- (br $while-in$38)
- (block
- (set_local $9
- (i32.const 173)
- )
- (br $label$break$L259)
+ )
+ (block
+ (set_local $9
+ (i32.const 173)
)
+ (br $label$break$L259)
)
)
)
@@ -12372,16 +12365,15 @@
(br $while-out$50)
)
)
- (if
+ (br_if $while-in$51
(tee_local $1
(i32.load offset=8
(get_local $1)
)
)
- (br $while-in$51)
- (set_local $20
- (i32.const 624)
- )
+ )
+ (set_local $20
+ (i32.const 624)
)
)
)
diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise
index e83f2b757..249892261 100644
--- a/test/emcc_hello_world.fromasm.imprecise
+++ b/test/emcc_hello_world.fromasm.imprecise
@@ -395,28 +395,29 @@
(br $while-out$0)
)
)
- (if
- (i32.eq
- (tee_local $2
- (i32.add
- (get_local $2)
- (i32.const 1)
+ (br_if $while-in$1
+ (i32.eqz
+ (i32.eq
+ (tee_local $2
+ (i32.add
+ (get_local $2)
+ (i32.const 1)
+ )
)
+ (i32.const 87)
)
+ )
+ )
+ (block
+ (set_local $3
(i32.const 87)
)
- (block
- (set_local $3
- (i32.const 87)
- )
- (set_local $1
- (i32.const 775)
- )
- (set_local $0
- (i32.const 5)
- )
+ (set_local $1
+ (i32.const 775)
+ )
+ (set_local $0
+ (i32.const 5)
)
- (br $while-in$1)
)
)
)
@@ -2127,7 +2128,7 @@
(br $label$break$L1)
)
)
- (if
+ (br_if $while-in$2
(i32.and
(tee_local $3
(i32.ne
@@ -2153,20 +2154,19 @@
(i32.const 0)
)
)
- (br $while-in$2)
- (block
- (set_local $13
- (get_local $2)
- )
- (set_local $10
- (get_local $0)
- )
- (set_local $14
- (get_local $3)
- )
- (set_local $3
- (i32.const 5)
- )
+ )
+ (block
+ (set_local $13
+ (get_local $2)
+ )
+ (set_local $10
+ (get_local $0)
+ )
+ (set_local $14
+ (get_local $3)
+ )
+ (set_local $3
+ (i32.const 5)
)
)
)
@@ -2291,7 +2291,7 @@
(i32.const 4)
)
)
- (if
+ (br_if $while-in$6
(i32.gt_u
(tee_local $5
(i32.add
@@ -2301,19 +2301,18 @@
)
(i32.const 3)
)
- (br $while-in$6)
- (block
- (set_local $11
- (get_local $5)
- )
- (set_local $12
- (get_local $4)
- )
- (set_local $3
- (i32.const 11)
- )
- (br $label$break$L11)
+ )
+ (block
+ (set_local $11
+ (get_local $5)
+ )
+ (set_local $12
+ (get_local $4)
+ )
+ (set_local $3
+ (i32.const 11)
)
+ (br $label$break$L11)
)
)
)
@@ -3538,7 +3537,7 @@
(get_local $5)
)
)
- (if
+ (br_if $while-in$18
(i32.lt_u
(tee_local $5
(i32.add
@@ -3555,10 +3554,9 @@
)
(i32.const 10)
)
- (br $while-in$18)
- (br $label$break$L46
- (get_local $10)
- )
+ )
+ (br $label$break$L46
+ (get_local $10)
)
)
)
@@ -5287,15 +5285,14 @@
)
)
)
- (if
+ (br_if $while-in$69
(i32.gt_s
(get_local $8)
(i32.const 0)
)
- (br $while-in$69)
- (set_local $6
- (get_local $5)
- )
+ )
+ (set_local $6
+ (get_local $5)
)
)
)
@@ -5545,7 +5542,7 @@
(i32.const 9)
)
)
- (if
+ (br_if $do-once$82
(i32.lt_u
(tee_local $8
(i32.load
@@ -5554,10 +5551,9 @@
)
(i32.const 10)
)
- (br $do-once$82)
- (set_local $7
- (i32.const 10)
- )
+ )
+ (set_local $7
+ (i32.const 10)
)
(loop $while-in$85
(set_local $6
@@ -5947,25 +5943,26 @@
(i32.const 1)
)
)
- (if
- (i32.lt_u
- (get_local $13)
- (tee_local $8
- (i32.mul
- (get_local $8)
- (i32.const 10)
+ (br_if $while-in$95
+ (i32.eqz
+ (i32.lt_u
+ (get_local $13)
+ (tee_local $8
+ (i32.mul
+ (get_local $8)
+ (i32.const 10)
+ )
)
)
)
- (block
- (set_local $8
- (get_local $5)
- )
- (set_local $5
- (get_local $6)
- )
+ )
+ (block
+ (set_local $8
+ (get_local $5)
+ )
+ (set_local $5
+ (get_local $6)
)
- (br $while-in$95)
)
)
)
@@ -7536,19 +7533,18 @@
)
)
)
- (if
+ (br_if $while-in$134
(i32.lt_u
(get_local $7)
(get_local $9)
)
- (br $while-in$134)
- (block
- (set_local $35
- (get_local $9)
- )
- (set_local $12
- (i32.const 98)
- )
+ )
+ (block
+ (set_local $35
+ (get_local $9)
+ )
+ (set_local $12
+ (i32.const 98)
)
)
)
@@ -7856,7 +7852,7 @@
(get_local $1)
(get_local $2)
)
- (if
+ (br_if $while-in$137
(i32.lt_s
(tee_local $0
(i32.add
@@ -7866,13 +7862,12 @@
)
(i32.const 10)
)
- (br $while-in$137)
- (block
- (set_local $22
- (i32.const 1)
- )
- (br $label$break$L343)
+ )
+ (block
+ (set_local $22
+ (i32.const 1)
)
+ (br $label$break$L343)
)
)
)
@@ -10480,20 +10475,19 @@
(br $while-in$20)
)
)
- (if
+ (br_if $while-in$20
(tee_local $5
(i32.load offset=20
(get_local $5)
)
)
- (br $while-in$20)
- (block
- (set_local $13
- (get_local $7)
- )
- (set_local $12
- (get_local $1)
- )
+ )
+ (block
+ (set_local $13
+ (get_local $7)
+ )
+ (set_local $12
+ (get_local $1)
)
)
)
@@ -11739,19 +11733,18 @@
)
)
)
- (if
+ (br_if $while-in$38
(tee_local $1
(i32.load offset=8
(get_local $1)
)
)
- (br $while-in$38)
- (block
- (set_local $9
- (i32.const 173)
- )
- (br $label$break$L259)
+ )
+ (block
+ (set_local $9
+ (i32.const 173)
)
+ (br $label$break$L259)
)
)
)
@@ -12365,16 +12358,15 @@
(br $while-out$50)
)
)
- (if
+ (br_if $while-in$51
(tee_local $1
(i32.load offset=8
(get_local $1)
)
)
- (br $while-in$51)
- (set_local $20
- (i32.const 624)
- )
+ )
+ (set_local $20
+ (i32.const 624)
)
)
)
diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt
index 574be4965..9f1021b30 100644
--- a/test/example/c-api-kitchen-sink.txt
+++ b/test/example/c-api-kitchen-sink.txt
@@ -1104,11 +1104,10 @@ optimized:
(call_import $check
(i32.const 1)
)
- (if
+ (br_if $shape$0$continue
(i32.const 10)
- (br $shape$0$continue)
- (br $block$3$break)
)
+ (br $block$3$break)
)
)
(call_import $check
@@ -1131,11 +1130,10 @@ optimized:
(call_import $check
(i32.const 2)
)
- (if
+ (br_if $block$4$break
(i32.const -6)
- (br $block$4$break)
- (br $shape$1$continue)
)
+ (br $shape$1$continue)
)
)
(call_import $check
@@ -3161,11 +3159,10 @@ optimized:
(call_import $check
(i32.const 1)
)
- (if
+ (br_if $shape$0$continue
(i32.const 10)
- (br $shape$0$continue)
- (br $block$3$break)
)
+ (br $block$3$break)
)
)
(call_import $check
@@ -3188,11 +3185,10 @@ optimized:
(call_import $check
(i32.const 2)
)
- (if
+ (br_if $block$4$break
(i32.const -6)
- (br $block$4$break)
- (br $shape$1$continue)
)
+ (br $shape$1$continue)
)
)
(call_import $check
diff --git a/test/example/c-api-kitchen-sink.txt.txt b/test/example/c-api-kitchen-sink.txt.txt
index 991c8738c..022bcc2e3 100644
--- a/test/example/c-api-kitchen-sink.txt.txt
+++ b/test/example/c-api-kitchen-sink.txt.txt
@@ -1097,11 +1097,10 @@
(call_import $check
(i32.const 1)
)
- (if
+ (br_if $shape$0$continue
(i32.const 10)
- (br $shape$0$continue)
- (br $block$3$break)
)
+ (br $block$3$break)
)
)
(call_import $check
@@ -1124,11 +1123,10 @@
(call_import $check
(i32.const 2)
)
- (if
+ (br_if $block$4$break
(i32.const -6)
- (br $block$4$break)
- (br $shape$1$continue)
)
+ (br $shape$1$continue)
)
)
(call_import $check
diff --git a/test/example/relooper-fuzz.txt b/test/example/relooper-fuzz.txt
index b46932009..5db33f21e 100644
--- a/test/example/relooper-fuzz.txt
+++ b/test/example/relooper-fuzz.txt
@@ -478,47 +478,47 @@
(call_import $print
(i32.const 5)
)
- (if
- (i32.rem_u
- (call $check)
- (i32.const 2)
- )
- (block
- (set_local $0
- (i32.const 6)
+ (br_if $shape$3$continue
+ (i32.eqz
+ (i32.rem_u
+ (call $check)
+ (i32.const 2)
)
- (br $shape$3$continue)
)
- (br $shape$3$continue)
)
+ (set_local $0
+ (i32.const 6)
+ )
+ (br $shape$3$continue)
)
)
(call_import $print
(i32.const 4)
)
- (if
- (i32.rem_u
- (tee_local $1
- (call $check)
+ (br_if $shape$3$continue
+ (i32.eqz
+ (i32.rem_u
+ (tee_local $1
+ (call $check)
+ )
+ (i32.const 3)
)
- (i32.const 3)
)
- (if
- (i32.eq
- (i32.rem_u
- (get_local $1)
- (i32.const 3)
- )
- (i32.const 1)
+ )
+ (if
+ (i32.eq
+ (i32.rem_u
+ (get_local $1)
+ (i32.const 3)
)
- (block
- (set_local $0
- (i32.const 6)
- )
- (br $shape$3$continue)
+ (i32.const 1)
+ )
+ (block
+ (set_local $0
+ (i32.const 6)
)
+ (br $shape$3$continue)
)
- (br $shape$3$continue)
)
(call_import $print
(i32.const 2)
diff --git a/test/memorygrowth.fromasm b/test/memorygrowth.fromasm
index 972379b5c..70ef836b0 100644
--- a/test/memorygrowth.fromasm
+++ b/test/memorygrowth.fromasm
@@ -3253,20 +3253,17 @@
)
)
)
- (if
+ (br_if $while-in$36
(tee_local $7
(i32.load offset=8
(get_local $7)
)
)
- (br $while-in$36)
- (block
- (set_local $9
- (i32.const 171)
- )
- (br $label$break$c)
- )
)
+ (set_local $9
+ (i32.const 171)
+ )
+ (br $label$break$c)
)
)
(if
@@ -3892,16 +3889,15 @@
(br $while-out$48)
)
)
- (if
+ (br_if $while-in$49
(tee_local $1
(i32.load offset=8
(get_local $1)
)
)
- (br $while-in$49)
- (set_local $30
- (i32.const 1656)
- )
+ )
+ (set_local $30
+ (i32.const 1656)
)
)
)
@@ -8478,7 +8474,7 @@
(br $label$break$a)
)
)
- (if
+ (br_if $while-in$2
(i32.and
(tee_local $4
(tee_local $0
@@ -8490,14 +8486,13 @@
)
(i32.const 3)
)
- (br $while-in$2)
- (block
- (set_local $1
- (get_local $0)
- )
- (set_local $2
- (i32.const 4)
- )
+ )
+ (block
+ (set_local $1
+ (get_local $0)
+ )
+ (set_local $2
+ (i32.const 4)
)
)
)
diff --git a/test/memorygrowth.fromasm.imprecise b/test/memorygrowth.fromasm.imprecise
index aa03ca8e4..4e4891a8d 100644
--- a/test/memorygrowth.fromasm.imprecise
+++ b/test/memorygrowth.fromasm.imprecise
@@ -3251,20 +3251,17 @@
)
)
)
- (if
+ (br_if $while-in$36
(tee_local $7
(i32.load offset=8
(get_local $7)
)
)
- (br $while-in$36)
- (block
- (set_local $9
- (i32.const 171)
- )
- (br $label$break$c)
- )
)
+ (set_local $9
+ (i32.const 171)
+ )
+ (br $label$break$c)
)
)
(if
@@ -3890,16 +3887,15 @@
(br $while-out$48)
)
)
- (if
+ (br_if $while-in$49
(tee_local $1
(i32.load offset=8
(get_local $1)
)
)
- (br $while-in$49)
- (set_local $30
- (i32.const 1656)
- )
+ )
+ (set_local $30
+ (i32.const 1656)
)
)
)
@@ -8476,7 +8472,7 @@
(br $label$break$a)
)
)
- (if
+ (br_if $while-in$2
(i32.and
(tee_local $4
(tee_local $0
@@ -8488,14 +8484,13 @@
)
(i32.const 3)
)
- (br $while-in$2)
- (block
- (set_local $1
- (get_local $0)
- )
- (set_local $2
- (i32.const 4)
- )
+ )
+ (block
+ (set_local $1
+ (get_local $0)
+ )
+ (set_local $2
+ (i32.const 4)
)
)
)
diff --git a/test/passes/remove-unused-brs.txt b/test/passes/remove-unused-brs.txt
index ff150f1ac..50f3b3a62 100644
--- a/test/passes/remove-unused-brs.txt
+++ b/test/passes/remove-unused-brs.txt
@@ -481,12 +481,13 @@
)
(loop $in
(block $out
- (if
- (i32.const 0)
- (block $block8
- (call $loops)
+ (br_if $in
+ (i32.eqz
+ (i32.const 0)
)
- (br $in)
+ )
+ (block $block8
+ (call $loops)
)
)
)
@@ -591,22 +592,20 @@
)
(loop $in
(block $out
- (if
+ (br_if $out
(i32.const 0)
- (br $out)
- (call $loops)
)
+ (call $loops)
(return)
(br $in)
)
)
(loop $in
(block $out
- (if
+ (br_if $out
(i32.const 0)
- (br $out)
- (call $loops)
)
+ (call $loops)
(br $out)
(br $in)
)
@@ -691,4 +690,40 @@
)
)
)
+ (func $br_if_in_block (type $2) (result i32)
+ (block $outval
+ (block $in
+ (br_if $in
+ (i32.const 1)
+ )
+ (br $in)
+ (drop
+ (i32.const 2)
+ )
+ (br_if $in
+ (i32.eqz
+ (i32.const 3)
+ )
+ )
+ (unreachable)
+ (drop
+ (i32.const 4)
+ )
+ (br_if $in
+ (i32.const 5)
+ )
+ (unreachable)
+ (drop
+ (i32.const 6)
+ )
+ )
+ (if
+ (i32.const 6)
+ (br $outval
+ (i32.const 7)
+ )
+ (i32.const 8)
+ )
+ )
+ )
)
diff --git a/test/passes/remove-unused-brs.wast b/test/passes/remove-unused-brs.wast
index 87e144096..1a0b16477 100644
--- a/test/passes/remove-unused-brs.wast
+++ b/test/passes/remove-unused-brs.wast
@@ -653,4 +653,17 @@
)
)
)
+ (func $br_if_in_block (result i32)
+ (block $outval
+ (block $in
+ (if (i32.const 1) (br $in) (br $in))
+ (drop (i32.const 2))
+ (if (i32.const 3) (unreachable) (br $in))
+ (drop (i32.const 4))
+ (if (i32.const 5) (br $in) (unreachable))
+ (drop (i32.const 6))
+ )
+ (if (i32.const 6) (br $outval (i32.const 7)) (i32.const 8))
+ )
+ )
)