From 43d1e70cedfa02c1c2f5f33aaaf6920d269a4083 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 8 Nov 2018 09:53:48 -0800 Subject: Fix a merge-blocks fuzz bug (#1730) If a block has code after an unreachable element, it makes merging to an outer block tricky - the child block may be unreachable, but the parent have a return type, (block (result i32) .. (block (unreachable) (nop) ) ) It's ok to end an unreachable block with a nop, but not a typed one. To avoid this, if a child block has dce-able code, just ignore it. --- src/passes/MergeBlocks.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/passes/MergeBlocks.cpp b/src/passes/MergeBlocks.cpp index 352a0a08d..50610afed 100644 --- a/src/passes/MergeBlocks.cpp +++ b/src/passes/MergeBlocks.cpp @@ -175,6 +175,18 @@ static bool hasUnreachableChild(Block* block) { return false; } +// Checks for code after an unreachable element. +static bool hasDeadCode(Block* block) { + auto& list = block->list; + auto size = list.size(); + for (size_t i = 1; i < size; i++) { + if (list[i - 1]->type == unreachable) { + return true; + } + } + return false; +} + // core block optimizer routine static void optimizeBlock(Block* curr, Module* module, PassOptions& passOptions) { bool more = true; @@ -244,6 +256,9 @@ static void optimizeBlock(Block* curr, Module* module, PassOptions& passOptions) auto& childList = childBlock->list; auto childSize = childList.size(); if (childSize == 0) continue; + // If the child has items after an unreachable, ignore it - dce should have + // been run, and we prefer to not handle the complexity here. + if (hasDeadCode(childBlock)) continue; // If this is a loop, we may be removing only the tail. Index start = 0; Index end = childSize; @@ -304,7 +319,9 @@ static void optimizeBlock(Block* curr, Module* module, PassOptions& passOptions) break; } } - if (changed) curr->finalize(curr->type); + if (changed) { + curr->finalize(curr->type); + } } void BreakValueDropper::visitBlock(Block* curr) { -- cgit v1.2.3