diff options
author | Timothy Arceri <[email protected]> | 2018-03-26 10:31:26 +1100 |
---|---|---|
committer | Juan A. Suarez Romero <[email protected]> | 2018-04-12 21:49:30 +0200 |
commit | 7fe3731e9fa884d1b449af3dd8706aec3970ef77 (patch) | |
tree | 98bd1b874a7da4467410eeff21cd062e71f0d46a | |
parent | 4cfb3553eb40b26c1c2931e13136c2ceb216e114 (diff) |
glsl: fix infinite loop caused by bug in loop unrolling pass
Just checking for 2 jumps is not enough to be sure we can do a
complex loop unroll. We need to make sure we also have also found
2 loop terminators.
Without this we were attempting to unroll a loop where the second
jump was nested inside multiple ifs which loop analysis is unable
to detect as a terminator. We ended up splicing out the first
terminator but failed to actually unroll the loop, this resulted
in the creation of a possible infinite loop.
Fixes: 646621c66da9 "glsl: make loop unrolling more like the nir unrolling path"
Tested-by: Gert Wollny <[email protected]>
Reviewed-by: Ian Romanick <[email protected]>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105670
(cherry picked from commit 56b867395dee1a48594b27987d3bf68a4e745dda)
Squashed with:
glsl: remove unreachable assert()
Earlier commit enforced that we'll bail out if the number of terminators
is different than 2. With that in mind, the assert() will never trigger.
Fixes: 56b867395de ("glsl: fix infinite loop caused by bug in loop
unrolling pass")
Reviewed-by: Timothy Arceri <[email protected]>
Signed-off-by: Emil Velikov <[email protected]>
(cherry picked from commit 8eceac9de7d3cd4fddabbe61d512acfed9812169)
-rw-r--r-- | src/compiler/glsl/loop_unroll.cpp | 4 |
1 files changed, 1 insertions, 3 deletions
diff --git a/src/compiler/glsl/loop_unroll.cpp b/src/compiler/glsl/loop_unroll.cpp index 6e06a30fb91..874f4185681 100644 --- a/src/compiler/glsl/loop_unroll.cpp +++ b/src/compiler/glsl/loop_unroll.cpp @@ -519,7 +519,7 @@ loop_unroll_visitor::visit_leave(ir_loop *ir) * isn't any additional unknown terminators, or any other jumps nested * inside futher ifs. */ - if (ls->num_loop_jumps != 2) + if (ls->num_loop_jumps != 2 || ls->terminators.length() != 2) return visit_continue; ir_instruction *first_ir = @@ -528,8 +528,6 @@ loop_unroll_visitor::visit_leave(ir_loop *ir) unsigned term_count = 0; bool first_term_then_continue = false; foreach_in_list(loop_terminator, t, &ls->terminators) { - assert(term_count < 2); - ir_if *ir_if = t->ir->as_if(); assert(ir_if != NULL); |