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@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12320>
This commit is contained in:
parent
1ce48ce91d
commit
0cf25f559f
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue