Mesa (10.1): glsl: Fix continue statements in do-while loops.

Ian Romanick idr at kemper.freedesktop.org
Sat Feb 8 01:10:20 UTC 2014


Module: Mesa
Branch: 10.1
Commit: ee632e68bd945a0650f6382750b01fc959f7d2e1
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ee632e68bd945a0650f6382750b01fc959f7d2e1

Author: Paul Berry <stereotype441 at gmail.com>
Date:   Fri Jan 31 09:55:35 2014 -0800

glsl: Fix continue statements in do-while loops.

>From the GLSL 4.40 spec, section 6.4 (Jumps):

    The continue jump is used only in loops. It skips the remainder of
    the body of the inner most loop of which it is inside. For while
    and do-while loops, this jump is to the next evaluation of the
    loop condition-expression from which the loop continues as
    previously defined.

Previously, we incorrectly treated a "continue" statement as jumping
to the top of a do-while loop.

This patch fixes the problem by replicating the loop condition when
converting the "continue" statement to IR.  (We already do a similar
thing in "for" loops, to ensure that "continue" causes the loop
expression to be executed).

Fixes piglit tests:
- glsl-fs-continue-inside-do-while.shader_test
- glsl-vs-continue-inside-do-while.shader_test
- glsl-fs-continue-in-switch-in-do-while.shader_test
- glsl-vs-continue-in-switch-in-do-while.shader_test

Cc: mesa-stable at lists.freedesktop.org

Acked-by: Carl Worth <cworth at cworth.org>
Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
Reviewed-by: Matt Turner <mattst88 at gmail.com>
(cherry picked from commit 7f5740899fe8ee2d7fecebf1b9622e06dbc78f43)

---

 src/glsl/ast_to_hir.cpp |   23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 950f513..8d096ad 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -4029,17 +4029,22 @@ ast_jump_statement::hir(exec_list *instructions,
 	 _mesa_glsl_error(& loc, state,
 			  "break may only appear in a loop or a switch");
       } else {
-	 /* For a loop, inline the for loop expression again,
-	  * since we don't know where near the end of
-	  * the loop body the normal copy of it
-	  * is going to be placed.
+	 /* For a loop, inline the for loop expression again, since we don't
+	  * know where near the end of the loop body the normal copy of it is
+	  * going to be placed.  Same goes for the condition for a do-while
+	  * loop.
 	  */
 	 if (state->loop_nesting_ast != NULL &&
-	     mode == ast_continue &&
-	     state->loop_nesting_ast->rest_expression) {
-	    state->loop_nesting_ast->rest_expression->hir(instructions,
-							  state);
-	 }
+	     mode == ast_continue) {
+            if (state->loop_nesting_ast->rest_expression) {
+               state->loop_nesting_ast->rest_expression->hir(instructions,
+                                                             state);
+            }
+            if (state->loop_nesting_ast->mode ==
+                ast_iteration_statement::ast_do_while) {
+               state->loop_nesting_ast->condition_to_hir(instructions, state);
+            }
+         }
 
 	 if (state->switch_state.is_switch_innermost &&
 	     mode == ast_break) {




More information about the mesa-commit mailing list