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: 646621c66d "glsl: make loop unrolling more like the nir unrolling path"

Tested-by: Gert Wollny <gw.fossdev@gmail.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105670
(cherry picked from commit 56b867395d)

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: 56b867395d ("glsl: fix infinite loop caused by bug in loop
unrolling pass")
Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
(cherry picked from commit 8eceac9de7)
This commit is contained in:
Timothy Arceri 2018-03-26 10:31:26 +11:00 committed by Juan A. Suarez Romero
parent 4cfb3553eb
commit 7fe3731e9f

View file

@ -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);