nir/algebraic: support float controls conditions per instruction

v?:
 - Make the Python not awful (Dylan)

Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27281>
This commit is contained in:
Iván Briano 2024-02-12 17:20:34 -08:00 committed by Marge Bot
parent 08df0c7dde
commit 8c4cd3e74e
4 changed files with 39 additions and 9 deletions

View file

@ -205,6 +205,9 @@ class Value(object):
${'true' if val.inexact else 'false'},
${'true' if val.exact else 'false'},
${'true' if val.ignore_exact else 'false'},
${'true' if val.nsz else 'false'},
${'true' if val.nnan else 'false'},
${'true' if val.ninf else 'false'},
${val.c_opcode()},
${val.comm_expr_idx}, ${val.comm_exprs},
{ ${', '.join(src.array_index for src in val.sources)} },
@ -377,16 +380,15 @@ class Expression(Value):
# "many-comm-expr" isn't really a condition. It's notification to the
# generator that this pattern is known to have too many commutative
# expressions, and an error should not be generated for this case.
self.many_commutative_expressions = False
if self.cond and self.cond.find("many-comm-expr") >= 0:
# Split the condition into a comma-separated list. Remove
# "many-comm-expr". If there is anything left, put it back together.
c = self.cond[1:-1].split(",")
c.remove("many-comm-expr")
assert(len(c) <= 1)
# nsz, nnan and ninf are special conditions, so we treat them specially too.
cond = {k: True for k in self.cond[1:-1].split(",")} if self.cond else {}
self.many_commutative_expressions = cond.pop('many-comm-expr', False)
self.nsz = cond.pop('nsz', False)
self.nnan = cond.pop('nnan', False)
self.ninf = cond.pop('ninf', False)
self.cond = c[0] if c else None
self.many_commutative_expressions = True
assert len(cond) <= 1
self.cond = cond.popitem()[0] if cond else None
# Deduplicate references to the condition functions for the expressions
# and save the index for the order they were added.

View file

@ -91,6 +91,16 @@ ignore_exact = nir_algebraic.ignore_exact
# than nir_replace_instr can handle. If this special condition is needed with
# another condition, the two can be separated by a comma (e.g.,
# "(many-comm-expr,is_used_once)").
#
# Another set of special "conditions" are
# "nsz": sign of zero is not preserved
# "ninf": infinities are not preserved
# "nnan": nan is not preserved
# These relate to the float controls/fpfastmath and more descriptions of the
# expression than conditions. That is, an expression with the "nsz" condition
# means that the replacement expression won't preserve the sign of zero of the
# result, and so it will be skipped if the matching instruction has the
# 'signed_zero_preserve' flag set.
# based on https://web.archive.org/web/20180105155939/http://forum.devmaster.net/t/fast-and-accurate-sine-cosine/9648
def lowered_sincos(c):

View file

@ -370,6 +370,15 @@ match_expression(const nir_algebraic_table *table, const nir_search_expression *
if (expr->cond_index != -1 && !table->expression_cond[expr->cond_index](instr))
return false;
if (expr->nsz && nir_is_float_control_signed_zero_preserve(instr->fp_fast_math, instr->def.bit_size))
return false;
if (expr->nnan && nir_is_float_control_nan_preserve(instr->fp_fast_math, instr->def.bit_size))
return false;
if (expr->ninf && nir_is_float_control_inf_preserve(instr->fp_fast_math, instr->def.bit_size))
return false;
if (!nir_op_matches_search_op(instr->op, expr->opcode))
return false;

View file

@ -139,6 +139,15 @@ typedef struct {
/** Don't make the replacement exact if the search expression is exact. */
bool ignore_exact : 1;
/** Replacement does not preserve signed of zero. */
bool nsz : 1;
/** Replacement does not preserve NaN. */
bool nnan : 1;
/** Replacement does not preserve infinities. */
bool ninf : 1;
/* One of nir_op or nir_search_op */
uint16_t opcode : 13;