aco/tests: add vop3p constant combine tests
authorRhys Perry <pendingchaos02@gmail.com>
Mon, 2 May 2022 17:21:56 +0000 (18:21 +0100)
committerMarge Bot <emma+marge@anholt.net>
Tue, 5 Jul 2022 16:39:56 +0000 (16:39 +0000)
Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16296>

src/amd/compiler/tests/test_optimizer.cpp

index 8afb56c..1059378 100644 (file)
@@ -1664,3 +1664,118 @@ BEGIN_TEST(optimize.mad_mix.cast)
    }
 END_TEST
 
+static void vop3p_constant(unsigned *idx, aco_opcode op, const char *swizzle, uint32_t val)
+{
+   uint32_t halves[2] = {val & 0xffff, val >> 16};
+   uint32_t expected = halves[swizzle[0] - 'x'] | (halves[swizzle[1] - 'x'] << 16);
+   fprintf(output, "Expected for %u: 0x%.8x / %u\n", *idx, expected, expected);
+
+   unsigned opsel_lo = swizzle[0] == 'x' ? 0x0 : 0x1;
+   unsigned opsel_hi = swizzle[1] == 'x' ? 0x2 : 0x3;
+   writeout((*idx)++, bld.vop3p(op, bld.def(v1), bld.copy(bld.def(v1), Operand::c32(val)),
+                                inputs[0], opsel_lo, opsel_hi));
+}
+
+BEGIN_TEST(optimize.vop3p_constants)
+   for (aco_opcode op : {aco_opcode::v_pk_add_f16, aco_opcode::v_pk_add_u16}) {
+      for (const char *swizzle : {"xx", "yy", "xy", "yx"}) {
+         char variant[16];
+         strcpy(variant, op == aco_opcode::v_pk_add_f16 ? "_f16" : "_u16");
+         strcat(variant, "_");
+         strcat(variant, swizzle);
+
+         //; for i in range(36):
+         //;    insert_pattern('Expected for %u: $_ / #expected%u' % (i, i))
+
+         //>> v1: %a = p_startpgm
+         if (!setup_cs("v1", GFX10_3, CHIP_UNKNOWN, variant))
+            continue;
+
+         //; opcode = 'v_pk_add_u16' if 'u16' in variant else 'v_pk_add_f16'
+         //; for i in range(36):
+         //;    insert_pattern('v1: %%res%u = %s $got%u %%a' % (i, opcode, i))
+         //;    insert_pattern('p_unit_test %u, %%res%u' % (i, i))
+         //! s_endpgm
+
+         //; def parse_op(op):
+         //;    is_int = opcode == 'v_pk_add_u16'
+         //;    op = op.rstrip(',')
+         //;
+         //;    mods = lambda v: v
+         //;    if op.endswith('*[1,-1]'):
+         //;       mods = lambda v: v ^ 0x80000000
+         //;       assert(not is_int)
+         //;    elif op.endswith('*[-1,1]'):
+         //;       mods = lambda v: v ^ 0x00008000
+         //;       assert(not is_int)
+         //;    op = op.split('*')[0]
+         //;
+         //;    swizzle = lambda v: v
+         //;    if op.endswith('.xx'):
+         //;       swizzle = lambda v: ((v & 0xffff) | (v << 16)) & 0xffffffff;
+         //;    elif op.endswith('.yy'):
+         //;       swizzle = lambda v: (v >> 16) | (v & 0xffff0000);
+         //;    elif op.endswith('.yx'):
+         //;       swizzle = lambda v: ((v >> 16) | (v << 16)) & 0xffffffff;
+         //;    op = op.rstrip('xy.')
+         //;
+         //;    val = None
+         //;    if op.startswith('0x'):
+         //;       val = int(op[2:], 16)
+         //;    elif op == '-1.0':
+         //;       val = 0xbf800000 if is_int else 0xbC00
+         //;    elif op == '1.0':
+         //;       val = 0x3f800000 if is_int else 0x3c00
+         //;    else:
+         //;       val = int(op) & 0xffffffff
+         //;
+         //;    return mods(swizzle(val))
+
+         //; # Check correctness
+         //; for i in range(36):
+         //;    expected = globals()['expected%u' % i]
+         //;    got = globals()['got%u' % i]
+         //;    got_parsed = parse_op(got)
+         //;    if got_parsed != expected:
+         //;       raise Exception('Check %u failed: expected 0x%.8x, got 0x%.8x ("%s")' % (i, expected, got_parsed, got))
+
+         //; # Check that all literals are ones that cannot be encoded as inline constants
+         //; allowed_literals = [0x00004242, 0x0000fffe, 0x00308030, 0x0030ffff, 0x3c00ffff,
+         //;                     0x42420000, 0x42424242, 0x4242c242, 0x4242ffff, 0x7ffefffe,
+         //;                     0x80300030, 0xbeefdead, 0xc2424242, 0xdeadbeef, 0xfffe0000,
+         //;                     0xfffe7ffe, 0xffff0030, 0xffff3c00, 0xffff4242]
+         //; if opcode == 'v_pk_add_u16':
+         //;    allowed_literals.extend([0x00003c00, 0x3c000000, 0x3c003c00, 0x3c00bc00, 0xbc003c00])
+         //; else:
+         //;    allowed_literals.extend([0x00003f80, 0x3f800000])
+         //;
+         //; for i in range(36):
+         //;    got = globals()['got%u' % i]
+         //;    if not got.startswith('0x'):
+         //;       continue;
+         //;    got = int(got[2:].rstrip(',').split('*')[0].split('.')[0], 16)
+         //;    if got not in allowed_literals:
+         //;       raise Exception('Literal check %u failed: 0x%.8x not in allowed literals' % (i, got))
+
+         unsigned idx = 0;
+         for (uint32_t constant : {0x3C00, 0x0030, 0xfffe, 0x4242}) {
+            vop3p_constant(&idx, op, swizzle, constant);
+            vop3p_constant(&idx, op, swizzle, constant | 0xffff0000);
+            vop3p_constant(&idx, op, swizzle, constant | (constant << 16));
+            vop3p_constant(&idx, op, swizzle, constant << 16);
+            vop3p_constant(&idx, op, swizzle, (constant << 16) | 0x0000ffff);
+            vop3p_constant(&idx, op, swizzle, constant | ((constant ^ 0x8000) << 16));
+            vop3p_constant(&idx, op, swizzle, (constant ^ 0x8000) | (constant << 16));
+         }
+
+         for (uint32_t constant : {0x3f800000u, 0xfffffffeu, 0x00000030u, 0xdeadbeefu}) {
+            uint32_t lo = constant & 0xffff;
+            uint32_t hi = constant >> 16;
+            vop3p_constant(&idx, op, swizzle, constant);
+            vop3p_constant(&idx, op, swizzle, hi | (lo << 16));
+         }
+
+         finish_opt_test();
+      }
+   }
+END_TEST