i965/vec4: Generate better code for ir_triop_csel.

Previously, we generated an extra CMP instruction:

   cmp.ge.f0(8)    g6<1>D          g1<0,4,1>F      0F
   cmp.nz.f0(8)    null            g6<4,4,1>D      0D
   (+f0) sel(8)    g5<1>F          g1.4<0,4,1>F    g2<0,4,1>F

The first operand is always a boolean, and we want to predicate the SEL
on that.  Rather than producing a boolean value and comparing it against
zero, we can just produce a condition code in the flag register.

Now we generate:

   cmp.ge.f0(8)    null            g1<0,4,1>F      0F
   (+f0) sel(8)    g5<1>F          g1.4<0,4,1>F    g2<0,4,1>F

No difference in shader-db.

v2: Remember to delete the old code (thanks Matt).

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Matt Turner <mattst88@gmail.com>
This commit is contained in:
Kenneth Graunke
2014-10-15 18:57:07 -07:00
parent f5c3f095b9
commit 6dc6e6e0d9
+15 -3
View File
@@ -1277,6 +1277,20 @@ vec4_visitor::visit(ir_expression *ir)
dst_reg result_dst(this, ir->type);
src_reg result_src(result_dst);
if (ir->operation == ir_triop_csel) {
ir->operands[1]->accept(this);
op[1] = this->result;
ir->operands[2]->accept(this);
op[2] = this->result;
enum brw_predicate predicate;
emit_bool_to_cond_code(ir->operands[0], &predicate);
inst = emit(BRW_OPCODE_SEL, result_dst, op[1], op[2]);
inst->predicate = predicate;
this->result = result_src;
return;
}
for (operand = 0; operand < ir->get_num_operands(); operand++) {
this->result.file = BAD_FILE;
ir->operands[operand]->accept(this);
@@ -1780,9 +1794,7 @@ vec4_visitor::visit(ir_expression *ir)
break;
case ir_triop_csel:
emit(CMP(dst_null_d(), op[0], src_reg(0), BRW_CONDITIONAL_NZ));
inst = emit(BRW_OPCODE_SEL, result_dst, op[1], op[2]);
inst->predicate = BRW_PREDICATE_NORMAL;
unreachable("already handled above");
break;
case ir_triop_bfi: