summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2019-06-20 15:48:48 -0700
committerIan Romanick <[email protected]>2019-06-24 14:32:33 -0700
commitee1c69faddb3624ace6548dafaff50549a031380 (patch)
treecb49aecd3f3727da46c96fe086790c92ce9f9413 /src
parent5c4289dd4b3f37bc5b23b24069ee1137a6c1fa32 (diff)
glsl: Don't increase the iteration count when there are no terminators
Incrementing the iteration count was intended to fix an off-by-one error when the first terminator was superseded by a later terminator. If there is no first terminator or later terminator, there is no off-by-one error. Incrementing the loop count creates one. This can be seen in loops like: do { if (something) { // No breaks or continues here. } } while (false); Reviewed-by: Timothy Arceri <[email protected]> Tested-by: Abel Briggs <[email protected]> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=110953 Fixes: 646621c66da ("glsl: make loop unrolling more like the nir unrolling path")
Diffstat (limited to 'src')
-rw-r--r--src/compiler/glsl/loop_unroll.cpp8
1 files changed, 7 insertions, 1 deletions
diff --git a/src/compiler/glsl/loop_unroll.cpp b/src/compiler/glsl/loop_unroll.cpp
index 874f4185681..7e97c3cddf1 100644
--- a/src/compiler/glsl/loop_unroll.cpp
+++ b/src/compiler/glsl/loop_unroll.cpp
@@ -180,6 +180,11 @@ loop_unroll_visitor::simple_unroll(ir_loop *ir, int iterations)
void *const mem_ctx = ralloc_parent(ir);
loop_variable_state *const ls = this->state->get(ir);
+ /* If there are no terminators, then the loop iteration count must be 1.
+ * This is the 'do { } while (false);' case.
+ */
+ assert(!ls->terminators.is_empty() || iterations == 1);
+
ir_instruction *first_ir =
(ir_instruction *) ir->body_instructions.get_head();
@@ -221,7 +226,8 @@ loop_unroll_visitor::simple_unroll(ir_loop *ir, int iterations)
* the loop, or it the exit branch contains instructions. This ensures we
* execute any instructions before the terminator or in its exit branch.
*/
- if (limit_if != first_ir->as_if() || exit_branch_has_instructions)
+ if (!ls->terminators.is_empty() &&
+ (limit_if != first_ir->as_if() || exit_branch_has_instructions))
iterations++;
for (int i = 0; i < iterations; i++) {