summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2017-02-09 15:21:47 +0000
committerIan Romanick <ian.d.romanick@intel.com>2017-02-09 15:25:18 +0000
commit7e7d26a593d2f2dcb7fe5d9764ea67b2f971f70d (patch)
treee3d010102ddefe643bbe580123a2af4b9cae1aa4
parentaa062eb51c8352eac08ec00fbf23ba2736b64adc (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.cpp37
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]);