summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimur Kristóf <timur.kristof@gmail.com>2021-12-21 15:24:21 +0100
committerEric Engestrom <eric@engestrom.ch>2021-12-29 20:56:29 +0000
commit11ef52212adfafbdc389d474b21ce97815d5b51d (patch)
tree2eada649d1666a73b523fb6b35627ae051702687
parent0fb58901f05f6ef5441b265f8b2d8f3ac8837988 (diff)
aco/optimizer_postRA: Fix applying VCC to branches.
Fixes: a93092d0edc92eea8e8e96709ad9857f05c45cef Signed-off-by: Timur Kristóf <timur.kristof@gmail.com> Reviewed-by: Daniel Schürmann <daniel@schuermann.dev> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14281> (cherry picked from commit b293299776069676af1bc76aeb1d48223e0e7de2)
-rw-r--r--.pick_status.json2
-rw-r--r--src/amd/compiler/aco_optimizer_postRA.cpp25
2 files changed, 9 insertions, 18 deletions
diff --git a/.pick_status.json b/.pick_status.json
index 1d6b515ff61..bc4d21e9ee1 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -895,7 +895,7 @@
"description": "aco/optimizer_postRA: Fix applying VCC to branches.",
"nominated": true,
"nomination_type": 1,
- "resolution": 0,
+ "resolution": 1,
"main_sha": null,
"because_sha": "a93092d0edc92eea8e8e96709ad9857f05c45cef"
},
diff --git a/src/amd/compiler/aco_optimizer_postRA.cpp b/src/amd/compiler/aco_optimizer_postRA.cpp
index 2b59ad54e06..5019eb619f0 100644
--- a/src/amd/compiler/aco_optimizer_postRA.cpp
+++ b/src/amd/compiler/aco_optimizer_postRA.cpp
@@ -50,18 +50,6 @@ Idx clobbered{UINT32_MAX, 1};
Idx const_or_undef{UINT32_MAX, 2};
Idx written_by_multiple_instrs{UINT32_MAX, 3};
-bool
-is_instr_after(Idx second, Idx first)
-{
- if (first == not_written_in_block && second != not_written_in_block)
- return true;
-
- if (!first.found() || !second.found())
- return false;
-
- return second.block > first.block || (second.block == first.block && second.instr > first.instr);
-}
-
struct pr_opt_ctx {
Program* program;
Block* current_block;
@@ -215,16 +203,19 @@ try_apply_branch_vcc(pr_opt_ctx& ctx, aco_ptr<Instruction>& instr)
Idx op0_instr_idx = last_writer_idx(ctx, instr->operands[0]);
Idx last_vcc_wr_idx = last_writer_idx(ctx, vcc, ctx.program->lane_mask);
- Idx last_exec_wr_idx = last_writer_idx(ctx, exec, ctx.program->lane_mask);
/* We need to make sure:
+ * - the instructions that wrote the operand register and VCC are both found
* - the operand register used by the branch, and VCC were both written in the current block
- * - VCC was NOT written after the operand register
- * - EXEC is sane and was NOT written after the operand register
+ * - EXEC hasn't been clobbered since the last VCC write
+ * - VCC hasn't been clobbered since the operand register was written
+ * (ie. the last VCC writer precedes the op0 writer)
*/
if (!op0_instr_idx.found() || !last_vcc_wr_idx.found() ||
- !is_instr_after(last_vcc_wr_idx, last_exec_wr_idx) ||
- !is_instr_after(op0_instr_idx, last_vcc_wr_idx))
+ op0_instr_idx.block != ctx.current_block->index ||
+ last_vcc_wr_idx.block != ctx.current_block->index ||
+ is_clobbered_since(ctx, exec, ctx.program->lane_mask, last_vcc_wr_idx) ||
+ is_clobbered_since(ctx, vcc, ctx.program->lane_mask, op0_instr_idx))
return;
Instruction* op0_instr = ctx.get(op0_instr_idx);