agx: Fix abs/neg propagation into fcmpsel
authorAlyssa Rosenzweig <alyssa@rosenzweig.io>
Sat, 8 Apr 2023 21:52:52 +0000 (17:52 -0400)
committerAlyssa Rosenzweig <alyssa@rosenzweig.io>
Sun, 7 May 2023 13:00:56 +0000 (09:00 -0400)
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 <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22891>

src/asahi/compiler/agx_optimizer.c
src/asahi/compiler/agx_pack.c

index 3c2c3b6..458459f 100644 (file)
@@ -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 */
index 4df255f..883a344 100644 (file)
@@ -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);