i965/fs: Don't double-accept operands of logical and/or/xor operations.
If the argument to emit_bool_to_cond_code() is an ir_expression, we
loop over the operands, calling accept() on each of them, which
generates assembly code to compute that subexpression. We then emit
one or two final instruction that perform the top-level operation on
those operands.
If it's not an expression (say, a boolean-valued variable), we simply
call accept() on the whole value.
In commit 80ecb8f1
(i965/fs: Avoid generating extra AND instructions on
bool logic ops), Eric made logic operations jump out of the expression
path to the non-expression path.
Unfortunately, this meant that we would first accept() the two operands,
skip generating any code that used them, then accept() the whole
expression, generating code for the operands a second time.
Dead code elimination would always remove the first set of redundant
operand assembly, since nothing actually used them. But we shouldn't
generate it in the first place.
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Matt Turner <mattst88@gmail.com>
This commit is contained in:
parent
e5c49bc25b
commit
aac75f877d
|
@ -1724,7 +1724,10 @@ fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
|
|||
{
|
||||
ir_expression *expr = ir->as_expression();
|
||||
|
||||
if (expr) {
|
||||
if (expr &&
|
||||
expr->operation != ir_binop_logic_and &&
|
||||
expr->operation != ir_binop_logic_or &&
|
||||
expr->operation != ir_binop_logic_xor) {
|
||||
fs_reg op[2];
|
||||
fs_inst *inst;
|
||||
|
||||
|
@ -1744,11 +1747,6 @@ fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
|
|||
inst->conditional_mod = BRW_CONDITIONAL_Z;
|
||||
break;
|
||||
|
||||
case ir_binop_logic_xor:
|
||||
case ir_binop_logic_or:
|
||||
case ir_binop_logic_and:
|
||||
goto out;
|
||||
|
||||
case ir_unop_f2b:
|
||||
if (brw->gen >= 6) {
|
||||
emit(CMP(reg_null_d, op[0], fs_reg(0.0f), BRW_CONDITIONAL_NZ));
|
||||
|
@ -1790,7 +1788,6 @@ fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
|
|||
return;
|
||||
}
|
||||
|
||||
out:
|
||||
ir->accept(this);
|
||||
|
||||
fs_inst *inst = emit(AND(reg_null_d, this->result, fs_reg(1)));
|
||||
|
|
Loading…
Reference in New Issue