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>
(cherry picked from commit ba30794847)
This commit is contained in:
Ian Romanick 2025-11-12 16:57:30 -08:00 committed by Dylan Baker
parent 4b1bd74165
commit fe2f91e005
3 changed files with 25 additions and 3 deletions

View file

@ -584,7 +584,7 @@
"description": "brw/cmod: Don't propagate between instructions in different groups",
"nominated": true,
"nomination_type": 2,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "95ac3b1daeaa7d40d49fa2e0bdef46346c2996d5",
"notes": null

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

@ -2615,3 +2615,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);
}