From: Alyssa Rosenzweig Date: Tue, 3 Aug 2021 22:39:13 +0000 (-0400) Subject: pan/bi: Add optimizer unit tests X-Git-Tag: upstream/22.3.5~19318 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a98790fa963919514398f76a912ed9c228b25ae3;p=platform%2Fupstream%2Fmesa.git pan/bi: Add optimizer unit tests Writing these tests brought to light the cluster of bugs fixed in the previous commits. Now that things work, let's ensure they stay working. Signed-off-by: Alyssa Rosenzweig Part-of: --- diff --git a/src/panfrost/bifrost/meson.build b/src/panfrost/bifrost/meson.build index 38f1539..6885581 100644 --- a/src/panfrost/bifrost/meson.build +++ b/src/panfrost/bifrost/meson.build @@ -185,6 +185,20 @@ if with_tests ) test( + 'bifrost_optimizer', + executable( + 'bifrost_optimizer_test', + files('test/test-optimizer.c'), + c_args : [c_msvc_compat_args, no_override_init_args], + gnu_symbol_visibility : 'hidden', + include_directories : [inc_include, inc_src, inc_mesa], + dependencies: [idep_nir, idep_bi_opcodes_h, idep_bi_builder_h], + link_with : [libpanfrost_bifrost], + ), + suite : ['panfrost'], + ) + + test( 'bifrost_constant_fold', executable( 'bifrost_constant_fold_test', diff --git a/src/panfrost/bifrost/test/test-optimizer.c b/src/panfrost/bifrost/test/test-optimizer.c new file mode 100644 index 0000000..43dc015 --- /dev/null +++ b/src/panfrost/bifrost/test/test-optimizer.c @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2021 Collabora, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "compiler.h" +#include "bi_test.h" +#include "bi_builder.h" + +#define CASE(instr, expected) do { \ + bi_builder *A = bit_builder(ralloc_ctx); \ + bi_builder *B = bit_builder(ralloc_ctx); \ + { \ + bi_builder *b = A; \ + instr; \ + } \ + { \ + bi_builder *b = B; \ + expected; \ + } \ + bi_opt_mod_prop_forward(A->shader); \ + bi_opt_mod_prop_backward(A->shader); \ + bi_opt_dead_code_eliminate(A->shader); \ + if (bit_shader_equal(A->shader, B->shader)) { \ + nr_pass++; \ + } else { \ + fprintf(stderr, "Got:\n"); \ + bi_print_shader(A->shader, stderr); \ + fprintf(stderr, "Expected:\n"); \ + bi_print_shader(B->shader, stderr); \ + fprintf(stderr, "\n"); \ + nr_fail++; \ + } \ +} while(0) + +#define NEGCASE(instr) CASE(instr, instr) + +int +main(int argc, const char **argv) +{ + unsigned nr_fail = 0, nr_pass = 0; + void *ralloc_ctx = ralloc_context(NULL); + bi_index zero = bi_zero(); + bi_index reg = bi_register(0); + bi_index x = bi_register(1); + bi_index y = bi_register(2); + bi_index negabsx = bi_neg(bi_abs(x)); + + /* Check absneg is fused */ + + CASE(bi_fadd_f32_to(b, reg, bi_fabsneg_f32(b, bi_abs(x)), y, BI_ROUND_NONE), + bi_fadd_f32_to(b, reg, bi_abs(x), y, BI_ROUND_NONE)); + + CASE(bi_fadd_f32_to(b, reg, bi_fabsneg_f32(b, bi_neg(x)), y, BI_ROUND_NONE), + bi_fadd_f32_to(b, reg, bi_neg(x), y, BI_ROUND_NONE)); + + CASE(bi_fadd_f32_to(b, reg, bi_fabsneg_f32(b, negabsx), y, BI_ROUND_NONE), + bi_fadd_f32_to(b, reg, negabsx, y, BI_ROUND_NONE)); + + CASE(bi_fadd_f32_to(b, reg, bi_fabsneg_f32(b, x), y, BI_ROUND_NONE), + bi_fadd_f32_to(b, reg, x, y, BI_ROUND_NONE)); + + /* Check absneg is fused on a variety of instructions */ + + CASE(bi_fadd_f32_to(b, reg, bi_fabsneg_f32(b, negabsx), y, BI_ROUND_RTP), + bi_fadd_f32_to(b, reg, negabsx, y, BI_ROUND_RTP)); + + CASE(bi_fmin_f32_to(b, reg, bi_fabsneg_f32(b, negabsx), bi_neg(y)), + bi_fmin_f32_to(b, reg, negabsx, bi_neg(y))); + + /* Check absneg is fused on fp16 */ + + CASE(bi_fadd_v2f16_to(b, reg, bi_fabsneg_v2f16(b, negabsx), y, BI_ROUND_RTP), + bi_fadd_v2f16_to(b, reg, negabsx, y, BI_ROUND_RTP)); + + CASE(bi_fmin_v2f16_to(b, reg, bi_fabsneg_v2f16(b, negabsx), bi_neg(y)), + bi_fmin_v2f16_to(b, reg, negabsx, bi_neg(y))); + + /* Check that swizzles are composed for fp16 */ + + CASE(bi_fadd_v2f16_to(b, reg, bi_fabsneg_v2f16(b, bi_swz_16(negabsx, true, false)), y, BI_ROUND_RTP), + bi_fadd_v2f16_to(b, reg, bi_swz_16(negabsx, true, false), y, BI_ROUND_RTP)); + + CASE(bi_fadd_v2f16_to(b, reg, bi_swz_16(bi_fabsneg_v2f16(b, negabsx), true, false), y, BI_ROUND_RTP), + bi_fadd_v2f16_to(b, reg, bi_swz_16(negabsx, true, false), y, BI_ROUND_RTP)); + + CASE(bi_fadd_v2f16_to(b, reg, bi_swz_16(bi_fabsneg_v2f16(b, bi_swz_16(negabsx, true, false)), true, false), y, BI_ROUND_RTP), + bi_fadd_v2f16_to(b, reg, negabsx, y, BI_ROUND_RTP)); + + CASE(bi_fadd_v2f16_to(b, reg, bi_swz_16(bi_fabsneg_v2f16(b, bi_half(negabsx, false)), true, false), y, BI_ROUND_RTP), + bi_fadd_v2f16_to(b, reg, bi_half(negabsx, false), y, BI_ROUND_RTP)); + + CASE(bi_fadd_v2f16_to(b, reg, bi_swz_16(bi_fabsneg_v2f16(b, bi_half(negabsx, true)), true, false), y, BI_ROUND_RTP), + bi_fadd_v2f16_to(b, reg, bi_half(negabsx, true), y, BI_ROUND_RTP)); + + /* Check that widens are passed through */ + + CASE(bi_fadd_f32_to(b, reg, bi_fabsneg_f32(b, bi_half(negabsx, false)), y, BI_ROUND_NONE), + bi_fadd_f32_to(b, reg, bi_half(negabsx, false), y, BI_ROUND_NONE)); + + CASE(bi_fadd_f32_to(b, reg, bi_fabsneg_f32(b, bi_half(negabsx, true)), y, BI_ROUND_NONE), + bi_fadd_f32_to(b, reg, bi_half(negabsx, true), y, BI_ROUND_NONE)); + + CASE(bi_fadd_f32_to(b, reg, bi_fabsneg_f32(b, bi_half(x, true)), bi_fabsneg_f32(b, bi_half(x, false)), BI_ROUND_NONE), + bi_fadd_f32_to(b, reg, bi_half(x, true), bi_half(x, false), BI_ROUND_NONE)); + + /* Refuse to mix sizes for fabsneg, that's wrong */ + + NEGCASE(bi_fadd_f32_to(b, reg, bi_fabsneg_v2f16(b, negabsx), y, BI_ROUND_NONE)); + NEGCASE(bi_fadd_v2f16_to(b, reg, bi_fabsneg_f32(b, negabsx), y, BI_ROUND_NONE)); + + /* It's tempting to use addition by 0.0 as the absneg primitive, but that + * has footguns around signed zero and round modes. Check we don't + * incorrectly fuse these rules. */ + + NEGCASE(bi_fadd_f32_to(b, reg, bi_fadd_f32(b, bi_abs(x), zero, BI_ROUND_NONE), y, BI_ROUND_NONE)); + NEGCASE(bi_fadd_f32_to(b, reg, bi_fadd_f32(b, bi_neg(x), zero, BI_ROUND_NONE), y, BI_ROUND_NONE)); + NEGCASE(bi_fadd_f32_to(b, reg, bi_fadd_f32(b, bi_neg(bi_abs(x)), zero, BI_ROUND_NONE), y, BI_ROUND_NONE)); + NEGCASE(bi_fadd_f32_to(b, reg, bi_fadd_f32(b, x, zero, BI_ROUND_NONE), y, BI_ROUND_NONE)); + + ralloc_free(ralloc_ctx); + TEST_END(nr_pass, nr_fail); +}