brw/cmod: Don't propagate between instructions in different groups

The group implicity selects which flags the instruction can write. This
was discovered while working on another set of changes that could change
some logical operations into predicated MOV instructions.

Prevents regressions later in the series in
dEQP-VK.graphicsfuzz.cov-loop-fragcoord-identical-condition.

No shader-db or fossil-db changes on any Intel platform.

v2: Update the comment in the test case. Suggested by Caio.

Fixes: 95ac3b1dae ("i965/fs: don't propagate cmod when the exec sizes differ")
Reviewed-by: Caio Oliveira <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38315>
This commit is contained in:
Ian Romanick 2025-11-12 16:57:30 -08:00
parent c0fb93506b
commit ba30794847
2 changed files with 24 additions and 2 deletions

View file

@ -120,7 +120,8 @@ cmod_propagate_cmp_to_add(const intel_device_info *devinfo, brw_inst *inst)
if (scan_inst->opcode == BRW_OPCODE_ADD &&
!scan_inst->predicate &&
scan_inst->dst.is_contiguous() &&
scan_inst->exec_size == inst->exec_size) {
scan_inst->exec_size == inst->exec_size &&
scan_inst->group == inst->group) {
bool negate;
/* A CMP is basically a subtraction. The result of the
@ -295,7 +296,8 @@ opt_cmod_propagation_local(const intel_device_info *devinfo, bblock_t *block)
if (scan_inst->predicate ||
!scan_inst->dst.is_contiguous() ||
scan_inst->dst.offset != inst->src[0].offset ||
scan_inst->exec_size != inst->exec_size)
scan_inst->exec_size != inst->exec_size ||
scan_inst->group != inst->group)
break;
/* If the write mask is different we can't propagate. */

View file

@ -2589,3 +2589,23 @@ TEST_F(cmod_propagation_test, BFN_G_CMP_D_G)
EXPECT_SHADERS_MATCH(bld, exp);
}
TEST_F(cmod_propagation_test, different_group)
{
unsigned width = devinfo->ver >= 20 ? 32 : 16;
brw_builder bld = make_shader(MESA_SHADER_FRAGMENT, width);
brw_reg src0 = vgrf(bld, BRW_TYPE_UD);
brw_reg src1 = vgrf(bld, BRW_TYPE_UD);
/* Propagation should not happen. The second instructions writes the second
* half of the flags. Propagating that to the first instruction would
* incorrectly cause it to write the first half of the flags.
*/
bld.group(width / 2, 1).MOV(src1, retype(src0, BRW_TYPE_D));
bld.group(width / 2, 0).MOV(bld.null_reg_d(), src1)
->conditional_mod = BRW_CONDITIONAL_NZ;
EXPECT_NO_PROGRESS(brw_opt_cmod_propagation, bld);
}