diff --git a/src/broadcom/compiler/nir_to_vir.c b/src/broadcom/compiler/nir_to_vir.c index 804f8f73b34..7611bd00be5 100644 --- a/src/broadcom/compiler/nir_to_vir.c +++ b/src/broadcom/compiler/nir_to_vir.c @@ -1137,6 +1137,11 @@ ntq_get_alu_parent(nir_src src) static enum v3d_qpu_cond ntq_emit_bool_to_cond(struct v3d_compile *c, nir_src src) { + struct qreg qsrc = ntq_get_src(c, src, 0); + /* skip if we already have src in the flags */ + if (qsrc.file == QFILE_TEMP && c->flags_temp == qsrc.index) + return c->flags_cond; + nir_alu_instr *compare = ntq_get_alu_parent(src); if (!compare) goto out; @@ -1146,6 +1151,7 @@ ntq_emit_bool_to_cond(struct v3d_compile *c, nir_src src) return cond; out: + vir_set_pf(c, vir_MOV_dest(c, vir_nop_reg(), ntq_get_src(c, src, 0)), V3D_QPU_PF_PUSHZ); return V3D_QPU_COND_IFNA; @@ -1294,6 +1300,8 @@ ntq_emit_alu(struct v3d_compile *c, nir_alu_instr *instr) result = vir_MOV(c, vir_SEL(c, cond, vir_uniform_f(c, 1.0), vir_uniform_f(c, 0.0))); + c->flags_temp = result.index; + c->flags_cond = cond; break; } @@ -1315,6 +1323,8 @@ ntq_emit_alu(struct v3d_compile *c, nir_alu_instr *instr) result = vir_MOV(c, vir_SEL(c, cond, vir_uniform_ui(c, ~0), vir_uniform_ui(c, 0))); + c->flags_temp = result.index; + c->flags_cond = cond; break; } @@ -1397,6 +1407,8 @@ ntq_emit_alu(struct v3d_compile *c, nir_alu_instr *instr) result = vir_MOV(c, vir_SEL(c, V3D_QPU_COND_IFA, vir_uniform_ui(c, ~0), vir_uniform_ui(c, 0))); + c->flags_temp = result.index; + c->flags_cond = V3D_QPU_COND_IFA; break; case nir_op_pack_half_2x16_split: @@ -2672,10 +2684,12 @@ ntq_emit_intrinsic(struct v3d_compile *c, nir_intrinsic_instr *instr) case nir_intrinsic_load_helper_invocation: vir_set_pf(c, vir_MSF_dest(c, vir_nop_reg()), V3D_QPU_PF_PUSHZ); - ntq_store_dest(c, &instr->dest, 0, - vir_MOV(c, vir_SEL(c, V3D_QPU_COND_IFA, - vir_uniform_ui(c, ~0), - vir_uniform_ui(c, 0)))); + struct qreg qdest = vir_MOV(c, vir_SEL(c, V3D_QPU_COND_IFA, + vir_uniform_ui(c, ~0), + vir_uniform_ui(c, 0))); + c->flags_temp = qdest.index; + c->flags_cond = V3D_QPU_COND_IFA; + ntq_store_dest(c, &instr->dest, 0, qdest); break; case nir_intrinsic_load_front_face: diff --git a/src/broadcom/compiler/v3d_compiler.h b/src/broadcom/compiler/v3d_compiler.h index a9ed28b1a7a..548940c7f92 100644 --- a/src/broadcom/compiler/v3d_compiler.h +++ b/src/broadcom/compiler/v3d_compiler.h @@ -735,6 +735,13 @@ struct v3d_compile { struct qblock *cur_block; struct qblock *loop_cont_block; struct qblock *loop_break_block; + /** + * Which temp, if any, do we currently have in the flags? + * This is set when processing a comparison instruction, and + * reset to -1 by anything else that touches the flags. + */ + int32_t flags_temp; + enum v3d_qpu_cond flags_cond; uint64_t *qpu_insts; uint32_t qpu_inst_count; diff --git a/src/broadcom/compiler/vir.c b/src/broadcom/compiler/vir.c index 1d9aa1f51f4..e6cf729f929 100644 --- a/src/broadcom/compiler/vir.c +++ b/src/broadcom/compiler/vir.c @@ -234,6 +234,7 @@ vir_set_cond(struct qinst *inst, enum v3d_qpu_cond cond) void vir_set_pf(struct v3d_compile *c, struct qinst *inst, enum v3d_qpu_pf pf) { + c->flags_temp = -1; if (vir_is_add(inst)) { inst->qpu.flags.apf = pf; } else { @@ -245,6 +246,7 @@ vir_set_pf(struct v3d_compile *c, struct qinst *inst, enum v3d_qpu_pf pf) void vir_set_uf(struct v3d_compile *c, struct qinst *inst, enum v3d_qpu_uf uf) { + c->flags_temp = -1; if (vir_is_add(inst)) { inst->qpu.flags.auf = uf; } else { @@ -542,6 +544,7 @@ vir_compile_init(const struct v3d_compiler *compiler, _mesa_key_pointer_equal); c->tmu.outstanding_regs = _mesa_pointer_set_create(c); + c->flags_temp = -1; return c; }