aco: fix transition_to_{WQM,Exact} if exec.back() is not in exec

This can happen at merge blocks.

fossil-db (GFX10.3):
Totals from 25229 (17.25% of 146267) affected shaders:
CodeSize: 58575920 -> 58571376 (-0.01%); split: -0.01%, +0.00%
Instrs: 10979245 -> 10978109 (-0.01%); split: -0.01%, +0.00%
SClause: 591817 -> 591816 (-0.00%)
Copies: 604987 -> 603851 (-0.19%); split: -0.19%, +0.00%
Cycles: 96088796 -> 96084252 (-0.00%); split: -0.00%, +0.00%
VMEM: 10470372 -> 10470368 (-0.00%)

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Fixes: a56ddca4e8 ("aco: make all exec accesses non-temporaries")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4299
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9047>
This commit is contained in:
Rhys Perry 2021-02-15 11:24:22 +00:00 committed by Marge Bot
parent f0d17aa88c
commit ddce1ec5f5

View file

@ -306,14 +306,26 @@ void calculate_wqm_needs(exec_ctx& exec_ctx)
exec_ctx.handle_wqm = true;
}
Operand get_exec_op(Temp t)
{
if (t == Temp())
return Operand(exec, t.regClass());
else
return Operand(t);
}
void transition_to_WQM(exec_ctx& ctx, Builder bld, unsigned idx)
{
if (ctx.info[idx].exec.back().second & mask_type_wqm)
return;
if (ctx.info[idx].exec.back().second & mask_type_global) {
Temp exec_mask = bld.pseudo(aco_opcode::p_parallelcopy, bld.def(bld.lm), Operand(exec, bld.lm));
ctx.info[idx].exec.back().first = exec_mask;
exec_mask = bld.sop1(Builder::s_wqm, Definition(exec, bld.lm), bld.def(s1, scc), Operand(exec, bld.lm));
Temp exec_mask = ctx.info[idx].exec.back().first;
if (exec_mask == Temp()) {
exec_mask = bld.pseudo(aco_opcode::p_parallelcopy, bld.def(bld.lm), Operand(exec, bld.lm));
ctx.info[idx].exec.back().first = exec_mask;
}
exec_mask = bld.sop1(Builder::s_wqm, Definition(exec, bld.lm), bld.def(s1, scc), get_exec_op(exec_mask));
ctx.info[idx].exec.emplace_back(exec_mask, mask_type_global | mask_type_wqm);
return;
}
@ -344,20 +356,17 @@ void transition_to_Exact(exec_ctx& ctx, Builder bld, unsigned idx)
return;
}
/* otherwise, we create an exact mask and push to the stack */
Temp wqm = bld.sop1(Builder::s_and_saveexec, bld.def(bld.lm), bld.def(s1, scc),
Definition(exec, bld.lm), ctx.info[idx].exec[0].first, Operand(exec, bld.lm));
Temp wqm = ctx.info[idx].exec.back().first;
if (wqm == Temp()) {
wqm = bld.sop1(Builder::s_and_saveexec, bld.def(bld.lm), bld.def(s1, scc),
Definition(exec, bld.lm), ctx.info[idx].exec[0].first, Operand(exec, bld.lm));
} else {
bld.sop2(Builder::s_and, Definition(exec, bld.lm), bld.def(s1, scc), ctx.info[idx].exec[0].first, wqm);
}
ctx.info[idx].exec.back().first = wqm;
ctx.info[idx].exec.emplace_back(Temp(0, bld.lm), mask_type_exact);
}
Operand get_exec_op(Temp t)
{
if (t == Temp())
return Operand(exec, t.regClass());
else
return Operand(t);
}
unsigned add_coupling_code(exec_ctx& ctx, Block* block,
std::vector<aco_ptr<Instruction>>& instructions)
{