diff --git a/src/amd/compiler/aco_optimizer.cpp b/src/amd/compiler/aco_optimizer.cpp index 22497a10452..c839e0696a3 100644 --- a/src/amd/compiler/aco_optimizer.cpp +++ b/src/amd/compiler/aco_optimizer.cpp @@ -1212,6 +1212,27 @@ void label_instruction(opt_ctx &ctx, Block& block, aco_ptr& instr) case aco_opcode::s_mov_b32: /* propagate */ case aco_opcode::s_mov_b64: case aco_opcode::v_mov_b32: + if (instr->operands[0].isTemp() && ctx.info[instr->operands[0].tempId()].is_vec() && + instr->operands[0].regClass() != instr->definitions[0].regClass()) { + /* We might not be able to copy-propagate if it's a SGPR->VGPR copy, so + * duplicate the vector instead. + */ + Instruction *vec = ctx.info[instr->operands[0].tempId()].instr; + aco_ptr old_copy = std::move(instr); + + instr.reset(create_instruction(aco_opcode::p_create_vector, Format::PSEUDO, vec->operands.size(), 1)); + instr->definitions[0] = old_copy->definitions[0]; + std::copy(vec->operands.begin(), vec->operands.end(), instr->operands.begin()); + for (unsigned i = 0; i < vec->operands.size(); i++) { + Operand& op = instr->operands[i]; + if (op.isTemp() && ctx.info[op.tempId()].is_temp() && + ctx.info[op.tempId()].temp.type() == instr->definitions[0].regClass().type()) + op.setTemp(ctx.info[op.tempId()].temp); + } + ctx.info[instr->definitions[0].tempId()].set_vec(instr.get()); + break; + } + /* fallthrough */ case aco_opcode::p_as_uniform: if (instr->definitions[0].isFixed()) { /* don't copy-propagate copies into fixed registers */