diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index eddab6aceed..f79f5104af4 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -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; diff --git a/src/compiler/nir/nir_loop_analyze.c b/src/compiler/nir/nir_loop_analyze.c index 64d82b5c2fe..208dd9fd895 100644 --- a/src/compiler/nir/nir_loop_analyze.c +++ b/src/compiler/nir/nir_loop_analyze.c @@ -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 diff --git a/src/compiler/nir/nir_opt_loop_unroll.c b/src/compiler/nir/nir_opt_loop_unroll.c index 70a23b7acce..df3a2767f6f 100644 --- a/src/compiler/nir/nir_opt_loop_unroll.c +++ b/src/compiler/nir/nir_opt_loop_unroll.c @@ -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;