if (instr->format == Format::PSEUDO) {
switch (instr->opcode) {
case aco_opcode::p_create_vector:
- return instr->definitions[0].getTemp().type() == RegType::vgpr;
case aco_opcode::p_extract_vector:
case aco_opcode::p_split_vector:
- return instr->operands[0].getTemp().type() == RegType::vgpr;
+ for (Definition def : instr->definitions) {
+ if (def.getTemp().type() == RegType::vgpr)
+ return true;
+ }
+ return false;
case aco_opcode::p_spill:
case aco_opcode::p_reload:
return false;
if (block->kind & block_kind_top_level) {
if (ctx.loop && ctx.wqm) {
- /* mark all break conditions as WQM */
unsigned block_idx = block->index + 1;
while (!(ctx.program->blocks[block_idx].kind & block_kind_top_level)) {
+ /* flag all break conditions as WQM:
+ * the conditions might be computed outside the nested CF */
if (ctx.program->blocks[block_idx].kind & block_kind_break)
mark_block_wqm(ctx, block_idx);
+ /* flag all blocks as WQM to ensure we enter all (nested) loops in WQM */
+ exec_ctx.info[block_idx].block_needs |= WQM;
block_idx++;
}
} else if (ctx.loop && !ctx.wqm) {
return;
if (ctx.info[idx].exec.back().second & mask_type_global) {
Temp exec_mask = ctx.info[idx].exec.back().first;
+ /* TODO: we might generate better code if we pass the uncopied "exec_mask"
+ * directly to the s_wqm (we still need to keep this parallelcopy for
+ * potential later uses of exec_mask though). We currently can't do this
+ * because of a RA bug. */
+ exec_mask = bld.pseudo(aco_opcode::p_parallelcopy, bld.def(bld.lm), bld.exec(exec_mask));
+ ctx.info[idx].exec.back().first = exec_mask;
+
exec_mask = bld.sop1(Builder::s_wqm, bld.def(bld.lm, exec), bld.def(s1, scc), exec_mask);
ctx.info[idx].exec.emplace_back(exec_mask, mask_type_global | mask_type_wqm);
return;
bld.insert(std::move(startpgm));
/* exec seems to need to be manually initialized with combined shaders */
- if (util_bitcount(ctx.program->stage & sw_mask) > 1) {
+ if (util_bitcount(ctx.program->stage & sw_mask) > 1 || (ctx.program->stage & hw_ngg_gs)) {
bld.sop1(Builder::s_mov, bld.exec(Definition(exec_mask)), bld.lm == s2 ? Operand(UINT64_MAX) : Operand(UINT32_MAX));
instructions[0]->definitions.pop_back();
}
/* create phi for loop footer */
aco_ptr<Pseudo_instruction> phi{create_instruction<Pseudo_instruction>(aco_opcode::p_linear_phi, Format::PSEUDO, preds.size(), 1)};
phi->definitions[0] = bld.def(bld.lm);
- if (k == info.num_exec_masks - 1) {
+ if (k == info.num_exec_masks - 1u) {
phi->definitions[0].setFixed(exec);
need_parallelcopy = false;
}
assert(block->instructions.back()->opcode == aco_opcode::p_branch);
block->instructions.pop_back();
- while (!(ctx.info[idx].exec.back().second & mask_type_loop))
+ bool need_parallelcopy = false;
+ while (!(ctx.info[idx].exec.back().second & mask_type_loop)) {
ctx.info[idx].exec.pop_back();
+ need_parallelcopy = true;
+ }
- ctx.info[idx].exec.back().first = bld.pseudo(aco_opcode::p_parallelcopy, bld.def(bld.lm, exec), ctx.info[idx].exec.back().first);
+ if (need_parallelcopy)
+ ctx.info[idx].exec.back().first = bld.pseudo(aco_opcode::p_parallelcopy, bld.def(bld.lm, exec), ctx.info[idx].exec.back().first);
bld.branch(aco_opcode::p_cbranch_nz, bld.exec(ctx.info[idx].exec.back().first), block->linear_succs[1], block->linear_succs[0]);
return;
}
cond = bld.tmp(s1);
Temp exec_mask = ctx.info[idx].exec[exec_idx].first;
exec_mask = bld.sop2(Builder::s_andn2, bld.def(bld.lm), bld.scc(Definition(cond)),
- exec_mask, current_exec);
+ exec_mask, bld.exec(current_exec));
ctx.info[idx].exec[exec_idx].first = exec_mask;
if (ctx.info[idx].exec[exec_idx].second & mask_type_loop)
break;