nir/opt_algebraic: optimize b2f(a) * b

When the multiplication is only used by fadd, it's not a clear win
because of potential fma fusion.

Totals from 8015 (6.99% of 114655) affected shaders:
MaxWaves: 199394 -> 199466 (+0.04%); split: +0.04%, -0.01%
Instrs: 17461518 -> 17451076 (-0.06%); split: -0.10%, +0.04%
CodeSize: 94779552 -> 94769828 (-0.01%); split: -0.07%, +0.06%
VGPRs: 526012 -> 525532 (-0.09%); split: -0.10%, +0.01%
SpillSGPRs: 12466 -> 12517 (+0.41%); split: -0.09%, +0.50%
Latency: 191274766 -> 191297394 (+0.01%); split: -0.03%, +0.04%
InvThroughput: 31465968 -> 31456785 (-0.03%); split: -0.07%, +0.04%
VClause: 312081 -> 312073 (-0.00%); split: -0.10%, +0.09%
SClause: 366914 -> 366906 (-0.00%); split: -0.02%, +0.01%
Copies: 1222482 -> 1221933 (-0.04%); split: -0.20%, +0.15%
Branches: 376651 -> 376577 (-0.02%); split: -0.03%, +0.01%
PreSGPRs: 442974 -> 443240 (+0.06%); split: -0.01%, +0.07%
PreVGPRs: 415964 -> 415668 (-0.07%); split: -0.09%, +0.02%
VALU: 9403517 -> 9393916 (-0.10%); split: -0.12%, +0.02%
SALU: 2799420 -> 2800430 (+0.04%); split: -0.13%, +0.16%
VOPD: 472826 -> 472347 (-0.10%); split: +0.09%, -0.19%

Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40399>
This commit is contained in:
Georg Lehmann 2026-03-13 14:21:26 +01:00 committed by Marge Bot
parent d2b37b667e
commit 643dd510d4
2 changed files with 19 additions and 0 deletions

View file

@ -1623,6 +1623,19 @@ optimizations.extend([
(('iand', 'a@bool16', 1.0), ('b2f', a)),
(('iand', 'a@bool32', 1.0), ('b2f', a)),
# For this optimization, there are a few things to consider:
# The replacement must flush denorms, fcanonicalize/fneg takes care of that.
# For fmul, if b is not finite, b2f(False) * b would need to be NaN.
# If b is negative, b2f(False) * b would be -0.0, not +0.0, hence the nsz.
# For fmulz, if b is -0.0, b2f(True) * b would need to be +0.0, not b.
# So even there nsz is needed.
# When the multiplication is only used by fadd, it's not a clear win
# because of potential fma fusion.
(('fmul(nsz,is_not_only_used_by_fadd)', ('b2f', 'a@1'), 'b(is_finite)'), ('bcsel', a, ('fcanonicalize', b), 0.0)),
(('fmul(nsz,is_not_only_used_by_fadd)', ('fneg', ('b2f', 'a@1')), 'b(is_finite)'), ('bcsel', a, ('fneg', b), 0.0)),
(('fmulz(nsz,is_not_only_used_by_fadd)', ('b2f', 'a@1'), b), ('bcsel', a, ('fcanonicalize', b), 0.0)),
(('fmulz(nsz,is_not_only_used_by_fadd)', ('fneg', ('b2f', 'a@1')), b), ('bcsel', a, ('fneg', b), 0.0)),
# Comparison with the same args. Note that these are only done for the
# float versions when the source must be a number. Generally, NaN cmp NaN
# produces the opposite result of X cmp X. flt is the outlier. NaN < NaN

View file

@ -592,6 +592,12 @@ is_only_used_by_fadd(const nir_alu_instr *instr)
return true;
}
static inline bool
is_not_only_used_by_fadd(const nir_alu_instr *instr)
{
return !is_only_used_by_fadd(instr);
}
static inline bool
is_only_used_by_alu_op(const nir_alu_instr *instr, nir_op op)
{