summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl
diff options
context:
space:
mode:
authorTimothy Arceri <[email protected]>2017-03-26 23:34:13 +1100
committerTimothy Arceri <[email protected]>2017-03-28 09:54:31 +1100
commitc1096b7f1d49f33c85b1042f82ccb063f63e7c20 (patch)
tree3dbee77693f390af6492f186e93c65f2e295a66c /src/compiler/glsl
parentb640dfcd0506253231b93c03de7ee393fb0dfc46 (diff)
glsl: fix lower jumps for returns when loop is inside an if
Previously we would just escape the loop and move everything following the loop inside the if to the else branch of a new if with a return flag conditional. However everything outside the if the loop was nested in would still get executed. Adding a new return to the then branch of the new if fixes this and we just let a follow pass clean it up if needed. Fixes: tests/spec/glsl-1.10/execution/vs-nested-return-sibling-loop.shader_test tests/spec/glsl-1.10/execution/vs-nested-return-sibling-loop2.shader_test Cc: "13.0 17.0" <[email protected]> Reviewed-by: Roland Scheidegger <[email protected]>
Diffstat (limited to 'src/compiler/glsl')
-rw-r--r--src/compiler/glsl/lower_jumps.cpp17
1 files changed, 12 insertions, 5 deletions
diff --git a/src/compiler/glsl/lower_jumps.cpp b/src/compiler/glsl/lower_jumps.cpp
index ed1b6d1ea63..1b893e521b8 100644
--- a/src/compiler/glsl/lower_jumps.cpp
+++ b/src/compiler/glsl/lower_jumps.cpp
@@ -932,14 +932,21 @@ lower_continue:
* break statement if necessary.
*/
return_if->then_instructions.push_tail(new(ir) ir_loop_jump(ir_loop_jump::jump_break));
- else
- /* Otherwise, all we need to do is ensure that the
- * instructions that follow are only executed if the
- * return flag is clear. We can do that by moving those
- * instructions into the else clause of the generated if
+ else {
+ /* Otherwise, ensure that the instructions that follow are only
+ * executed if the return flag is clear. We can do that by moving
+ * those instructions into the else clause of the generated if
* statement.
*/
move_outer_block_inside(ir, &return_if->else_instructions);
+
+ /* In case the loop is embeded inside an if add a new return to
+ * the return flag then branch and let a future pass tidy it up.
+ */
+ if (this->function.signature->return_type->is_void())
+ return_if->then_instructions.push_tail(new(ir) ir_return(NULL));
+ }
+
ir->insert_after(return_if);
}