From 19222867e43679885533c08004c0c003c44748c3 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 15 Feb 2022 09:24:14 -0800 Subject: [PATCH] nir/algebraic: Reassociate some iand to eliminate an operation MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit No shader-db changes on any Intel platform. All of the helped shaders were presumably regressed by 4676b3d3dd9 (nir: Use nir_test_mask instead of i2b(iand)). v2: Add some comments explaining why specific replacements are used. In the umin pattern, only markup the first usage of 'b' in the source pattern. Tiger Lake, Ice Lake, and Skylake had similar results. (Ice Lake shown) Instructions in all programs: 141384970 -> 141200966 (-0.1%) Instructions helped: 45842 Cycles in all programs: 9133648977 -> 9133282672 (-0.0%) Cycles helped: 26812 Cycles hurt: 6025 Gained: 23 Lost: 135 Acked-by: Jesse Natalie Acked-by: Alyssa Rosenzweig Tested-by: Daniel Schürmann Part-of: --- src/compiler/nir/nir_opt_algebraic.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/compiler/nir/nir_opt_algebraic.py b/src/compiler/nir/nir_opt_algebraic.py index edade80..77fa16b 100644 --- a/src/compiler/nir/nir_opt_algebraic.py +++ b/src/compiler/nir/nir_opt_algebraic.py @@ -897,6 +897,10 @@ optimizations.extend([ # This is how SpvOpFOrdNotEqual might be implemented. If both values are # numbers, then it can be replaced with fneu. (('ior', ('flt', 'a(is_a_number)', 'b(is_a_number)'), ('flt', b, a)), ('fneu', a, b)), + + # Other patterns may optimize the resulting iand tree further. + (('umin', ('iand', a, '#b(is_pos_power_of_two)'), ('iand', c, b)), + ('iand', ('iand', a, b), ('iand', c, b))), ]) # Float sizes @@ -1265,6 +1269,12 @@ optimizations.extend([ (('iand', ('ior', a, b), b), b), (('iand', ('iand', a, b), b), ('iand', a, b)), + # It is common for sequences of (x & 1) to occur in large trees. Replacing + # an expression like ((a & 1) & (b & 1)) with ((a & b) & 1) allows the "& + # 1" to eventually bubble up to the top of the tree. + (('iand', ('iand(is_used_once)', a, b), ('iand(is_used_once)', a, c)), + ('iand', a, ('iand', b, c))), + (('iand@64', a, '#b(is_lower_half_zero)'), ('pack_64_2x32_split', 0, ('iand', ('unpack_64_2x32_split_y', a), ('unpack_64_2x32_split_y', b)))), -- 2.7.4