diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index 726516fea..4ed4b0cb6 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -737,9 +737,12 @@ struct OptDffWorker bool run_constbits() { ModWalker modwalker(module->design, module); QuickConeSat qcsat(modwalker); - std::vector cells_to_remove; - // Run as a separate sub-pass, so that we don't mutate (non-FF) cells under ModWalker. + // Defer mutating cells by removing them/emiting new flip flops so that + // cell references in modwalker are not invalidated + std::vector cells_to_remove; + std::vector ffs_to_emit; + bool did_something = false; for (auto cell : module->selected_cells()) { if (!RTLIL::builtin_ff_cell_types().count(cell->type)) @@ -837,12 +840,14 @@ struct OptDffWorker } ff = ff.slice(keep_bits); ff.cell = cell; - ff.emit(); + ffs_to_emit.emplace_back(ff); did_something = true; } } for (auto* cell : cells_to_remove) module->remove(cell); + for (auto& ff : ffs_to_emit) + ff.emit(); return did_something; } };