@@ -1290,14 +1290,32 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
1290
1290
auto * last = curr->list [size - 1 ];
1291
1291
if (auto * drop = secondLast->dynCast <Drop>()) {
1292
1292
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 ;
1301
1319
}
1302
1320
}
1303
1321
}
0 commit comments