Reviewed-by: Marta Lofstedt <marta.lofst...@intel.com>
> -----Original Message----- > From: mesa-dev [mailto:mesa-dev-boun...@lists.freedesktop.org] On > Behalf Of Timothy Arceri > Sent: Sunday, November 1, 2015 9:33 AM > To: mesa-dev@lists.freedesktop.org > Subject: [Mesa-dev] [PATCH] glsl: remove redundant function inout > assignments > > Handles the case with function inout params where array elements do an > assignment to themselves e.g. > > void array_mod(inout int b[2]) > { > b[0] = int(2); > b[1] = b[1]; > } > > Fixes assert in nir for: > ES31-CTS.arrays_of_arrays.InteractionFunctionCalls2 > > https://bugs.freedesktop.org/show_bug.cgi?id=92588 > --- > src/glsl/opt_copy_propagation_elements.cpp | 46 > ++++++++++++++++++++++++++++++ > 1 file changed, 46 insertions(+) > > Piglit test: https://patchwork.freedesktop.org/patch/63355/ > > diff --git a/src/glsl/opt_copy_propagation_elements.cpp > b/src/glsl/opt_copy_propagation_elements.cpp > index 353a5c6..a62b625 100644 > --- a/src/glsl/opt_copy_propagation_elements.cpp > +++ b/src/glsl/opt_copy_propagation_elements.cpp > @@ -439,6 +439,8 @@ ir_copy_propagation_elements_visitor::kill(kill_entry > *k) > /** > * Adds directly-copied channels between vector variables to the available > * copy propagation list. > + * > + * Also tidy up redundant function inout assignments while we are here. > */ > void > ir_copy_propagation_elements_visitor::add_copy(ir_assignment *ir) @@ - > 450,6 +452,50 @@ > ir_copy_propagation_elements_visitor::add_copy(ir_assignment *ir) > if (ir->condition) > return; > > + /* Handle a corner case with function inout params where array elements > + * do an assignment to themselves e.g. > + * > + * void array_mod(inout int b[2]) > + * { > + * b[0] = int(2); > + * b[1] = b[1]; > + * } > + */ > + ir_rvalue *rhs_array = ir->rhs; > + ir_rvalue *lhs_array = ir->lhs; > + if (lhs_array->as_dereference_array() && > + rhs_array->as_dereference_array()) { > + /* Check arrays are indexed by a const and match otherwise return */ > + while (rhs_array->as_dereference_array() && > + lhs_array->as_dereference_array()) { > + > + ir_dereference_array *rhs_deref_array = > + rhs_array->as_dereference_array(); > + ir_dereference_array *lhs_deref_array = > + lhs_array->as_dereference_array(); > + > + ir_constant *lhs_ai_const = > + lhs_deref_array->array_index->as_constant(); > + ir_constant *rhs_ai_const = > + rhs_deref_array->array_index->as_constant(); > + if (lhs_ai_const == NULL || rhs_ai_const == NULL || > + lhs_ai_const->value.i[0] != rhs_ai_const->value.i[0]) > + return; > + lhs_array = lhs_deref_array->array; > + rhs_array = rhs_deref_array->array; > + } > + > + ir_dereference_variable *lhs_var = lhs_array- > >as_dereference_variable(); > + ir_dereference_variable *rhs_var = rhs_array- > >as_dereference_variable(); > + if(lhs_var && rhs_var && lhs_var->var == rhs_var->var){ > + /* Removing the assignment now would mess up the loop > iteration > + * calling us. Just flag it to not execute, and someone else > + * will clean up the mess. > + */ > + ir->condition = new(ralloc_parent(ir)) ir_constant(false); > + } > + } > + > ir_dereference_variable *lhs = ir->lhs->as_dereference_variable(); > if (!lhs || !(lhs->type->is_scalar() || lhs->type->is_vector())) > return; > -- > 2.4.3 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev