i965: Implement b2f and b2i using negation.
authorFrancisco Jerez <currojerez@riseup.net>
Fri, 10 Jul 2015 16:18:39 +0000 (19:18 +0300)
committerFrancisco Jerez <currojerez@riseup.net>
Thu, 16 Jul 2015 15:29:32 +0000 (18:29 +0300)
Booleans are represented as 0/-1 on modern hardware which means we can
just negate them to convert them into a numeric type.  Negation has
the benefit that it can be implemented using a source modifier which
can easily be propagated into some other instruction.  shader-db
results on HSW:

total instructions in shared programs: 6349082 -> 6346693 (-0.04%)
instructions in affected programs:     40948 -> 38559 (-5.83%)
helped:                                123
HURT:                                  1
GAINED:                                1
LOST:                                  0

Reviewed-by: Matt Turner <mattst88@gmail.com>
src/mesa/drivers/dri/i965/brw_fs_nir.cpp
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp

index 10903a11c31b6cfc489b03dde165c1a69db68284..198703281e6bf840b337a7bb0bfe6e162b20fa57 100644 (file)
@@ -968,10 +968,8 @@ fs_visitor::nir_emit_alu(const fs_builder &bld, nir_alu_instr *instr)
       break;
 
    case nir_op_b2i:
-      bld.AND(result, op[0], fs_reg(1));
-      break;
    case nir_op_b2f:
-      bld.AND(retype(result, BRW_REGISTER_TYPE_UD), op[0], fs_reg(0x3f800000u));
+      bld.MOV(result, negate(op[0]));
       break;
 
    case nir_op_f2b:
index 67f2b5c29ff420ab944b353b1e518e3e2ddd3eb6..8a352d33e2fe3b7947089d0c1d3b6c22d661902a 100644 (file)
@@ -1733,16 +1733,11 @@ vec4_visitor::visit(ir_expression *ir)
       emit(MOV(result_dst, op[0]));
       break;
    case ir_unop_b2i:
-      emit(AND(result_dst, op[0], src_reg(1)));
-      break;
    case ir_unop_b2f:
       if (devinfo->gen <= 5) {
          resolve_bool_comparison(ir->operands[0], &op[0]);
       }
-      op[0].type = BRW_REGISTER_TYPE_D;
-      result_dst.type = BRW_REGISTER_TYPE_D;
-      emit(AND(result_dst, op[0], src_reg(0x3f800000u)));
-      result_dst.type = BRW_REGISTER_TYPE_F;
+      emit(MOV(result_dst, negate(op[0])));
       break;
    case ir_unop_f2b:
       emit(CMP(result_dst, op[0], src_reg(0.0f), BRW_CONDITIONAL_NZ));