diff --git a/src/intel/compiler/brw/brw_opt_cmod_propagation.cpp b/src/intel/compiler/brw/brw_opt_cmod_propagation.cpp index 496379fa8a8..0f66f379dbd 100644 --- a/src/intel/compiler/brw/brw_opt_cmod_propagation.cpp +++ b/src/intel/compiler/brw/brw_opt_cmod_propagation.cpp @@ -99,6 +99,17 @@ cmod_propagate_cmp_to_add(const intel_device_info *devinfo, brw_inst *inst) } foreach_inst_in_block_reverse_starting_from(brw_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(devinfo, 0)) || + regions_overlap(scan_inst->dst, scan_inst->size_written, + inst->src[1], inst->size_read(devinfo, 1))) { + break; + } + if (scan_inst->opcode == BRW_OPCODE_ADD && !scan_inst->predicate && scan_inst->dst.is_contiguous() && diff --git a/src/intel/compiler/brw/test_opt_cmod_propagation.cpp b/src/intel/compiler/brw/test_opt_cmod_propagation.cpp index c18b3f663eb..93d891be10e 100644 --- a/src/intel/compiler/brw/test_opt_cmod_propagation.cpp +++ b/src/intel/compiler/brw/test_opt_cmod_propagation.cpp @@ -693,6 +693,27 @@ TEST_F(cmod_propagation_test, subtract_delete_compare) EXPECT_SHADERS_MATCH(bld, exp); } +TEST_F(cmod_propagation_test, subtract_no_delete_compare_write_between) +{ + brw_builder bld = make_shader(); + brw_reg dest = vgrf(bld, BRW_TYPE_F); + brw_reg src0 = vgrf(bld, BRW_TYPE_F); + + set_condmod(BRW_CONDITIONAL_L, bld.ADD(dest, src0, brw_imm_f(-1.0f))); + bld.MOV(src0, brw_imm_f(5.0)); + bld.CMP(bld.null_reg_f(), src0, brw_imm_f(1.0f), BRW_CONDITIONAL_L); + + /* = Before = + * 0: add.l.f0(8) dest0:F src0:F -1.0:F + * 1: mov(0) src0:F 5.0:F + * 2: cmp.l.f0(8) null:F src0:F 1.0:F + * + * = After = + * No changes. + */ + EXPECT_NO_PROGRESS(brw_opt_cmod_propagation, bld); +} + TEST_F(cmod_propagation_test, subtract_delete_compare_other_flag) { /* This test is the same as subtract_delete_compare but it explicitly used