glsl: handle scope correctly when inlining loop expression
authorTimothy Arceri <tarceri@itsqueeze.com>
Tue, 24 Aug 2021 07:54:06 +0000 (17:54 +1000)
committerMarge Bot <eric+marge@anholt.net>
Wed, 8 Sep 2021 03:56:59 +0000 (03:56 +0000)
We need to clone the previously evaluated loop expression when
inlining otherwise we will have conflicts with shadow variables
defined in deeper scopes.

Fixes: 5c02e2e2de75 ("glsl: Generate IR for switch statements")

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5255

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12465>

src/compiler/glsl/ast.h
src/compiler/glsl/ast_to_hir.cpp

index c6b578c..0a5b94b 100644 (file)
@@ -1195,6 +1195,8 @@ public:
    ast_node *condition;
    ast_expression *rest_expression;
 
+   exec_list rest_instructions;
+
    ast_node *body;
 
    /**
index 4b9530c..07a39a2 100644 (file)
@@ -6531,8 +6531,8 @@ ast_jump_statement::hir(exec_list *instructions,
          if (state->loop_nesting_ast != NULL &&
              mode == ast_continue && !state->switch_state.is_switch_innermost) {
             if (state->loop_nesting_ast->rest_expression) {
-               state->loop_nesting_ast->rest_expression->hir(instructions,
-                                                             state);
+               clone_ir_list(ctx, instructions,
+                             &state->loop_nesting_ast->rest_instructions);
             }
             if (state->loop_nesting_ast->mode ==
                 ast_iteration_statement::ast_do_while) {
@@ -6780,8 +6780,8 @@ ast_switch_statement::hir(exec_list *instructions,
 
       if (state->loop_nesting_ast != NULL) {
          if (state->loop_nesting_ast->rest_expression) {
-            state->loop_nesting_ast->rest_expression->hir(&irif->then_instructions,
-                                                          state);
+            clone_ir_list(ctx, &irif->then_instructions,
+                          &state->loop_nesting_ast->rest_instructions);
          }
          if (state->loop_nesting_ast->mode ==
              ast_iteration_statement::ast_do_while) {
@@ -7138,7 +7138,6 @@ ast_iteration_statement::hir(exec_list *instructions,
    if (mode != ast_do_while)
       condition_to_hir(&stmt->body_instructions, state);
 
-   exec_list rest_instructions;
    if (rest_expression != NULL)
       rest_expression->hir(&rest_instructions, state);