From 441294962cd65d44febdbe9ef0b0d99b5d27cec8 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 14 Feb 2019 09:42:38 -0800 Subject: [PATCH] v3d: Fix the check for "is the last thrsw inside control flow" The execute.file check used to be good enough, until I stopped setting up the execute mask for uniform ifs. No known tests fixed, noticed while doing a refactor. Fixes: 080506057310 ("v3d: Handle dynamically uniform IF statements with uniform control flow.") --- src/broadcom/compiler/nir_to_vir.c | 24 ++++++++++++++++-------- src/broadcom/compiler/v3d_compiler.h | 1 + 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/broadcom/compiler/nir_to_vir.c b/src/broadcom/compiler/nir_to_vir.c index 86f4a3a..7ab3b4f 100644 --- a/src/broadcom/compiler/nir_to_vir.c +++ b/src/broadcom/compiler/nir_to_vir.c @@ -121,7 +121,7 @@ vir_emit_thrsw(struct v3d_compile *c) */ c->last_thrsw = vir_NOP(c); c->last_thrsw->qpu.sig.thrsw = true; - c->last_thrsw_at_top_level = (c->execute.file == QFILE_NULL); + c->last_thrsw_at_top_level = !c->in_control_flow; } static uint32_t @@ -2085,10 +2085,10 @@ ntq_emit_nonuniform_if(struct v3d_compile *c, nir_if *if_stmt) else else_block = vir_new_block(c); - bool was_top_level = false; + bool was_uniform_control_flow = false; if (c->execute.file == QFILE_NULL) { c->execute = vir_MOV(c, vir_uniform_ui(c, 0)); - was_top_level = true; + was_uniform_control_flow = true; } /* Set up the flags for the IF condition (taking the THEN branch). */ @@ -2097,7 +2097,7 @@ ntq_emit_nonuniform_if(struct v3d_compile *c, nir_if *if_stmt) /* Update the flags+cond to mean "Taking the ELSE branch (!cond) and * was previously active (execute Z) for updating the exec flags. */ - if (was_top_level) { + if (was_uniform_control_flow) { cond = v3d_qpu_cond_invert(cond); } else { struct qinst *inst = vir_MOV_dest(c, vir_nop_reg(), c->execute); @@ -2152,7 +2152,7 @@ ntq_emit_nonuniform_if(struct v3d_compile *c, nir_if *if_stmt) vir_link_blocks(c->cur_block, after_block); vir_set_emit_block(c, after_block); - if (was_top_level) + if (was_uniform_control_flow) c->execute = c->undef; else ntq_activate_execute_for_block(c); @@ -2161,12 +2161,15 @@ ntq_emit_nonuniform_if(struct v3d_compile *c, nir_if *if_stmt) static void ntq_emit_if(struct v3d_compile *c, nir_if *nif) { + bool was_in_control_flow = c->in_control_flow; + c->in_control_flow = true; if (c->execute.file == QFILE_NULL && nir_src_is_dynamically_uniform(nif->condition)) { ntq_emit_uniform_if(c, nif); } else { ntq_emit_nonuniform_if(c, nif); } + c->in_control_flow = was_in_control_flow; } static void @@ -2245,10 +2248,13 @@ static void ntq_emit_cf_list(struct v3d_compile *c, struct exec_list *list); static void ntq_emit_loop(struct v3d_compile *c, nir_loop *loop) { - bool was_top_level = false; + bool was_in_control_flow = c->in_control_flow; + c->in_control_flow = true; + + bool was_uniform_control_flow = false; if (c->execute.file == QFILE_NULL) { c->execute = vir_MOV(c, vir_uniform_ui(c, 0)); - was_top_level = true; + was_uniform_control_flow = true; } struct qblock *save_loop_cont_block = c->loop_cont_block; @@ -2286,7 +2292,7 @@ ntq_emit_loop(struct v3d_compile *c, nir_loop *loop) vir_link_blocks(c->cur_block, c->loop_break_block); vir_set_emit_block(c, c->loop_break_block); - if (was_top_level) + if (was_uniform_control_flow) c->execute = c->undef; else ntq_activate_execute_for_block(c); @@ -2295,6 +2301,8 @@ ntq_emit_loop(struct v3d_compile *c, nir_loop *loop) c->loop_cont_block = save_loop_cont_block; c->loops++; + + c->in_control_flow = was_in_control_flow; } static void diff --git a/src/broadcom/compiler/v3d_compiler.h b/src/broadcom/compiler/v3d_compiler.h index d29579b..3817afe 100644 --- a/src/broadcom/compiler/v3d_compiler.h +++ b/src/broadcom/compiler/v3d_compiler.h @@ -538,6 +538,7 @@ struct v3d_compile { * yes, otherwise a block number + 1 that the channel jumped to. */ struct qreg execute; + bool in_control_flow; struct qreg line_x, point_x, point_y; -- 2.7.4