From 7bd017081d9336bb83f6486fdcdc07af60176c1e Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Fri, 16 Jan 2026 07:56:59 -0800 Subject: [PATCH] [codegen 1.5] Fix register cleanup pass if all writes are no-ops In this case, we try to remove the register - but we forgot to clean up the writes, resulting in an error when we tried to remove the register. PiperOrigin-RevId: 857162262 --- xls/codegen_v_1_5/register_cleanup_pass.cc | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/xls/codegen_v_1_5/register_cleanup_pass.cc b/xls/codegen_v_1_5/register_cleanup_pass.cc index af97b37df5..9bfc5c2b1c 100644 --- a/xls/codegen_v_1_5/register_cleanup_pass.cc +++ b/xls/codegen_v_1_5/register_cleanup_pass.cc @@ -75,7 +75,9 @@ absl::StatusOr RegisterCleanupPass::RemoveTrivialLoadEnables( absl::StatusOr RegisterCleanupPass::RemoveImpossibleWrites( Block* block, QueryEngine& query_engine) const { - for (Register* reg : block->GetRegisters()) { + std::vector registers(block->GetRegisters().begin(), + block->GetRegisters().end()); + for (Register* reg : registers) { XLS_ASSIGN_OR_RETURN(std::vector writes, GetRegisterWrites(block, reg)); for (RegisterWrite* write : writes) { @@ -89,19 +91,23 @@ absl::StatusOr RegisterCleanupPass::RemoveImpossibleWrites( } XLS_ASSIGN_OR_RETURN(writes, GetRegisterWrites(block, reg)); - if (writes.empty() || (reg->reset_value().has_value() && - absl::c_all_of(writes, [&](RegisterWrite* write) { - return query_engine.KnownValue(write->data()) == - *reg->reset_value(); - }))) { + if (absl::c_all_of(writes, [&](RegisterWrite* write) { + return reg->reset_value().has_value() && + query_engine.KnownValue(write->data()) == *reg->reset_value(); + })) { // Nothing can ever write a new value to this register, so it's equivalent - // to its reset value. + // to its reset value. We can remove the register & all ops. XLS_ASSIGN_OR_RETURN(RegisterRead * read, block->GetRegisterRead(reg)); XLS_RETURN_IF_ERROR( read->ReplaceUsesWithNew( reg->reset_value().value_or(ZeroOfType(reg->type()))) .status()); XLS_RETURN_IF_ERROR(block->RemoveNode(read)); + for (RegisterWrite* write : writes) { + XLS_RETURN_IF_ERROR( + write->ReplaceUsesWithNew(Value::Tuple({})).status()); + XLS_RETURN_IF_ERROR(block->RemoveNode(write)); + } XLS_RETURN_IF_ERROR(block->RemoveRegister(reg)); } }