Mesa (main): nir/nir_lower_io: Optimize 32-bit inbounds access

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jun 9 17:07:31 UTC 2022


Module: Mesa
Branch: main
Commit: 08577bbb703abdb91e1ae71ff2119beea59cd568
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=08577bbb703abdb91e1ae71ff2119beea59cd568

Author: Konstantin Seurer <konstantin.seurer at gmail.com>
Date:   Thu May 26 21:15:11 2022 +0200

nir/nir_lower_io: Optimize 32-bit inbounds access

Perform address calculation in 32 bits when
dealing with inbounds array derefs.

Closes: #6562
Signed-off-by: Konstantin Seurer <konstantin.seurer at gmail.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16729>

---

 src/compiler/nir/nir_lower_io.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/src/compiler/nir/nir_lower_io.c b/src/compiler/nir/nir_lower_io.c
index 4acd8f84ac9..9cb400b5a6e 100644
--- a/src/compiler/nir/nir_lower_io.c
+++ b/src/compiler/nir/nir_lower_io.c
@@ -1820,22 +1820,30 @@ nir_explicit_io_address_from_deref(nir_builder *b, nir_deref_instr *deref,
    case nir_deref_type_var:
       return build_addr_for_var(b, deref->var, addr_format);
 
+   case nir_deref_type_ptr_as_array:
    case nir_deref_type_array: {
       unsigned stride = nir_deref_instr_array_stride(deref);
       assert(stride > 0);
 
+      unsigned offset_bit_size = addr_get_offset_bit_size(base_addr, addr_format);
       nir_ssa_def *index = nir_ssa_for_src(b, deref->arr.index, 1);
-      index = nir_i2i(b, index, addr_get_offset_bit_size(base_addr, addr_format));
-      return build_addr_iadd(b, base_addr, addr_format, deref->modes,
-                                nir_amul_imm(b, index, stride));
-   }
+      nir_ssa_def *offset;
 
-   case nir_deref_type_ptr_as_array: {
-      nir_ssa_def *index = nir_ssa_for_src(b, deref->arr.index, 1);
-      index = nir_i2i(b, index, addr_get_offset_bit_size(base_addr, addr_format));
-      unsigned stride = nir_deref_instr_array_stride(deref);
-      return build_addr_iadd(b, base_addr, addr_format, deref->modes,
-                                nir_amul_imm(b, index, stride));
+      /* If the access chain has been declared in-bounds, then we know it doesn't
+       * overflow the type.  For nir_deref_type_array, this implies it cannot be
+       * negative. Also, since types in NIR have a maximum 32-bit size, we know the
+       * final result will fit in a 32-bit value so we can convert the index to
+       * 32-bit before multiplying and save ourselves from a 64-bit multiply.
+       */
+      if (deref->arr.in_bounds && deref->deref_type == nir_deref_type_array) {
+         index = nir_u2u32(b, index);
+         offset = nir_u2u(b, nir_amul_imm(b, index, stride), offset_bit_size);
+      } else {
+         index = nir_i2i(b, index, offset_bit_size);
+         offset = nir_amul_imm(b, index, stride);
+      }
+
+      return build_addr_iadd(b, base_addr, addr_format, deref->modes, offset);
    }
 
    case nir_deref_type_array_wildcard:



More information about the mesa-commit mailing list