Mesa (main): spirv: Generate shorter code for SpvOpFUnord comparisons
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Oct 6 02:17:30 UTC 2021
Module: Mesa
Branch: main
Commit: 0cf25f559f8dc99d59637e74650c38d6428433f3
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=0cf25f559f8dc99d59637e74650c38d6428433f3
Author: Ian Romanick <ian.d.romanick at intel.com>
Date: Thu Mar 11 09:46:07 2021 -0800
spirv: Generate shorter code for SpvOpFUnord comparisons
No shader-db or fossil-db changes on any Intel platform.
v2: Keep the flt <-> fge switcharoo local to the SpvOpFUnordLessThan,
etc. handling. Add a comment explaining why the suboptimal
SpvOpFUnordEqual implementation is used here. Suggested by Caio.
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira at intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12320>
---
src/compiler/spirv/vtn_alu.c | 38 ++++++++++++++++++++++++++++++++------
1 file changed, 32 insertions(+), 6 deletions(-)
diff --git a/src/compiler/spirv/vtn_alu.c b/src/compiler/spirv/vtn_alu.c
index 54019c37396..a9bdb4c3cf1 100644
--- a/src/compiler/spirv/vtn_alu.c
+++ b/src/compiler/spirv/vtn_alu.c
@@ -600,7 +600,29 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
break;
}
- case SpvOpFUnordEqual:
+ case SpvOpFUnordEqual: {
+ const bool save_exact = b->nb.exact;
+
+ b->nb.exact = true;
+
+ /* This could also be implemented as !(a < b || b < a). If one or both
+ * of the source are numbers, later optimization passes can easily
+ * eliminate the isnan() checks. This may trim the sequence down to a
+ * single (a == b) operation. Otherwise, the optimizer can transform
+ * whatever is left to !(a < b || b < a). Since some applications will
+ * open-code this sequence, these optimizations are needed anyway.
+ */
+ dest->def =
+ nir_ior(&b->nb,
+ nir_feq(&b->nb, src[0], src[1]),
+ nir_ior(&b->nb,
+ nir_fneu(&b->nb, src[0], src[0]),
+ nir_fneu(&b->nb, src[1], src[1])));
+
+ b->nb.exact = save_exact;
+ break;
+ }
+
case SpvOpFUnordLessThan:
case SpvOpFUnordGreaterThan:
case SpvOpFUnordLessThanEqual:
@@ -623,12 +645,16 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
b->nb.exact = true;
+ /* Use the property FUnordLessThan(a, b) ≡ !FOrdGreaterThanEqual(a, b). */
+ switch (op) {
+ case nir_op_fge: op = nir_op_flt; break;
+ case nir_op_flt: op = nir_op_fge; break;
+ default: unreachable("Impossible opcode.");
+ }
+
dest->def =
- nir_ior(&b->nb,
- nir_build_alu(&b->nb, op, src[0], src[1], NULL, NULL),
- nir_ior(&b->nb,
- nir_fneu(&b->nb, src[0], src[0]),
- nir_fneu(&b->nb, src[1], src[1])));
+ nir_inot(&b->nb,
+ nir_build_alu(&b->nb, op, src[0], src[1], NULL, NULL));
b->nb.exact = save_exact;
break;
More information about the mesa-commit
mailing list