From bb956464cbc3d5012527ea3d16dbd3f2c96cdae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Wed, 1 Sep 2021 18:09:01 +0200 Subject: [PATCH] aco: Skip code paths to emit copies when there are no copies. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Found while running with libstdc++ debug mode. Fixes the following: Error: attempt to advance a dereferenceable (start-of-sequence) iterator -1 steps, which falls outside its valid range. Cc: mesa-stable Signed-off-by: Timur Kristóf Reviewed-by: Rhys Perry Reviewed-by: Tony Wasserka Part-of: --- src/amd/compiler/aco_lower_to_cssa.cpp | 35 +++++++++++++++++--------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/amd/compiler/aco_lower_to_cssa.cpp b/src/amd/compiler/aco_lower_to_cssa.cpp index ff842cb7f0b..cbd9873c32b 100644 --- a/src/amd/compiler/aco_lower_to_cssa.cpp +++ b/src/amd/compiler/aco_lower_to_cssa.cpp @@ -445,6 +445,9 @@ emit_parallelcopies(cssa_ctx& ctx) continue; std::map ltg; + bool has_vgpr_copy = false; + bool has_sgpr_copy = false; + /* first, try to coalesce all parallelcopies */ for (const copy& cp : ctx.parallelcopies[i]) { if (try_coalesce_copy(ctx, cp, i)) { @@ -459,6 +462,10 @@ emit_parallelcopies(cssa_ctx& ctx) uint32_t write_idx = ctx.merge_node_table[cp.def.tempId()].index; assert(write_idx != -1u); ltg[write_idx] = {cp, read_idx}; + + bool is_vgpr = cp.def.regClass().type() == RegType::vgpr; + has_vgpr_copy |= is_vgpr; + has_sgpr_copy |= !is_vgpr; } } @@ -475,19 +482,23 @@ emit_parallelcopies(cssa_ctx& ctx) Builder bld(ctx.program); Block& block = ctx.program->blocks[i]; - /* emit VGPR copies */ - auto IsLogicalEnd = [](const aco_ptr& inst) -> bool - { return inst->opcode == aco_opcode::p_logical_end; }; - auto it = std::find_if(block.instructions.rbegin(), block.instructions.rend(), IsLogicalEnd); - bld.reset(&block.instructions, std::prev(it.base())); - emit_copies_block(bld, ltg, RegType::vgpr); + if (has_vgpr_copy) { + /* emit VGPR copies */ + auto IsLogicalEnd = [](const aco_ptr& inst) -> bool + { return inst->opcode == aco_opcode::p_logical_end; }; + auto it = std::find_if(block.instructions.rbegin(), block.instructions.rend(), IsLogicalEnd); + bld.reset(&block.instructions, std::prev(it.base())); + emit_copies_block(bld, ltg, RegType::vgpr); + } - /* emit SGPR copies */ - aco_ptr branch = std::move(block.instructions.back()); - block.instructions.pop_back(); - bld.reset(&block.instructions); - emit_copies_block(bld, ltg, RegType::sgpr); - bld.insert(std::move(branch)); + if (has_sgpr_copy) { + /* emit SGPR copies */ + aco_ptr branch = std::move(block.instructions.back()); + block.instructions.pop_back(); + bld.reset(&block.instructions); + emit_copies_block(bld, ltg, RegType::sgpr); + bld.insert(std::move(branch)); + } } /* finally, rename coalesced phi operands */