From 622e3a8510ad6ccff41b2ba2f6184b80ad67dea5 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Tue, 2 Jun 2020 12:15:18 -0400 Subject: [PATCH] pan/mdg: Legalize inverts with constants We need to force src_invert to be in the right place even if we flip when lowering an embedded->inline constant. Signed-off-by: Alyssa Rosenzweig Fixes: 449e5ded934 ("pan/mdg: Treat inot as a modifier") Reported-by: Icecream95 Part-of: --- src/panfrost/midgard/midgard_compile.c | 40 +++++++++++++++++++++----- src/panfrost/midgard/mir.c | 4 +++ 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/panfrost/midgard/midgard_compile.c b/src/panfrost/midgard/midgard_compile.c index e9e6c15c678..98f948a9b88 100644 --- a/src/panfrost/midgard/midgard_compile.c +++ b/src/panfrost/midgard/midgard_compile.c @@ -1147,13 +1147,6 @@ emit_alu(compiler_context *ctx, nir_alu_instr *instr) ins.is_pack = true; } - /* Arrange for creation of iandnot/iornot */ - if (ins.src_invert[0] && !ins.src_invert[1]) { - mir_flip(&ins); - ins.src_invert[0] = false; - ins.src_invert[1] = true; - } - if ((opcode_props & UNITS_ALL) == UNIT_VLUT) { /* To avoid duplicating the lookup tables (probably), true LUT * instructions can only operate as if they were scalars. Lower @@ -2307,6 +2300,38 @@ midgard_cull_dead_branch(compiler_context *ctx, midgard_block *block) } } +/* We want to force the invert on AND/OR to the second slot to legalize into + * iandnot/iornot. The relevant patterns are for AND (and OR respectively) + * + * ~a & #b = ~a & ~(#~b) + * ~a & b = b & ~a + */ + +static void +midgard_legalize_invert(compiler_context *ctx, midgard_block *block) +{ + mir_foreach_instr_in_block(block, ins) { + if (ins->type != TAG_ALU_4) continue; + + if (ins->alu.op != midgard_alu_op_iand && + ins->alu.op != midgard_alu_op_ior) continue; + + if (ins->src_invert[1] || !ins->src_invert[0]) continue; + + if (ins->has_inline_constant) { + /* ~(#~a) = ~(~#a) = a, so valid, and forces both + * inverts on */ + ins->inline_constant = ~ins->inline_constant; + ins->src_invert[1] = true; + } else { + /* Flip to the right invert order. Note + * has_inline_constant false by assumption on the + * branch, so flipping makes sense. */ + mir_flip(ins); + } + } +} + static unsigned emit_fragment_epilogue(compiler_context *ctx, unsigned rt) { @@ -2665,6 +2690,7 @@ midgard_compile_shader_nir(nir_shader *nir, panfrost_program *program, bool is_b mir_foreach_block(ctx, _block) { midgard_block *block = (midgard_block *) _block; midgard_lower_derivatives(ctx, block); + midgard_legalize_invert(ctx, block); midgard_cull_dead_branch(ctx, block); } diff --git a/src/panfrost/midgard/mir.c b/src/panfrost/midgard/mir.c index 0bb87c8fe00..771d600e945 100644 --- a/src/panfrost/midgard/mir.c +++ b/src/panfrost/midgard/mir.c @@ -445,6 +445,10 @@ mir_flip(midgard_instruction *ins) ins->src_neg[0] = ins->src_neg[1]; ins->src_neg[1] = temp; + temp = ins->src_invert[0]; + ins->src_invert[0] = ins->src_invert[1]; + ins->src_invert[1] = temp; + unsigned temp_swizzle[16]; memcpy(temp_swizzle, ins->swizzle[0], sizeof(ins->swizzle[0])); memcpy(ins->swizzle[0], ins->swizzle[1], sizeof(ins->swizzle[0])); -- 2.30.2