From 042adf3cc5e16890ee97878fff3b726ca4387973 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Mon, 7 Jul 2025 13:01:31 -0400 Subject: [PATCH] nir/opt_algebraic: optimize signed pow in Control used in a post-processing shader which goes 896 instrs -> 749 instrs. In my Control fossil: Totals from 2 (0.63% of 319) affected shaders: Instrs: 2078 -> 1841 (-11.41%) CodeSize: 14540 -> 12800 (-11.97%) ALU: 1779 -> 1626 (-8.60%) FSCIB: 1779 -> 1626 (-8.60%) Uniforms: 370 -> 372 (+0.54%) In radv_fossils, there are affected shaders in Dredge. Totals from 4 (0.01% of 54019) affected shaders: Instrs: 2306 -> 2294 (-0.52%) CodeSize: 16594 -> 16534 (-0.36%) ALU: 2010 -> 2004 (-0.30%) FSCIB: 2010 -> 2004 (-0.30%) Uniforms: 1138 -> 1146 (+0.70%) Signed-off-by: Alyssa Rosenzweig Reviewed-by: Ian Romanick Part-of: --- src/compiler/nir/nir_opt_algebraic.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/compiler/nir/nir_opt_algebraic.py b/src/compiler/nir/nir_opt_algebraic.py index 191e5e09681..0d8d9a9f058 100644 --- a/src/compiler/nir/nir_opt_algebraic.py +++ b/src/compiler/nir/nir_opt_algebraic.py @@ -1146,6 +1146,18 @@ for s in [16, 32, 64]: (('bcsel@{}'.format(s), ('feq', a, 0.0), 1.0, ('i2f{}'.format(s), ('iadd', ('b2i{}'.format(s), ('flt', 0.0, 'a@{}'.format(s))), ('ineg', ('b2i{}'.format(s), ('flt', 'a@{}'.format(s), 0.0)))))), ('i2f{}'.format(s), ('iadd', ('b2i32', ('!fge', a, 0.0)), ('ineg', ('b2i32', ('!flt', a, 0.0)))))), + # Signed pow() used in Control. It's not enough to match just the + # copysign piece because we would require extra instructions to handle + # the various floating point special cases. Specializing to the pow + # sequence lets us collapse all the sign fixup code. + (('fmul', ('fexp2', ('fmul', ('flog2', ('fabs', a)), b)), + ('i2f', ('iadd', ('b2i', ('flt', 0.0, a)), + ('ineg', ('b2i', ('flt', a, 0.0)))))), + + ('bcsel', ('!flt', a, 0.0), + ('fneg', ('fexp2', ('fmul', ('flog2', ('fabs', a)), b))), + ('fexp2', ('fmul', ('flog2', ('fabs', a)), b)))), + (('bcsel', a, ('b2f(is_used_once)', 'b@{}'.format(s)), ('b2f', 'c@{}'.format(s))), ('b2f', ('bcsel', a, b, c))), # The C spec says, "If the value of the integral part cannot be represented