From bfeb230f9bd4e7078c6625b295ff7da1e3117cb5 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 17 Feb 2026 12:01:18 -0800 Subject: [PATCH] elk/cmod: Don't propagate from CMP to ADD if there is a write between If either source of the CMP is modified before an appropriate ADD is found, the ADD and the CMP will not have the same result. No shader-db changes on any ELK platform. I suspect the problematic cases only occur after scheduling has rearranged instructions. This is likely the reason BRW didn't experience this problem until 09450faf. Fixes: 020b0055e7a ("i965/fs: Propagate conditional modifiers from compares to adds") Reviewed-by: Matt Turner (cherry picked from commit da1fd9786b42671001354c6db68eb9ae4df81dc7) Part-of: --- .pick_status.json | 2 +- src/intel/compiler/elk/elk_fs_cmod_propagation.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.pick_status.json b/.pick_status.json index 8ec7f718adc..cba3b67e406 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -2214,7 +2214,7 @@ "description": "elk/cmod: Don't propagate from CMP to ADD if there is a write between", "nominated": true, "nomination_type": 2, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "020b0055e7a085a6a8c961ad12ce94e58606a1ae", "notes": null diff --git a/src/intel/compiler/elk/elk_fs_cmod_propagation.cpp b/src/intel/compiler/elk/elk_fs_cmod_propagation.cpp index dc5faa23960..7ae70a3a024 100644 --- a/src/intel/compiler/elk/elk_fs_cmod_propagation.cpp +++ b/src/intel/compiler/elk/elk_fs_cmod_propagation.cpp @@ -109,6 +109,17 @@ cmod_propagate_cmp_to_add(const intel_device_info *devinfo, elk_bblock_t *block, } foreach_inst_in_block_reverse_starting_from(elk_fs_inst, scan_inst, inst) { + /* If either of the sources of the CMP is modified, the optimization + * cannot occur. This is the case even if the instruction modifying the + * value is an ADD of the appropriate form. + */ + if (regions_overlap(scan_inst->dst, scan_inst->size_written, + inst->src[0], inst->size_read(0)) || + regions_overlap(scan_inst->dst, scan_inst->size_written, + inst->src[1], inst->size_read(1))) { + break; + } + if (scan_inst->opcode == ELK_OPCODE_ADD && !scan_inst->is_partial_write() && scan_inst->exec_size == inst->exec_size) {