From c8e331bf72245c0f1909063c36b2f27552d635c8 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Sat, 8 Apr 2023 17:52:52 -0400 Subject: [PATCH] agx: Fix abs/neg propagation into fcmpsel The first two sources are floats, the latter two sources and destination (and hence the opcode) are not. Reflect that when packing and optimizing. Noticed while debugging a silly dEQP test. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/asahi/compiler/agx_optimizer.c | 10 ++++++---- src/asahi/compiler/agx_pack.c | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/asahi/compiler/agx_optimizer.c b/src/asahi/compiler/agx_optimizer.c index 3c2c3b6..458459f 100644 --- a/src/asahi/compiler/agx_optimizer.c +++ b/src/asahi/compiler/agx_optimizer.c @@ -86,6 +86,8 @@ agx_optimizer_fmov(agx_instr **defs, agx_instr *ins) continue; if (def->saturate) continue; + if (ins->op == AGX_OPCODE_FCMPSEL && s >= 2) + continue; ins->src[s] = agx_compose_float_src(src, def->src[0]); } @@ -111,9 +113,9 @@ agx_optimizer_inline_imm(agx_instr **defs, agx_instr *I, unsigned srcs, bool float_src = is_float; - /* cmpselsrc takes integer immediates only */ - if (s >= 2 && I->op == AGX_OPCODE_FCMPSEL) - float_src = false; + /* fcmpsel takes first 2 as floats specially */ + if (s < 2 && I->op == AGX_OPCODE_FCMPSEL) + float_src = true; if (I->op == AGX_OPCODE_ST_TILE && s == 0) continue; if (I->op == AGX_OPCODE_ZS_EMIT && s != 0) @@ -208,7 +210,7 @@ agx_optimizer_forward(agx_context *ctx) agx_optimizer_copyprop(defs, I); /* Propagate fmov down */ - if (info.is_float) + if (info.is_float || I->op == AGX_OPCODE_FCMPSEL) agx_optimizer_fmov(defs, I); /* Inline immediates if we can. TODO: systematic */ diff --git a/src/asahi/compiler/agx_pack.c b/src/asahi/compiler/agx_pack.c index 4df255f..883a344 100644 --- a/src/asahi/compiler/agx_pack.c +++ b/src/asahi/compiler/agx_pack.c @@ -385,7 +385,7 @@ agx_pack_alu(struct util_dynarray *emission, agx_instr *I) if (is_16 && !is_cmpsel) assert((src_short & (1 << 9)) == 0); - if (info.is_float) { + if (info.is_float || (I->op == AGX_OPCODE_FCMPSEL && !is_cmpsel)) { unsigned fmod = agx_pack_float_mod(I->src[s]); unsigned fmod_offset = is_16 ? 9 : 10; src_short |= (fmod << fmod_offset); -- 2.7.4