diff options
author | Ian Romanick <ian.d.romanick@intel.com> | 2017-02-09 15:21:47 +0000 |
---|---|---|
committer | Ian Romanick <ian.d.romanick@intel.com> | 2017-02-09 15:25:18 +0000 |
commit | 7e7d26a593d2f2dcb7fe5d9764ea67b2f971f70d (patch) | |
tree | e3d010102ddefe643bbe580123a2af4b9cae1aa4 | |
parent | aa062eb51c8352eac08ec00fbf23ba2736b64adc (diff) |
i965: Use De Morgan's laws to avoid logical-not of a logic result on Gen8+reverse-code-gen
Instead of emitting ~(a & b), emit (~a | ~b) since logical-not of
operands is free on Gen8+.
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp index 2a5f563c24a..7b215e5e5db 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp @@ -1062,6 +1062,43 @@ fs_visitor::nir_emit_alu(const fs_builder &bld, nir_alu_instr *instr) case nir_op_inot: if (devinfo->gen >= 8) { + if (instr->src[0].src.is_ssa && + (instr->src[0].src.ssa->parent_instr->type == nir_instr_type_alu)) { + const nir_alu_instr *alu_parent = + nir_instr_as_alu(instr->src[0].src.ssa->parent_instr); + if ((alu_parent->op == nir_op_ior || + alu_parent->op == nir_op_ixor || + alu_parent->op == nir_op_iand) && + !alu_parent->src[0].abs && + !alu_parent->src[0].negate && + !alu_parent->src[1].abs && + !alu_parent->src[1].negate) { + switch (alu_parent->op) { + case nir_op_ior: + op[0] = get_nir_src(alu_parent->src[0].src); + op[1] = get_nir_src(alu_parent->src[1].src); + op[0].negate = true; + op[1].negate = true; + bld.AND(result, op[0], op[1]); + return; + case nir_op_iand: + op[0] = get_nir_src(alu_parent->src[0].src); + op[1] = get_nir_src(alu_parent->src[1].src); + op[0].negate = true; + op[1].negate = true; + bld.OR(result, op[0], op[1]); + return; + case nir_op_ixor: + op[0] = get_nir_src(alu_parent->src[0].src); + op[1] = get_nir_src(alu_parent->src[1].src); + op[0].negate = true; + bld.XOR(result, op[0], op[1]); + return; + default: + unreachable("impossible opcode"); + } + } + } op[0] = resolve_source_modifiers(op[0]); } bld.NOT(result, op[0]); |