Skip to content

nir/lower_io: Fix the unknown-array-index case in get_deref_align

The current align_mul calculation in the unknown-array-index calculation is

align_mul = MIN3(parent_mul,
                 min_pow2_divisor(parent_offset),
                 min_pow2_divisor(stride))

which is certainly correct if parent_offset > 0. However, when parent_offset = 0, min_pow2_divisor(parent_offset) isn't well-defined and our calculation for it is 1 << -1 which isn't well-defined. That said.... it's not actually needed.

The offset to the base of the array is

array_base = parent_mul * k + parent_offset

for some integer k. When we throw in an unknown array index i, we get

elem = parent_mul * k + parent_offset + stride * i.

If we set new_align = MIN2(parent_mul, min_pow2_divisor(stride)), then both parent_mul and stride are divisible by new_align and

elem = (parent_mul / new_alig) * new_align * k +
       (stride / new_align) * new_align * i + parent_offset

     = new_align * ((parent_mul / new_alig) * k +
                    (stride / new_align) * i) + parent_offset

so elem = new_align * j + parent_offset where

j = (parent_mul / new_alig) * k + (stride / new_align) * i.

That's a very long-winded way of saying that we can delete one parameter from the align_mul calculation and it's still fine. :-)

Fixes: 480329cf "nir: Add a helper for getting the alignment of a deref"

Edited by Faith Ekstrand

Merge request reports

Loading