Skip to content

Commit d7aaeab

Browse files
authored
Fix RemoveUnusedBrs bug on removed br_if value where condition interferes (#7586)
Fixes a regression from #7506 . That PR checked for effects, but we forgot to also check for interactions between effects.
1 parent 1f27e2f commit d7aaeab

File tree

2 files changed

+57
-8
lines changed

2 files changed

+57
-8
lines changed

src/passes/RemoveUnusedBrs.cpp

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,14 +1290,32 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
12901290
auto* last = curr->list[size - 1];
12911291
if (auto* drop = secondLast->dynCast<Drop>()) {
12921292
if (auto* br = drop->value->dynCast<Break>();
1293-
br && br->value && br->condition) {
1294-
if (br->name == curr->name) {
1295-
if (!EffectAnalyzer(passOptions, *getModule(), br->value)
1296-
.hasUnremovableSideEffects()) {
1297-
if (ExpressionAnalyzer::equal(br->value, last)) {
1298-
// All conditions met, perform the update.
1299-
drop->value = br->condition;
1300-
}
1293+
br && br->value && br->condition && br->name == curr->name &&
1294+
ExpressionAnalyzer::equal(br->value, last)) {
1295+
// The value must have no effects, as we are removing one copy
1296+
// of it. Also, the condition must not interfere with that
1297+
// value, or it might change, e.g.
1298+
//
1299+
// (drop
1300+
// (br_if $block
1301+
// (read a value) ;; this original value is returned,
1302+
// (write that value) ;; if we branch
1303+
// )
1304+
// )
1305+
// (read a value)
1306+
// =>
1307+
// (drop
1308+
// (write that value)
1309+
// )
1310+
// (read a value) ;; now the written value is used
1311+
auto valueEffects =
1312+
EffectAnalyzer(passOptions, *getModule(), br->value);
1313+
if (!valueEffects.hasUnremovableSideEffects()) {
1314+
auto conditionEffects =
1315+
EffectAnalyzer(passOptions, *getModule(), br->condition);
1316+
if (!conditionEffects.invalidates(valueEffects)) {
1317+
// All conditions met, perform the update.
1318+
drop->value = br->condition;
13011319
}
13021320
}
13031321
}

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,37 @@
466466
)
467467
)
468468

469+
;; CHECK: (func $restructure-br_if-condition-invalidates-6 (type $2) (result i32)
470+
;; CHECK-NEXT: (local $temp i32)
471+
;; CHECK-NEXT: (block $block (result i32)
472+
;; CHECK-NEXT: (drop
473+
;; CHECK-NEXT: (br_if $block
474+
;; CHECK-NEXT: (local.get $temp)
475+
;; CHECK-NEXT: (local.tee $temp
476+
;; CHECK-NEXT: (i32.const 1)
477+
;; CHECK-NEXT: )
478+
;; CHECK-NEXT: )
479+
;; CHECK-NEXT: )
480+
;; CHECK-NEXT: (local.get $temp)
481+
;; CHECK-NEXT: )
482+
;; CHECK-NEXT: )
483+
(func $restructure-br_if-condition-invalidates-6 (result i32)
484+
(local $temp i32)
485+
;; The br value is syntactically identical to the value at the end of the
486+
;; block, however, the local.tee changes that value so we cannot optimize.
487+
(block $block (result i32)
488+
(drop
489+
(br_if $block
490+
(local.get $temp)
491+
(local.tee $temp
492+
(i32.const 1)
493+
)
494+
)
495+
)
496+
(local.get $temp)
497+
)
498+
)
499+
469500
;; CHECK: (func $restructure-select-no-multivalue (type $1)
470501
;; CHECK-NEXT: (tuple.drop 2
471502
;; CHECK-NEXT: (block $block (type $3) (result i32 i32)

0 commit comments

Comments
 (0)