i965/fs: Allow flipping cond mod for negated arguments.

This allows us to apply the optimization in cases where the CMP's
argument is negated, by flipping the conditional mod. For example, it
allows us to optimize this:

   add(8)       temp   a      b
   cmp.l.f0(8)  null   -temp  0.0

into

   add.g.f0(8)  temp   a      b

total instructions in shared programs: 5958360 -> 5955701 (-0.04%)
instructions in affected programs:     466880 -> 464221 (-0.57%)
GAINED:                                0
LOST:                                  1

Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
Matt Turner
2014-12-30 12:18:57 -08:00
parent d6317beb46
commit 9a3a294224
2 changed files with 39 additions and 3 deletions
@@ -62,7 +62,6 @@ opt_cmod_propagation_local(fs_visitor *v, bblock_t *block)
!inst->dst.is_null() ||
inst->src[0].file != GRF ||
inst->src[0].abs ||
inst->src[0].negate ||
!inst->src[1].is_zero())
continue;
@@ -74,10 +73,14 @@ opt_cmod_propagation_local(fs_visitor *v, bblock_t *block)
scan_inst->dst.reg_offset != inst->src[0].reg_offset)
break;
enum brw_conditional_mod cond =
inst->src[0].negate ? brw_swap_cmod(inst->conditional_mod)
: inst->conditional_mod;
if (scan_inst->can_do_cmod() &&
((!read_flag && scan_inst->conditional_mod == BRW_CONDITIONAL_NONE) ||
scan_inst->conditional_mod == inst->conditional_mod)) {
scan_inst->conditional_mod = inst->conditional_mod;
scan_inst->conditional_mod == cond)) {
scan_inst->conditional_mod = cond;
inst->remove(block);
progress = true;
}
@@ -350,3 +350,36 @@ TEST_F(cmod_propagation_test, intervening_flag_read_same_value)
EXPECT_EQ(BRW_OPCODE_SEL, instruction(block0, 1)->opcode);
EXPECT_EQ(BRW_PREDICATE_NORMAL, instruction(block0, 1)->predicate);
}
TEST_F(cmod_propagation_test, negate)
{
fs_reg dest = v->vgrf(glsl_type::float_type);
fs_reg src0 = v->vgrf(glsl_type::float_type);
fs_reg src1 = v->vgrf(glsl_type::float_type);
fs_reg zero(0.0f);
v->emit(BRW_OPCODE_ADD, dest, src0, src1);
dest.negate = true;
v->emit(BRW_OPCODE_CMP, v->reg_null_f, dest, zero)
->conditional_mod = BRW_CONDITIONAL_GE;
/* = Before =
*
* 0: add(8) dest src0 src1
* 1: cmp.ge.f0(8) null -dest 0.0f
*
* = After =
* 0: add.le.f0(8) dest src0 src1
*/
v->calculate_cfg();
bblock_t *block0 = v->cfg->blocks[0];
EXPECT_EQ(0, block0->start_ip);
EXPECT_EQ(1, block0->end_ip);
EXPECT_TRUE(cmod_propagation(v));
EXPECT_EQ(0, block0->start_ip);
EXPECT_EQ(0, block0->end_ip);
EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
EXPECT_EQ(BRW_CONDITIONAL_LE, instruction(block0, 0)->conditional_mod);
}