From 9f5f8dd2ffe0b89ea071aea3d2b3efad42dada4f Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 17 Dec 2024 14:30:46 -0800 Subject: 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. --- src/passes/RemoveUnusedBrs.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp index 32f7bd48a..47a1f1c65 100644 --- a/src/passes/RemoveUnusedBrs.cpp +++ b/src/passes/RemoveUnusedBrs.cpp @@ -621,9 +621,13 @@ struct RemoveUnusedBrs : public WalkerPass> { block->finalize(); return true; } - } else { - // this is already an if-else. if one side is a dead end, we can - // append to the other, if there is no returned value to concern us + } else if (iff->condition->type != Type::unreachable) { + // This is already an if-else. If one side is a dead end, we can + // append to the other, if there is no returned value to concern us. + // Note that we skip ifs with unreachable conditions, as they are dead + // code that DCE can remove, and modifying them can lead to errors + // (one of the arms may still be concrete, in which case appending to + // it would be invalid). // can't be, since in the middle of a block assert(!iff->type.isConcrete()); -- cgit v1.2.3