};
struct block_info {
- std::vector<std::pair<Operand, uint8_t>> exec;
+ std::vector<std::pair<Operand, uint8_t>> exec; /* Vector of exec masks. Either a temporary or const -1. */
std::vector<WQMState> instr_needs;
uint8_t block_needs;
uint8_t ever_again_needs;
assert(startpgm->opcode == aco_opcode::p_startpgm);
bld.insert(std::move(startpgm));
+ Operand start_exec(bld.lm);
+
/* exec seems to need to be manually initialized with combined shaders */
if (ctx.program->stage.num_sw_stages() > 1 || ctx.program->stage.hw == HWStage::NGG) {
- bld.copy(Definition(exec, bld.lm), Operand(UINT32_MAX, bld.lm == s2));
+ start_exec = Operand(-1u, bld.lm == s2);
+ bld.copy(Definition(exec, bld.lm), start_exec);
}
if (ctx.handle_wqm) {
- ctx.info[0].exec.emplace_back(Operand(bld.lm), mask_type_global | mask_type_exact);
+ ctx.info[0].exec.emplace_back(start_exec, mask_type_global | mask_type_exact);
/* if this block only needs WQM, initialize already */
if (ctx.info[0].block_needs == WQM)
transition_to_WQM(ctx, bld, 0);
} else {
mask |= mask_type_exact;
}
- ctx.info[0].exec.emplace_back(Operand(bld.lm), mask);
+ ctx.info[0].exec.emplace_back(start_exec, mask);
}
return 1;
if (block->kind & block_kind_merge && !ctx.info[idx].exec.back().first.isUndefined()) {
Operand restore = ctx.info[idx].exec.back().first;
assert(restore.size() == bld.lm.size());
- ctx.info[idx].exec.back().first = bld.pseudo(aco_opcode::p_parallelcopy, Definition(exec, bld.lm), restore);
+ bld.pseudo(aco_opcode::p_parallelcopy, Definition(exec, bld.lm), restore);
+ if (!restore.isConstant())
+ ctx.info[idx].exec.back().first = Operand(bld.lm);
}
return i;