From 174c057926fddd637d3c038c3162559a38bebe88 Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Tue, 24 Aug 2021 17:54:06 +1000 Subject: [PATCH] glsl: handle scope correctly when inlining loop expression 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 Part-of: --- src/compiler/glsl/ast.h | 2 ++ src/compiler/glsl/ast_to_hir.cpp | 9 ++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/compiler/glsl/ast.h b/src/compiler/glsl/ast.h index c6b578cb894..0a5b94bb1ce 100644 --- a/src/compiler/glsl/ast.h +++ b/src/compiler/glsl/ast.h @@ -1195,6 +1195,8 @@ public: ast_node *condition; ast_expression *rest_expression; + exec_list rest_instructions; + ast_node *body; /** diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp index 4b9530c1fca..07a39a2d9ce 100644 --- a/src/compiler/glsl/ast_to_hir.cpp +++ b/src/compiler/glsl/ast_to_hir.cpp @@ -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);