From 0520bfea892291a131134411d587034fcd36bf1c Mon Sep 17 00:00:00 2001
From: Clifford Wolf <clifford@clifford.at>
Date: Fri, 25 Jul 2014 12:49:51 +0200
Subject: [PATCH] Fixed memory corruption in "opt_reduce" pass

---
 passes/opt/opt_reduce.cc | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc
index 913855f48..0cc16ee67 100644
--- a/passes/opt/opt_reduce.cc
+++ b/passes/opt/opt_reduce.cc
@@ -312,12 +312,14 @@ struct OptReduceWorker
 
 			// merge identical inputs on $mux and $pmux cells
 
-			for (auto &cell_it : module->cells)
-			{
-				RTLIL::Cell *cell = cell_it.second;
-				if ((cell->type != "$mux" && cell->type != "$pmux" && cell->type != "$safe_pmux") || !design->selected(module, cell))
-					continue;
+			std::vector<RTLIL::Cell*> cells;
 
+			for (auto &it : module->cells)
+				if ((it.second->type == "$mux" || it.second->type == "$pmux" || it.second->type == "$safe_pmux") && design->selected(module, it.second))
+					cells.push_back(it.second);
+
+			for (auto cell : cells)
+			{
 				// this optimization is to aggressive for most coarse-grain applications.
 				// but we always want it for multiplexers driving write enable ports.
 				if (do_fine || mem_wren_sigs.check_any(assign_map(cell->connections.at("\\Y"))))