<div dir="ltr"><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Apr 25, 2019 at 5:37 PM Alyssa Rosenzweig <<a href="mailto:alyssa@rosenzweig.io">alyssa@rosenzweig.io</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">In addition to the familiar iand/ior/ixor, some architectures feature<br>
destination-inverted versions inand/inor/inxor. Certain<br>
architectures also have source-inverted forms, dubbed iandnot/iornot<br>
here. Midgard has the all of these opcodes natively. Many arches have<br>
comparible features to implement some/all of the above. Paired with De<br>
Morgan's Laws, these opcodes allow anything of the form<br>
"~? (~?a [&|] ~?b)" to complete in one instruction.<br>
<br>
This can be used to simplify some backend-specific code on affected<br>
architectures, e.f. 8eb36c91 ("intel/fs: Emit logical-not of operands on<br>
Gen8+").<br>
<br>
Signed-off-by: Alyssa Rosenzweig <<a href="mailto:alyssa@rosenzweig.io" target="_blank">alyssa@rosenzweig.io</a>><br>
Cc: Ian Romanick <<a href="mailto:ian.d.romanick@intel.com" target="_blank">ian.d.romanick@intel.com</a>><br>
Cc: Kenneth Graunke <<a href="mailto:kenneth@whitecape.org" target="_blank">kenneth@whitecape.org</a>><br>
---<br>
 src/compiler/nir/nir.h                |  4 ++++<br>
 src/compiler/nir/nir_opcodes.py       | 18 ++++++++++++++++++<br>
 src/compiler/nir/nir_opt_algebraic.py | 12 ++++++++++++<br>
 3 files changed, 34 insertions(+)<br>
<br>
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h<br>
index e878a63409d..3e01ec2cc06 100644<br>
--- a/src/compiler/nir/nir.h<br>
+++ b/src/compiler/nir/nir.h<br>
@@ -2318,6 +2318,10 @@ typedef struct nir_shader_compiler_options {<br>
    bool lower_hadd;<br>
    bool lower_add_sat;<br>
<br>
+   /* Set if inand/inor/inxor and iandnot/iornot supported respectively */<br>
+   bool bitwise_dest_invertable;<br>
+   bool bitwise_src_invertable;<br></blockquote><div><br></div><div>Do we really need two booleans?  Commentary on that below....<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
    /**<br>
     * Should nir_lower_io() create load_interpolated_input intrinsics?<br>
     *<br>
diff --git a/src/compiler/nir/nir_opcodes.py b/src/compiler/nir/nir_opcodes.py<br>
index d35d820aa5b..f9d92afb53e 100644<br>
--- a/src/compiler/nir/nir_opcodes.py<br>
+++ b/src/compiler/nir/nir_opcodes.py<br>
@@ -690,6 +690,24 @@ binop("iand", tuint, commutative + associative, "src0 & src1")<br>
 binop("ior", tuint, commutative + associative, "src0 | src1")<br>
 binop("ixor", tuint, commutative + associative, "src0 ^ src1")<br>
<br>
+# inverted bitwise logic operators<br>
+#<br>
+# These variants of the above include bitwise NOTs either on the result of the<br>
+# whole expression or on the latter operand. On some hardware (e.g. Midgard),<br>
+# these are native ops. On other hardware (e.g. Intel Gen8+), these can be<br>
+# implemented as modifiers of the standard three. Along with appropriate<br>
+# algebraic passes, these should permit any permutation of inverses on AND/OR<br>
+# to execute in a single cycle. For example, ~(a & ~b) = ~(~(~a | ~(~b))) = ~a<br>
+# | b = b | ~a = iornot(b, a).<br>
+<br>
+binop("inand", tuint, commutative, "~(src0 & src1)")<br>
+binop("inor", tuint, commutative, "~(src0 | src1)")<br>
+binop("inxor", tuint, commutative, "~(src0 ^ src1)")<br></blockquote><div><br></div><div>We can support all of these with source modifiers because the above three aren't really "dest invertable"...  For us, they'd be</div><div><br></div><div>~src0 | ~src1</div><div>~src0 & ~src1</div><div>~src0 ^ ~src1</div><div><br></div><div>Is it really dest_invertable or both_srcs_invertable? :-)</div><div><br></div><div>Also worth noting that I've considered adding a not modifier to NIR (if source modifiers are a thing we actually want at that level).  Over-all, I'm a little uncertain if these need to be their own ops or not...</div><div><br></div><div>--Jason<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+binop("iandnot", tuint, "", "src0 & (~src1)")<br>
+binop("iornot", tuint, "", "src0 & (~src1)")<br>
+<br>
+<br>
+<br>
<br>
 # floating point logic operators<br>
 #<br>
diff --git a/src/compiler/nir/nir_opt_algebraic.py b/src/compiler/nir/nir_opt_algebraic.py<br>
index dad0545594f..6cb3e8cb950 100644<br>
--- a/src/compiler/nir/nir_opt_algebraic.py<br>
+++ b/src/compiler/nir/nir_opt_algebraic.py<br>
@@ -1052,6 +1052,18 @@ late_optimizations = [<br>
    (('fmax', ('fadd(is_used_once)', '#c', a), ('fadd(is_used_once)', '#c', b)), ('fadd', c, ('fmax', a, b))),<br>
<br>
    (('bcsel', a, 0, ('b2f32', ('inot', 'b@bool'))), ('b2f32', ('inot', ('ior', a, b)))),<br>
+<br>
+   # We don't want to deal with inverted forms, so run this late. Any<br>
+   # combination of inverts on flags or output should result in a single<br>
+   # instruction if these are supported; cases not explicitly handled would<br>
+   # have been simplified via De Morgan's Law<br>
+   (('inot', ('iand', a, b)), ('inand', a, b), 'options->bitwise_dest_invertable'),<br>
+   (('inot', ('ior', a, b)), ('inor', a, b), 'options->bitwise_dest_invertable'),<br>
+   (('inot', ('ixor', a, b)), ('inxor', a, b), 'options->bitwise_dest_invertable'),<br>
+   (('iand', ('inot', a), b), ('iandnot', b, a), 'options->bitwise_src_invertable'),<br>
+   (('iand', a, ('inot', b)), ('iandnot', a, b), 'options->bitwise_src_invertable'),<br>
+   (('ior', a, ('inot', b)), ('iornot', a, b), 'options->bitwise_src_invertable'),<br>
+   (('ior', ('inot', a), b), ('iornot', b, a), 'options->bitwise_src_invertable'),<br>
 ]<br>
<br>
 print(nir_algebraic.AlgebraicPass("nir_opt_algebraic", optimizations).render())<br>
-- <br>
2.20.1<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a></blockquote></div></div>