From ba796d511501a6cea601ff51b8b6dbb09ea514f4 Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Thu, 25 Feb 2021 11:14:53 +0100 Subject: [PATCH] ir3/postsched: Make sure to schedule inputs before kill Before, we would prefer to schedule inputs before kills, which works assuming that the live range of the bary_ij system value don't get split and therefore all bary.f are ready at the start of the block. However live range splitting can mess up that assumption and cause a kill to get scheduled before a move that leads to a bary.f. This fixes even e.g. dEQP-GLES2.functional.shaders.discard.basic_always on a3xx before introducing CSE of collect instructions, but even after that it could be a problem theoretically as the register allocator doesn't guarantee that any live ranges aren't split. Reviewed-by: Eric Anholt Part-of: --- src/freedreno/ir3/ir3_postsched.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/freedreno/ir3/ir3_postsched.c b/src/freedreno/ir3/ir3_postsched.c index 6d53b000c21..f2ff6a051a1 100644 --- a/src/freedreno/ir3/ir3_postsched.c +++ b/src/freedreno/ir3/ir3_postsched.c @@ -527,6 +527,13 @@ sched_dag_init(struct ir3_postsched_ctx *ctx) struct util_dynarray kills; util_dynarray_init(&kills, ctx->mem_ctx); + /* The last bary.f with the (ei) flag must be scheduled before any kills, + * or the hw gets angry. Keep track of inputs here so we can add the + * false dep on the kill instruction. + */ + struct util_dynarray inputs; + util_dynarray_init(&inputs, ctx->mem_ctx); + /* * Normal srcs won't be in SSA at this point, those are dealt with in * calculate_forward_deps() and calculate_reverse_deps(). But we still @@ -553,7 +560,14 @@ sched_dag_init(struct ir3_postsched_ctx *ctx) dag_add_edge(&sn->dag, &n->dag, NULL); } - if (is_kill(instr)) { + if (is_input(instr)) { + util_dynarray_append(&inputs, struct ir3_instruction *, instr); + } else if (is_kill(instr)) { + util_dynarray_foreach(&inputs, struct ir3_instruction *, instrp) { + struct ir3_instruction *input = *instrp; + struct ir3_postsched_node *in = input->data; + dag_add_edge(&in->dag, &n->dag, NULL); + } util_dynarray_append(&kills, struct ir3_instruction *, instr); } else if (is_tex(instr) || is_mem(instr)) { util_dynarray_foreach(&kills, struct ir3_instruction *, instrp) {