diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc
index b876862c8..ef81cac01 100644
--- a/kernel/rtlil.cc
+++ b/kernel/rtlil.cc
@@ -1536,13 +1536,13 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const
 		new_mod->addWire(it.first, it.second);
 
 	for (auto &it : memories)
-		new_mod->memories[it.first] = new RTLIL::Memory(*it.second);
+		new_mod->addMemory(it.first, it.second);
 
 	for (auto &it : cells_)
 		new_mod->addCell(it.first, it.second);
 
 	for (auto &it : processes)
-		new_mod->processes[it.first] = it.second->clone();
+		new_mod->addProcess(it.first, it.second);
 
 	struct RewriteSigSpecWorker
 	{
@@ -1913,6 +1913,14 @@ RTLIL::Memory *RTLIL::Module::addMemory(RTLIL::IdString name, const RTLIL::Memor
 	return mem;
 }
 
+RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Process *other)
+{
+	RTLIL::Process *proc = other->clone();
+	proc->name = name;
+	processes[name] = proc;
+	return proc;
+}
+
 #define DEF_METHOD(_func, _y_size, _type) \
 	RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed, const std::string &src) { \
 		RTLIL::Cell *cell = addCell(name, _type);           \
diff --git a/kernel/rtlil.h b/kernel/rtlil.h
index f751bdce4..f3dc3af68 100644
--- a/kernel/rtlil.h
+++ b/kernel/rtlil.h
@@ -1175,6 +1175,8 @@ public:
 
 	RTLIL::Memory *addMemory(RTLIL::IdString name, const RTLIL::Memory *other);
 
+	RTLIL::Process *addProcess(RTLIL::IdString name, const RTLIL::Process *other);
+
 	// The add* methods create a cell and return the created cell. All signals must exist in advance.
 
 	RTLIL::Cell* addNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
diff --git a/passes/techmap/flatten.cc b/passes/techmap/flatten.cc
index a2794541a..a03226f9f 100644
--- a/passes/techmap/flatten.cc
+++ b/passes/techmap/flatten.cc
@@ -79,14 +79,6 @@ struct FlattenWorker
 
 	void flatten_cell(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Cell *cell, RTLIL::Module *tpl, std::vector<RTLIL::Cell*> &new_cells)
 	{
-		if (tpl->processes.size() != 0) {
-			log("Flattening yielded processes:");
-			for (auto &it : tpl->processes)
-				log(" %s",log_id(it.first));
-			log("\n");
-			log_error("Flattening yielded processes -> this is not supported.\n");
-		}
-
 		// Copy the contents of the flattened cell
 
 		dict<IdString, IdString> memory_map;
@@ -127,6 +119,14 @@ struct FlattenWorker
 			design->select(module, new_wire);
 		}
 
+		for (auto &tpl_proc_it : tpl->processes) {
+			RTLIL::Process *new_proc = module->addProcess(map_name(cell, tpl_proc_it.second), tpl_proc_it.second);
+			map_attributes(cell, new_proc, tpl_proc_it.second->name);
+			auto rewriter = [&](RTLIL::SigSpec &sig) { map_sigspec(wire_map, sig); };
+			new_proc->rewrite_sigspecs(rewriter);
+			design->select(module, new_proc);
+		}
+
 		for (auto tpl_cell : tpl->cells()) {
 			RTLIL::Cell *new_cell = module->addCell(map_name(cell, tpl_cell), tpl_cell);
 			map_attributes(cell, new_cell, tpl_cell->name);