summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIago Toral Quiroga <itoral@igalia.com>2022-06-10 10:46:51 +0200
committerMarge Bot <emma+marge@anholt.net>2022-06-14 11:30:33 +0000
commita97f78eb144ebc8964b891bbf708659e70e5f1c3 (patch)
tree68c743744ad4316eca36f844965867ef93adc7f9
parent2b0e45b18e0c29b9a3487df683369864f86d5c88 (diff)
broadcom/compiler: disable flags optimization for loop conditions
This is not safe because it may skip regenerating the flags for the loop condition in the loop continue block and these flags may be stomped in the loop body by other conditionals. Fixes: 9909fe6ba ('broadcom/compiler: Skip bool_to_cond where possible') Reviewed-by: Alejandro PiƱeiro <apinheiro@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17020>
-rw-r--r--src/broadcom/compiler/nir_to_vir.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/broadcom/compiler/nir_to_vir.c b/src/broadcom/compiler/nir_to_vir.c
index 852c454ffdf..2bdbccad308 100644
--- a/src/broadcom/compiler/nir_to_vir.c
+++ b/src/broadcom/compiler/nir_to_vir.c
@@ -4170,7 +4170,6 @@ ntq_emit_nonuniform_loop(struct v3d_compile *c, nir_loop *loop)
static void
ntq_emit_uniform_loop(struct v3d_compile *c, nir_loop *loop)
{
-
c->loop_cont_block = vir_new_block(c);
c->loop_break_block = vir_new_block(c);
@@ -4190,6 +4189,23 @@ ntq_emit_uniform_loop(struct v3d_compile *c, nir_loop *loop)
static void
ntq_emit_loop(struct v3d_compile *c, nir_loop *loop)
{
+ /* Disable flags optimization for loop conditions. The problem here is
+ * that we can have code like this:
+ *
+ * // block_0
+ * vec1 32 con ssa_9 = ine32 ssa_8, ssa_2
+ * loop {
+ * // block_1
+ * if ssa_9 {
+ *
+ * In this example we emit flags to compute ssa_9 and the optimization
+ * will skip regenerating them again for the loop condition in the
+ * loop continue block (block_1). However, this is not safe after the
+ * first iteration because the loop body can stomp the flags if it has
+ * any conditionals.
+ */
+ c->flags_temp = -1;
+
bool was_in_control_flow = c->in_control_flow;
c->in_control_flow = true;