mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 02:48:06 +02:00
nir: fix partial loop unroll OOB check for loops not starting at 0
is_access_out_of_bounds() decides whether the residual loop (created
by partial_unroll) will access arrays out of bounds by checking whether
array_length is less than or equal to trip_count. That assumes the
induction variable starts at 0. For example glamor gradient shader
shader-db/shaders/glamor/4.shader_test:
uniform float stops[18];
for (i = 1; i < n_stop; i++)
if (stop_len < stops[i]) break;
trip_count is guessed as 17 from the array indexing, so the residual
loop's index begins at 18, out of bounds for the 18-element array, yet
18 <= 17 is false, so the OOB removal is skipped and the residual loop
is not eliminated.
Correctly consider the start value for the OOB check. This lets glamor
gradient shaders with loops starting at i=1 unroll the same way as i=0
loops.
Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41203>
This commit is contained in:
parent
04055256ec
commit
959f59b3f0
3 changed files with 9 additions and 3 deletions
|
|
@ -3584,6 +3584,9 @@ typedef struct nir_loop_terminator {
|
|||
/** Condition instruction that contains the induction variable */
|
||||
nir_instr *conditional_instr;
|
||||
|
||||
/** Init source of the induction variable used in conditional_instr. */
|
||||
nir_src *init_src;
|
||||
|
||||
/** Block within ::nif that has the break instruction. */
|
||||
nir_block *break_block;
|
||||
|
||||
|
|
|
|||
|
|
@ -1201,6 +1201,7 @@ find_trip_count(loop_info_state *state, unsigned execution_mode,
|
|||
*/
|
||||
|
||||
nir_loop_induction_variable *lv = get_loop_var(basic_ind.def, state);
|
||||
terminator->init_src = lv->init_src;
|
||||
|
||||
/* The basic induction var might be a vector but, because we guarantee
|
||||
* earlier that the phi source has a scalar swizzle, we can take the
|
||||
|
|
|
|||
|
|
@ -627,11 +627,13 @@ is_access_out_of_bounds(nir_loop_terminator *term, nir_deref_instr *deref,
|
|||
|
||||
/* We have already unrolled the loop and the new one will be imbedded in
|
||||
* the innermost continue branch. So unless the array is greater than
|
||||
* the trip count any iteration over the loop will be an out of bounds
|
||||
* access of the array.
|
||||
* the initial value plus the trip count any iteration over the loop
|
||||
* will be an out of bounds access of the array.
|
||||
*/
|
||||
unsigned length = glsl_type_is_vector(parent->type) ? glsl_get_vector_elements(parent->type) : glsl_get_length(parent->type);
|
||||
return length <= trip_count;
|
||||
unsigned init_value = nir_src_is_const(*term->init_src) ?
|
||||
nir_src_as_uint(*term->init_src) : 0;
|
||||
return length <= init_value + trip_count;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue