diff options
authorKenneth Graunke <>2015-03-05 23:18:36 -0800
committerEmil Velikov <>2015-03-11 18:11:56 +0000
commitcddbb3a7ba632e525b5c5a57c39e78b1a926c70f (patch)
parente4d3bd685540e59cd7fe722ad6bd3a2c32f277ec (diff)
glsl: Mark array access when copying to a temporary for the ?: operator.
Piglit's spec/glsl-1.20/compiler/structure-and-array-operations/ array-selection.vert test contains the following code: gl_Position = (pick_from_a_or_b ? a : b)[i]; where "a" and "b" are uniform vec4[2] variables. ast_to_hir creates a temporary vec4[2] variable, conditional_tmp, and generates an if-block to copy one or the other: (declare (temporary) (array vec4 2) conditional_tmp) (if (var_ref pick_from_a_or_b) ((assign () (var_ref conditional_tmp) (var_ref a))) ((assign () (var_ref conditional_tmp) (var_ref b)))) However, we failed to update max_array_access for "a" and "b", so it remained 0 - here, the whole array is being accessed. At link time, update_array_sizes() used this bogus information to change the types of "a" and "b" to vec4[1]. We then had assignments from a vec4[1] to a vec4[2], which is highly illegal. This tripped assertions in nir_split_var_copies with scalar VS. Signed-off-by: Kenneth Graunke <> Reviewed-by: Jason Ekstrand <> Cc: (cherry picked from commit 9f1e250e77ebd9255bbd9a83bd68c9e4068c2aab)
1 files changed, 6 insertions, 0 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index ed0eb0982dd..1dcb9244104 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -1603,6 +1603,12 @@ ast_expression::do_hir(exec_list *instructions,
&& cond_val != NULL) {
result = cond_val->value.b[0] ? op[1] : op[2];
} else {
+ /* The copy to conditional_tmp reads the whole array. */
+ if (type->is_array()) {
+ mark_whole_array_access(op[1]);
+ mark_whole_array_access(op[2]);
+ }
ir_variable *const tmp =
new(ctx) ir_variable(type, "conditional_tmp", ir_var_temporary);