diff options
author | Ian Romanick <[email protected]> | 2019-06-20 15:48:48 -0700 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2019-06-24 14:32:33 -0700 |
commit | ee1c69faddb3624ace6548dafaff50549a031380 (patch) | |
tree | cb49aecd3f3727da46c96fe086790c92ce9f9413 /src | |
parent | 5c4289dd4b3f37bc5b23b24069ee1137a6c1fa32 (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.cpp | 8 |
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++) { |