brw/algebraic: Don't optimize float SEL.CMOD to MOV

Floating point SEL.CMOD may flush denorms to zero. We don't have enough
information at this point in compilation to know whether or not it is
safe to remove that.

Integer SEL or SEL without a conditional modifier is just a fancy
MOV. Those are always safe to eliminate.

See also 3f782cdd25.

Fixes: fab92fa1cb ("i965/fs: Optimize SEL with the same sources into a MOV.")

No shader-db changes on any Intel platform.

fossil-db:

All Intel platforms had similar results. (Lunar Lake shown)
Totals:
Instrs: 209903490 -> 209903492 (+0.00%)
Cycle count: 30546025224 -> 30546021980 (-0.00%); split: -0.00%, +0.00%
Max live registers: 65516231 -> 65516235 (+0.00%)

Totals from 2 (0.00% of 706657) affected shaders:
Instrs: 3197 -> 3199 (+0.06%)
Cycle count: 361650 -> 358406 (-0.90%); split: -10.05%, +9.15%
Max live registers: 300 -> 304 (+1.33%)

Reviewed-by: Ivan Briano <ivan.briano@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34192>
This commit is contained in:
Ian Romanick 2025-03-10 11:37:50 -07:00 committed by Marge Bot
parent 07dc1d4043
commit 6a19d8915f
2 changed files with 44 additions and 1 deletions

View file

@ -546,7 +546,16 @@ brw_opt_algebraic(brw_shader &s)
}
break;
case BRW_OPCODE_SEL:
if (inst->src[0].equals(inst->src[1])) {
/* Floating point SEL.CMOD may flush denorms to zero. We don't have
* enough information at this point in compilation to know whether or
* not it is safe to remove that.
*
* Integer SEL or SEL without a conditional modifier is just a fancy
* MOV. Those are always safe to eliminate.
*/
if (inst->src[0].equals(inst->src[1]) &&
(!brw_type_is_float(inst->dst.type) ||
inst->conditional_mod == BRW_CONDITIONAL_NONE)) {
inst->opcode = BRW_OPCODE_MOV;
inst->predicate = BRW_PREDICATE_NONE;
inst->predicate_inverse = false;

View file

@ -24,3 +24,37 @@ TEST_F(algebraic_test, imax_a_a)
EXPECT_SHADERS_MATCH(bld, exp);
}
TEST_F(algebraic_test, sel_a_a)
{
brw_builder bld = make_shader(MESA_SHADER_FRAGMENT, 16);
brw_builder exp = make_shader(MESA_SHADER_FRAGMENT, 16);
brw_reg dst0 = vgrf(bld, exp, BRW_TYPE_D);
brw_reg src0 = vgrf(bld, exp, BRW_TYPE_D);
bld.SEL(dst0, src0, src0)
->predicate = BRW_PREDICATE_NORMAL;
EXPECT_PROGRESS(brw_opt_algebraic, bld);
exp.MOV(dst0, src0);
EXPECT_SHADERS_MATCH(bld, exp);
}
TEST_F(algebraic_test, fmax_a_a)
{
brw_builder bld = make_shader(MESA_SHADER_FRAGMENT, 16);
brw_reg dst0 = vgrf(bld, BRW_TYPE_F);
brw_reg src0 = vgrf(bld, BRW_TYPE_F);
bld.emit_minmax(dst0, src0, src0, BRW_CONDITIONAL_GE);
/* SEL.GE may flush denorms to zero. We don't have enough information at
* this point in compilation to know whether or not it is safe to remove
* that.
*/
EXPECT_NO_PROGRESS(brw_opt_algebraic, bld);
}