assert(block->linear_succs.size() == 2);
assert(block->instructions.back()->opcode == aco_opcode::p_cbranch_z);
Temp cond = block->instructions.back()->operands[0].getTemp();
- nir_selection_control sel_ctrl = block->instructions.back()->branch().selection_control;
+ const bool sel_ctrl = block->instructions.back()->branch().selection_control_remove;
block->instructions.pop_back();
uint8_t mask_type = ctx.info[idx].exec.back().second & (mask_type_wqm | mask_type_exact);
Builder::Result r = bld.branch(aco_opcode::p_cbranch_z, bld.def(s2), Operand(exec, bld.lm),
block->linear_succs[1], block->linear_succs[0]);
- r->branch().selection_control = sel_ctrl;
+ r->branch().selection_control_remove = sel_ctrl;
return;
}
if (block->kind & block_kind_invert) {
// exec = s_andn2_b64 (original_exec, exec)
assert(block->instructions.back()->opcode == aco_opcode::p_branch);
- nir_selection_control sel_ctrl = block->instructions.back()->branch().selection_control;
+ const bool sel_ctrl = block->instructions.back()->branch().selection_control_remove;
block->instructions.pop_back();
assert(ctx.info[idx].exec.size() >= 2);
Operand orig_exec = ctx.info[idx].exec[ctx.info[idx].exec.size() - 2].first;
Builder::Result r = bld.branch(aco_opcode::p_cbranch_z, bld.def(s2), Operand(exec, bld.lm),
block->linear_succs[1], block->linear_succs[0]);
- r->branch().selection_control = sel_ctrl;
+ r->branch().selection_control_remove = sel_ctrl;
return;
}
Format::PSEUDO_BRANCH, 1, 1));
branch->definitions[0] = Definition(ctx->program->allocateTmp(s2));
branch->operands[0] = Operand(cond);
- branch->selection_control = sel_ctrl;
+ branch->selection_control_remove = sel_ctrl == nir_selection_control_flatten ||
+ sel_ctrl == nir_selection_control_divergent_always_taken;
ctx->block->instructions.push_back(std::move(branch));
ic->BB_if_idx = ctx->block->index;
branch.reset(create_instruction<Pseudo_branch_instruction>(aco_opcode::p_branch,
Format::PSEUDO_BRANCH, 0, 1));
branch->definitions[0] = Definition(ctx->program->allocateTmp(s2));
- branch->selection_control = sel_ctrl;
+ branch->selection_control_remove = sel_ctrl == nir_selection_control_flatten ||
+ sel_ctrl == nir_selection_control_divergent_always_taken;
ctx->block->instructions.push_back(std::move(branch));
ic->exec_potentially_empty_discard_old |= ctx->cf_info.exec_potentially_empty_discard;
* A value of 0 means the target has not been initialized (BB0 cannot be a branch target).
*/
uint32_t target[2];
- nir_selection_control selection_control;
+
+ /* Indicates that selection control prefers to remove this instruction if possible.
+ * This is set when the branch is divergent and always taken, or flattened.
+ */
+ bool selection_control_remove;
};
static_assert(sizeof(Pseudo_branch_instruction) == sizeof(Instruction) + 12, "Unexpected padding");
* - The compiler stack knows that it's a divergent branch always taken
*/
const bool prefer_remove =
- (branch->selection_control == nir_selection_control_flatten ||
- branch->selection_control == nir_selection_control_divergent_always_taken) &&
- ctx.program->gfx_level >= GFX10;
+ branch->selection_control_remove && ctx.program->gfx_level >= GFX10;
bool can_remove = block->index < target;
unsigned num_scalar = 0;
unsigned num_vector = 0;