# UNDF: UNDF-2026-000000170 --- a/src/amd/compiler/aco_register_allocation.cpp +++ b/src/amd/compiler/aco_register_allocation.cpp @@ -998,6 +998,14 @@ update_renames(ra_ctx& ctx, RegisterFile& reg_file, std::vector& p bool never_rename = false) { + /* Build a tempId→index map for O(1) lookup of "did we already move a + * definition with this temp ID?". Maintained incrementally as entries + * are erased below. + */ + std::unordered_map def_temp_idx; + for (size_t i = 0; i < parallelcopies.size(); i++) { + if (parallelcopies[i].def.isTemp()) + def_temp_idx[parallelcopies[i].def.getTemp().id()] = i; + } + /* clear operands */ if (clear_operands) { for (parallelcopy& copy : parallelcopies) { @@ -1056,10 +1064,16 @@ update_renames(ra_ctx& ctx, RegisterFile& reg_file, std::vector& p /* Check if we moved another parallelcopy definition. */ - auto other = std::find_if(parallelcopies.begin(), parallelcopies.end(), [&](parallelcopy& c) - { return c.def.isTemp() && it->op.getTemp() == c.def.getTemp(); }); + auto map_it = def_temp_idx.find(it->op.getTemp().id()); + auto other = (map_it != def_temp_idx.end()) + ? parallelcopies.begin() + map_it->second + : parallelcopies.end(); if (other != parallelcopies.end()) it->op = other->op; @@ -1077,6 +1091,12 @@ update_renames(ra_ctx& ctx, RegisterFile& reg_file, std::vector& p if (!is_copy_kill && other != parallelcopies.end()) { if (renamed_all) { assert(other < it); + /* Remove erased entry from the index map. */ + if (other->def.isTemp()) + def_temp_idx.erase(other->def.getTemp().id()); it = parallelcopies.erase(other); + /* Rebuild indices after erase — entries after `other` shifted. */ + for (size_t i = std::distance(parallelcopies.begin(), it); i < parallelcopies.size(); i++) + if (parallelcopies[i].def.isTemp()) + def_temp_idx[parallelcopies[i].def.getTemp().id()] = i; } else if (other->copy_kill < 0 && !never_rename) {