From 4d821a11012d9a18e7364f4281d94dbe8ee12013 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Thu, 25 Apr 2019 03:48:08 +0000 Subject: [PATCH] panfrost/midgard: Optimize csel involving 0 Signed-off-by: Alyssa Rosenzweig --- .../drivers/panfrost/midgard/helpers.h | 2 +- .../panfrost/midgard/midgard_compile.c | 43 +++++++++++++------ 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/gallium/drivers/panfrost/midgard/helpers.h b/src/gallium/drivers/panfrost/midgard/helpers.h index 5912963ccdd..116c69b2c14 100644 --- a/src/gallium/drivers/panfrost/midgard/helpers.h +++ b/src/gallium/drivers/panfrost/midgard/helpers.h @@ -217,6 +217,7 @@ static struct { /* XXX: Test case where it's right on smul but not sadd */ [midgard_alu_op_iand] = {"iand", UNITS_ADD | OP_COMMUTES}, + [midgard_alu_op_iandnot] = {"iandnot", UNITS_ADD}, [midgard_alu_op_ior] = {"ior", UNITS_ADD | OP_COMMUTES}, [midgard_alu_op_ixor] = {"ixor", UNITS_ADD | OP_COMMUTES}, @@ -237,7 +238,6 @@ static struct { /* These instructions are not yet emitted by the compiler, so * don't speculate about units yet */ [midgard_alu_op_ishladd] = {"ishladd", 0}, - [midgard_alu_op_iandnot] = {"iandnot", 0}, [midgard_alu_op_uball_lt] = {"uball_lt", 0}, [midgard_alu_op_uball_lte] = {"uball_lte", 0}, diff --git a/src/gallium/drivers/panfrost/midgard/midgard_compile.c b/src/gallium/drivers/panfrost/midgard/midgard_compile.c index 5b5a44013a2..b5ab103298e 100644 --- a/src/gallium/drivers/panfrost/midgard/midgard_compile.c +++ b/src/gallium/drivers/panfrost/midgard/midgard_compile.c @@ -1227,29 +1227,44 @@ emit_alu(compiler_context *ctx, nir_alu_instr *instr) break; } + /* For a few special csel cases not handled by NIR, we can opt to + * bitwise. Otherwise, we emit the condition and do a real csel */ + case nir_op_b32csel: { - op = midgard_alu_op_fcsel; + if (nir_is_fzero_constant(instr->src[2].src)) { + /* (b ? v : 0) = (b & v) */ + op = midgard_alu_op_iand; + nr_inputs = 2; + } else if (nir_is_fzero_constant(instr->src[1].src)) { + /* (b ? 0 : v) = (!b ? v : 0) = (~b & v) = (v & ~b) */ + op = midgard_alu_op_iandnot; + nr_inputs = 2; + instr->src[1] = instr->src[0]; + instr->src[0] = instr->src[2]; + } else { + op = midgard_alu_op_fcsel; - /* csel works as a two-arg in Midgard, since the condition is hardcoded in r31.w */ - nr_inputs = 2; + /* csel works as a two-arg in Midgard, since the condition is hardcoded in r31.w */ + nr_inputs = 2; - /* Figure out which component the condition is in */ + /* Figure out which component the condition is in */ - unsigned comp = instr->src[0].swizzle[0]; + unsigned comp = instr->src[0].swizzle[0]; - /* Make sure NIR isn't throwing a mixed condition at us */ + /* Make sure NIR isn't throwing a mixed condition at us */ - for (unsigned c = 1; c < nr_components; ++c) - assert(instr->src[0].swizzle[c] == comp); + for (unsigned c = 1; c < nr_components; ++c) + assert(instr->src[0].swizzle[c] == comp); - /* Emit the condition into r31.w */ - emit_condition(ctx, &instr->src[0].src, false, comp); + /* Emit the condition into r31.w */ + emit_condition(ctx, &instr->src[0].src, false, comp); - /* The condition is the first argument; move the other - * arguments up one to be a binary instruction for - * Midgard */ + /* The condition is the first argument; move the other + * arguments up one to be a binary instruction for + * Midgard */ - memmove(instr->src, instr->src + 1, 2 * sizeof(nir_alu_src)); + memmove(instr->src, instr->src + 1, 2 * sizeof(nir_alu_src)); + } break; } -- 2.30.2