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

Author: Alyssa Rosenzweig <[email protected]>
Date:   Fri Nov 25 21:40:38 2022 -0500

nir/lower_blend: Avoid useless iand with logic ops

The upper bits start correctly, there's no need to clear them as long as we keep
them zero'ed by using ixor with a valid bit mask instead of inot.

Makes the code generated for logic op slightly less ridiculous. I'm joking. It's
still ridiculous but I'm not in the mood to fix up the Midgard compiler and it's
just a little ALU for a feature almost nothing uses.

Signed-off-by: Alyssa Rosenzweig <[email protected]>
Reviewed-by: Gert Wollny <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20016>

---

 src/compiler/nir/nir_lower_blend.c | 33 +++++++++++++++------------------
 1 file changed, 15 insertions(+), 18 deletions(-)

diff --git a/src/compiler/nir/nir_lower_blend.c 
b/src/compiler/nir/nir_lower_blend.c
index d17d6768435..9f394d96c12 100644
--- a/src/compiler/nir/nir_lower_blend.c
+++ b/src/compiler/nir/nir_lower_blend.c
@@ -225,37 +225,37 @@ static nir_ssa_def *
 nir_logicop_func(
    nir_builder *b,
    unsigned func,
-   nir_ssa_def *src, nir_ssa_def *dst)
+   nir_ssa_def *src, nir_ssa_def *dst, nir_ssa_def *bitmask)
 {
    switch (func) {
    case PIPE_LOGICOP_CLEAR:
       return nir_imm_ivec4(b, 0, 0, 0, 0);
    case PIPE_LOGICOP_NOR:
-      return nir_inot(b, nir_ior(b, src, dst));
+      return nir_ixor(b, nir_ior(b, src, dst), bitmask);
    case PIPE_LOGICOP_AND_INVERTED:
-      return nir_iand(b, nir_inot(b, src), dst);
+      return nir_iand(b, nir_ixor(b, src, bitmask), dst);
    case PIPE_LOGICOP_COPY_INVERTED:
-      return nir_inot(b, src);
+      return nir_ixor(b, src, bitmask);
    case PIPE_LOGICOP_AND_REVERSE:
-      return nir_iand(b, src, nir_inot(b, dst));
+      return nir_iand(b, src, nir_ixor(b, dst, bitmask));
    case PIPE_LOGICOP_INVERT:
-      return nir_inot(b, dst);
+      return nir_ixor(b, dst, bitmask);
    case PIPE_LOGICOP_XOR:
       return nir_ixor(b, src, dst);
    case PIPE_LOGICOP_NAND:
-      return nir_inot(b, nir_iand(b, src, dst));
+      return nir_ixor(b, nir_iand(b, src, dst), bitmask);
    case PIPE_LOGICOP_AND:
       return nir_iand(b, src, dst);
    case PIPE_LOGICOP_EQUIV:
-      return nir_inot(b, nir_ixor(b, src, dst));
+      return nir_ixor(b, nir_ixor(b, src, dst), bitmask);
    case PIPE_LOGICOP_NOOP:
       return dst;
    case PIPE_LOGICOP_OR_INVERTED:
-      return nir_ior(b, nir_inot(b, src), dst);
+      return nir_ior(b, nir_ixor(b, src, bitmask), dst);
    case PIPE_LOGICOP_COPY:
       return src;
    case PIPE_LOGICOP_OR_REVERSE:
-      return nir_ior(b, src, nir_inot(b, dst));
+      return nir_ior(b, src, nir_ixor(b, dst, bitmask));
    case PIPE_LOGICOP_OR:
       return nir_ior(b, src, dst);
    case PIPE_LOGICOP_SET:
@@ -300,15 +300,12 @@ nir_blend_logicop(
       assert(util_format_is_pure_integer(format));
    }
 
-   nir_ssa_def *out = nir_logicop_func(b, options->logicop_func, src, dst);
-
-   if (bits[0] < 32) {
-       nir_const_value mask[4];
-       for (int i = 0; i < 4; ++i)
-           mask[i] = nir_const_value_for_int((1u << bits[i]) - 1, 32);
+   nir_const_value mask[4];
+   for (int i = 0; i < 4; ++i)
+      mask[i] = nir_const_value_for_int(BITFIELD_MASK(bits[i]), 32);
 
-       out = nir_iand(b, out, nir_build_imm(b, 4, 32, mask));
-   }
+   nir_ssa_def *out = nir_logicop_func(b, options->logicop_func, src, dst,
+                                       nir_build_imm(b, 4, 32, mask));
 
    if (util_format_is_unorm(format)) {
       out = nir_format_unorm_to_float(b, out, bits);

Reply via email to