summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Turner <[email protected]>2014-12-30 12:18:57 -0800
committerMatt Turner <[email protected]>2015-01-23 17:57:40 -0800
commit9a3a2942240065d85e197e04d9612af696b9ea99 (patch)
tree553b89976da6f065c5edc401cd5d3aaff00a2799
parentd6317beb463e1e362562fd0353a99b4b080c136c (diff)
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 <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_cmod_propagation.cpp9
-rw-r--r--src/mesa/drivers/dri/i965/test_fs_cmod_propagation.cpp33
2 files changed, 39 insertions, 3 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_cmod_propagation.cpp b/src/mesa/drivers/dri/i965/brw_fs_cmod_propagation.cpp
index c8eb3a4f8be..8a03315bc4c 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_cmod_propagation.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_cmod_propagation.cpp
@@ -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;
}
diff --git a/src/mesa/drivers/dri/i965/test_fs_cmod_propagation.cpp b/src/mesa/drivers/dri/i965/test_fs_cmod_propagation.cpp
index 95d335d9543..fefe515a216 100644
--- a/src/mesa/drivers/dri/i965/test_fs_cmod_propagation.cpp
+++ b/src/mesa/drivers/dri/i965/test_fs_cmod_propagation.cpp
@@ -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);
+}