Mesa (main): intel/fs: Add many cmod propagation tests involving MOV instructions
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Mon Aug 30 21:11:44 UTC 2021
Module: Mesa
Branch: main
Commit: 0797388dc2598d38700c8b4cc84d437fe6000c61
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=0797388dc2598d38700c8b4cc84d437fe6000c61
Author: Ian Romanick <ian.d.romanick at intel.com>
Date: Tue Aug 17 16:04:09 2021 -0700
intel/fs: Add many cmod propagation tests involving MOV instructions
Of particular interest are the tests where the MOV performs a type
conversion. If the restriction on conditional modifier for a MOV is
ever relaxed, some of these cases must still be disallowed.
v2: s/NZ/Z/ in one of the comments. Notice by Marcin.
Reviewed-by: Marcin Ślusarz <marcin.slusarz at intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12045>
---
src/intel/compiler/test_fs_cmod_propagation.cpp | 584 ++++++++++++++++++++++++
1 file changed, 584 insertions(+)
diff --git a/src/intel/compiler/test_fs_cmod_propagation.cpp b/src/intel/compiler/test_fs_cmod_propagation.cpp
index 50e4efc137e..4c58684aa3f 100644
--- a/src/intel/compiler/test_fs_cmod_propagation.cpp
+++ b/src/intel/compiler/test_fs_cmod_propagation.cpp
@@ -40,6 +40,11 @@ public:
struct gl_shader_program *shader_prog;
fs_visitor *v;
+ void test_mov_prop(enum brw_conditional_mod cmod,
+ enum brw_reg_type add_type,
+ enum brw_reg_type mov_dst_type,
+ bool expected_cmod_prop_progress);
+
void test_saturate_prop(enum brw_conditional_mod before,
enum brw_conditional_mod after,
enum opcode op,
@@ -1500,6 +1505,585 @@ TEST_F(cmod_propagation_test, signed_unsigned_comparison_mismatch)
EXPECT_EQ(BRW_CONDITIONAL_LE, instruction(block0, 1)->conditional_mod);
}
+void
+cmod_propagation_test::test_mov_prop(enum brw_conditional_mod cmod,
+ enum brw_reg_type add_type,
+ enum brw_reg_type mov_dst_type,
+ bool expected_cmod_prop_progress)
+{
+ const fs_builder &bld = v->bld;
+ fs_reg dest = bld.vgrf(add_type);
+ fs_reg src0 = bld.vgrf(add_type);
+ fs_reg src1 = bld.vgrf(add_type);
+
+ bld.ADD(dest, src0, src1);
+ bld.MOV(retype(bld.null_reg_ud(), mov_dst_type), dest)
+ ->conditional_mod = cmod;
+
+ v->calculate_cfg();
+ bblock_t *block0 = v->cfg->blocks[0];
+
+ EXPECT_EQ(0, block0->start_ip);
+ EXPECT_EQ(1, block0->end_ip);
+
+ EXPECT_EQ(expected_cmod_prop_progress, cmod_propagation(v));
+
+ const enum brw_conditional_mod add_cmod =
+ expected_cmod_prop_progress ? cmod : BRW_CONDITIONAL_NONE;
+
+ EXPECT_EQ(0, block0->start_ip);
+
+ EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
+ EXPECT_EQ(add_cmod, instruction(block0, 0)->conditional_mod);
+
+ if (expected_cmod_prop_progress) {
+ EXPECT_EQ(0, block0->end_ip);
+ } else {
+ /* This is ASSERT_EQ because if end_ip is 0, the instruction(block0, 1)
+ * calls will not work properly, and the test will give weird results.
+ */
+ ASSERT_EQ(1, block0->end_ip);
+
+ EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 1)->opcode);
+ EXPECT_EQ(cmod, instruction(block0, 1)->conditional_mod);
+ }
+}
+
+TEST_F(cmod_propagation_test, fadd_fmov_nz)
+{
+ /* = Before =
+ * 0: add(8) dest:F src0:F src1:F
+ * 1: mov.nz(8) null:F dest:F
+ *
+ * = After =
+ * 0: add.nz(8) dest:F src0:F src1:F
+ */
+ test_mov_prop(BRW_CONDITIONAL_NZ,
+ BRW_REGISTER_TYPE_F,
+ BRW_REGISTER_TYPE_F,
+ true);
+}
+
+TEST_F(cmod_propagation_test, fadd_fmov_z)
+{
+ /* = Before =
+ * 0: add(8) dest:F src0:F src1:F
+ * 1: mov.z(8) null:F dest:F
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ */
+ test_mov_prop(BRW_CONDITIONAL_Z,
+ BRW_REGISTER_TYPE_F,
+ BRW_REGISTER_TYPE_F,
+ false);
+}
+
+TEST_F(cmod_propagation_test, fadd_fmov_l)
+{
+ /* = Before =
+ * 0: add(8) dest:F src0:F src1:F
+ * 1: mov.l(8) null:F dest:F
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ */
+ test_mov_prop(BRW_CONDITIONAL_L,
+ BRW_REGISTER_TYPE_F,
+ BRW_REGISTER_TYPE_F,
+ false);
+}
+
+TEST_F(cmod_propagation_test, fadd_fmov_g)
+{
+ /* = Before =
+ * 0: add(8) dest:F src0:F src1:F
+ * 1: mov.g(8) null:F dest:F
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ */
+ test_mov_prop(BRW_CONDITIONAL_G,
+ BRW_REGISTER_TYPE_F,
+ BRW_REGISTER_TYPE_F,
+ false);
+}
+
+TEST_F(cmod_propagation_test, fadd_fmov_le)
+{
+ /* = Before =
+ * 0: add(8) dest:F src0:F src1:F
+ * 1: mov.le(8) null:F dest:F
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ */
+ test_mov_prop(BRW_CONDITIONAL_LE,
+ BRW_REGISTER_TYPE_F,
+ BRW_REGISTER_TYPE_F,
+ false);
+}
+
+TEST_F(cmod_propagation_test, fadd_fmov_ge)
+{
+ /* = Before =
+ * 0: add(8) dest:F src0:F src1:F
+ * 1: mov.ge(8) null:F dest:F
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ */
+ test_mov_prop(BRW_CONDITIONAL_GE,
+ BRW_REGISTER_TYPE_F,
+ BRW_REGISTER_TYPE_F,
+ false);
+}
+
+TEST_F(cmod_propagation_test, iadd_imov_nz)
+{
+ /* = Before =
+ * 0: add(8) dest:D src0:D src1:D
+ * 1: mov.nz(8) null:D dest:D
+ *
+ * = After =
+ * 0: add.nz(8) dest:D src0:D src1:D
+ */
+ test_mov_prop(BRW_CONDITIONAL_NZ,
+ BRW_REGISTER_TYPE_D,
+ BRW_REGISTER_TYPE_D,
+ true);
+}
+
+TEST_F(cmod_propagation_test, iadd_imov_z)
+{
+ /* = Before =
+ * 0: add(8) dest:D src0:D src1:D
+ * 1: mov.z(8) null:D dest:D
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ */
+ test_mov_prop(BRW_CONDITIONAL_Z,
+ BRW_REGISTER_TYPE_D,
+ BRW_REGISTER_TYPE_D,
+ false);
+}
+
+TEST_F(cmod_propagation_test, iadd_imov_l)
+{
+ /* = Before =
+ * 0: add(8) dest:D src0:D src1:D
+ * 1: mov.l(8) null:D dest:D
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ */
+ test_mov_prop(BRW_CONDITIONAL_L,
+ BRW_REGISTER_TYPE_D,
+ BRW_REGISTER_TYPE_D,
+ false);
+}
+
+TEST_F(cmod_propagation_test, iadd_imov_g)
+{
+ /* = Before =
+ * 0: add(8) dest:D src0:D src1:D
+ * 1: mov.g(8) null:D dest:D
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ */
+ test_mov_prop(BRW_CONDITIONAL_G,
+ BRW_REGISTER_TYPE_D,
+ BRW_REGISTER_TYPE_D,
+ false);
+}
+
+TEST_F(cmod_propagation_test, iadd_imov_le)
+{
+ /* = Before =
+ * 0: add(8) dest:D src0:D src1:D
+ * 1: mov.le(8) null:D dest:D
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ */
+ test_mov_prop(BRW_CONDITIONAL_LE,
+ BRW_REGISTER_TYPE_D,
+ BRW_REGISTER_TYPE_D,
+ false);
+}
+
+TEST_F(cmod_propagation_test, iadd_imov_ge)
+{
+ /* = Before =
+ * 0: add(8) dest:D src0:D src1:D
+ * 1: mov.ge(8) null:D dest:D
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ */
+ test_mov_prop(BRW_CONDITIONAL_GE,
+ BRW_REGISTER_TYPE_D,
+ BRW_REGISTER_TYPE_D,
+ false);
+}
+
+TEST_F(cmod_propagation_test, iadd_umov_nz)
+{
+ /* = Before =
+ * 0: add(8) dest:D src0:D src1:D
+ * 1: mov.nz(8) null:UD dest:D
+ *
+ * = After =
+ * 0: add.nz(8) dest:D src0:D src1:D
+ */
+ test_mov_prop(BRW_CONDITIONAL_NZ,
+ BRW_REGISTER_TYPE_D,
+ BRW_REGISTER_TYPE_UD,
+ true);
+}
+
+TEST_F(cmod_propagation_test, iadd_umov_z)
+{
+ /* = Before =
+ * 0: add(8) dest:D src0:D src1:D
+ * 1: mov.z(8) null:UD dest:D
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ *
+ * In spite of the type conversion, the Z test would be safe to propagate.
+ */
+ test_mov_prop(BRW_CONDITIONAL_Z,
+ BRW_REGISTER_TYPE_D,
+ BRW_REGISTER_TYPE_UD,
+ false);
+}
+
+TEST_F(cmod_propagation_test, iadd_umov_l)
+{
+ /* = Before =
+ * 0: add(8) dest:D src0:D src1:D
+ * 1: mov.l(8) null:UD dest:D
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ *
+ * Due to the signed-to-usigned type conversion, the conditional modifier
+ * cannot be propagated to the ADD without changing at least the
+ * destination type of the add.
+ *
+ * This particular tests is a little silly. Unsigned less than zero is a
+ * contradiction, and earlier optimization passes should have eliminated
+ * it.
+ */
+ test_mov_prop(BRW_CONDITIONAL_L,
+ BRW_REGISTER_TYPE_D,
+ BRW_REGISTER_TYPE_UD,
+ false);
+}
+
+TEST_F(cmod_propagation_test, iadd_umov_g)
+{
+ /* = Before =
+ * 0: add(8) dest:D src0:D src1:D
+ * 1: mov.g(8) null:UD dest:D
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ *
+ * In spite of the type conversion, this could be made to work by
+ * propagating NZ instead of G to the ADD.
+ */
+ test_mov_prop(BRW_CONDITIONAL_G,
+ BRW_REGISTER_TYPE_D,
+ BRW_REGISTER_TYPE_UD,
+ false);
+}
+
+TEST_F(cmod_propagation_test, iadd_umov_le)
+{
+ /* = Before =
+ * 0: add(8) dest:D src0:D src1:D
+ * 1: mov.le(8) null:UD dest:D
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ *
+ * In spite of the type conversion, this could be made to work by
+ * propagating Z instead of LE to the ADD.
+ */
+ test_mov_prop(BRW_CONDITIONAL_LE,
+ BRW_REGISTER_TYPE_D,
+ BRW_REGISTER_TYPE_UD,
+ false);
+}
+
+TEST_F(cmod_propagation_test, iadd_umov_ge)
+{
+ /* = Before =
+ * 0: add(8) dest:D src0:D src1:D
+ * 1: mov.ge(8) null:UD dest:D
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ *
+ * Due to the signed-to-usigned type conversion, the conditional modifier
+ * cannot be propagated to the ADD without changing at least the
+ * destination type of the add.
+ *
+ * This particular tests is a little silly. Unsigned greater than or equal
+ * to zero is a tautology, and earlier optimization passes should have
+ * eliminated it.
+ */
+ test_mov_prop(BRW_CONDITIONAL_GE,
+ BRW_REGISTER_TYPE_D,
+ BRW_REGISTER_TYPE_UD,
+ false);
+}
+
+TEST_F(cmod_propagation_test, fadd_f2u_nz)
+{
+ /* = Before =
+ * 0: add(8) dest:F src0:F src1:F
+ * 1: mov.nz(8) null:UD dest:F
+ *
+ * = After =
+ * No changes. The MOV changes the type from float to unsigned integer.
+ * If dest is in the range [-Inf, 1), the conversion will clamp it to zero.
+ * If dest is NaN, the conversion will also clamp it to zero. It is not
+ * safe to propagate the NZ back to the ADD.
+ *
+ * It's tempting to try to propagate G to the ADD in place of the NZ. This
+ * fails for values (0, 1). For example, if dest is 0.5, add.g would set
+ * the flag, but mov.nz would not because the 0.5 would get rounded down to
+ * zero.
+ */
+ test_mov_prop(BRW_CONDITIONAL_NZ,
+ BRW_REGISTER_TYPE_F,
+ BRW_REGISTER_TYPE_UD,
+ false);
+}
+
+TEST_F(cmod_propagation_test, fadd_f2u_z)
+{
+ /* = Before =
+ * 0: add(8) dest:F src0:F src1:F
+ * 1: mov.z(8) null:UD dest:F
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ *
+ * The MOV changes the type from float to unsigned integer. If dest is in
+ * the range [-Inf, 1), the conversion will clamp it to zero. If dest is
+ * NaN, the conversion will also clamp it to zero. It is not safe to
+ * propagate the Z back to the ADD.
+ */
+ test_mov_prop(BRW_CONDITIONAL_Z,
+ BRW_REGISTER_TYPE_F,
+ BRW_REGISTER_TYPE_UD,
+ false);
+}
+
+TEST_F(cmod_propagation_test, fadd_f2u_l)
+{
+ /* = Before =
+ * 0: add(8) dest:F src0:F src1:F
+ * 1: mov.l(8) null:UD dest:F
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ *
+ * The MOV changes the type from float to unsigned integer. If dest is in
+ * the range [-Inf, 1), the conversion will clamp it to zero. If dest is
+ * NaN, the conversion will also clamp it to zero. It is not safe to
+ * propagate the L back to the ADD.
+ */
+ test_mov_prop(BRW_CONDITIONAL_L,
+ BRW_REGISTER_TYPE_F,
+ BRW_REGISTER_TYPE_UD,
+ false);
+}
+
+TEST_F(cmod_propagation_test, fadd_f2u_g)
+{
+ /* = Before =
+ * 0: add(8) dest:F src0:F src1:F
+ * 1: mov.g(8) null:UD dest:F
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ *
+ * The MOV changes the type from float to unsigned integer. If dest is in
+ * the range [-Inf, 1), the conversion will clamp it to zero. If dest is
+ * NaN, the conversion will also clamp it to zero. It is not safe to
+ * propagate the G back to the ADD.
+ */
+ test_mov_prop(BRW_CONDITIONAL_G,
+ BRW_REGISTER_TYPE_F,
+ BRW_REGISTER_TYPE_UD,
+ false);
+}
+
+TEST_F(cmod_propagation_test, fadd_f2u_le)
+{
+ /* = Before =
+ * 0: add(8) dest:F src0:F src1:F
+ * 1: mov.le(8) null:UD dest:F
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ *
+ * The MOV changes the type from float to unsigned integer. If dest is in
+ * the range [-Inf, 1), the conversion will clamp it to zero. If dest is
+ * NaN, the conversion will also clamp it to zero. It is not safe to
+ * propagate the LE back to the ADD.
+ */
+ test_mov_prop(BRW_CONDITIONAL_LE,
+ BRW_REGISTER_TYPE_F,
+ BRW_REGISTER_TYPE_UD,
+ false);
+}
+
+TEST_F(cmod_propagation_test, fadd_f2u_ge)
+{
+ /* = Before =
+ * 0: add(8) dest:F src0:F src1:F
+ * 1: mov.ge(8) null:UD dest:F
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ *
+ * The MOV changes the type from float to unsigned integer. If dest is in
+ * the range [-Inf, 1), the conversion will clamp it to zero. If dest is
+ * NaN, the conversion will also clamp it to zero. It is not safe to
+ * propagate the GE back to the ADD.
+ */
+ test_mov_prop(BRW_CONDITIONAL_GE,
+ BRW_REGISTER_TYPE_F,
+ BRW_REGISTER_TYPE_UD,
+ false);
+}
+
+TEST_F(cmod_propagation_test, fadd_f2i_nz)
+{
+ /* = Before =
+ * 0: add(8) dest:F src0:F src1:F
+ * 1: mov.nz(8) null:D dest:F
+ *
+ * = After =
+ * No changes. The MOV changes the type from float to signed integer. If
+ * dest is in the range (-1, 1), the conversion will clamp it to zero. If
+ * dest is NaN, the conversion will also clamp it to zero. It is not safe
+ * to propagate the NZ back to the ADD.
+ */
+ test_mov_prop(BRW_CONDITIONAL_NZ,
+ BRW_REGISTER_TYPE_F,
+ BRW_REGISTER_TYPE_D,
+ false);
+}
+
+TEST_F(cmod_propagation_test, fadd_f2i_z)
+{
+ /* = Before =
+ * 0: add(8) dest:F src0:F src1:F
+ * 1: mov.z(8) null:D dest:F
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ *
+ * The MOV changes the type from float to signed integer. If dest is in
+ * the range (-1, 1), the conversion will clamp it to zero. If dest is
+ * NaN, the conversion will also clamp it to zero. It is not safe to
+ * propagate the Z back to the ADD.
+ */
+ test_mov_prop(BRW_CONDITIONAL_Z,
+ BRW_REGISTER_TYPE_F,
+ BRW_REGISTER_TYPE_D,
+ false);
+}
+
+TEST_F(cmod_propagation_test, fadd_f2i_l)
+{
+ /* = Before =
+ * 0: add(8) dest:F src0:F src1:F
+ * 1: mov.l(8) null:D dest:F
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ *
+ * The MOV changes the type from float to signed integer. If dest is in
+ * the range (-1, 1), the conversion will clamp it to zero. If dest is
+ * NaN, the conversion will also clamp it to zero. It is not safe to
+ * propagate the L back to the ADD.
+ */
+ test_mov_prop(BRW_CONDITIONAL_L,
+ BRW_REGISTER_TYPE_F,
+ BRW_REGISTER_TYPE_D,
+ false);
+}
+
+TEST_F(cmod_propagation_test, fadd_f2i_g)
+{
+ /* = Before =
+ * 0: add(8) dest:F src0:F src1:F
+ * 1: mov.g(8) null:D dest:F
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ *
+ * The MOV changes the type from float to signed integer. If dest is in
+ * the range (-1, 1), the conversion will clamp it to zero. If dest is
+ * NaN, the conversion will also clamp it to zero. It is not safe to
+ * propagate the G back to the ADD.
+ */
+ test_mov_prop(BRW_CONDITIONAL_G,
+ BRW_REGISTER_TYPE_F,
+ BRW_REGISTER_TYPE_D,
+ false);
+}
+
+TEST_F(cmod_propagation_test, fadd_f2i_le)
+{
+ /* = Before =
+ * 0: add(8) dest:F src0:F src1:F
+ * 1: mov.le(8) null:D dest:F
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ *
+ * The MOV changes the type from float to signed integer. If dest is in
+ * the range (-1, 1), the conversion will clamp it to zero. If dest is
+ * NaN, the conversion will also clamp it to zero. It is not safe to
+ * propagate the LE back to the ADD.
+ */
+ test_mov_prop(BRW_CONDITIONAL_LE,
+ BRW_REGISTER_TYPE_F,
+ BRW_REGISTER_TYPE_D,
+ false);
+}
+
+TEST_F(cmod_propagation_test, fadd_f2i_ge)
+{
+ /* = Before =
+ * 0: add(8) dest:F src0:F src1:F
+ * 1: mov.ge(8) null:D dest:F
+ *
+ * = After =
+ * No changes. cmod propagation bails on every MOV except MOV.NZ.
+ *
+ * The MOV changes the type from float to signed integer. If dest is in
+ * the range (-1, 1), the conversion will clamp it to zero. If dest is
+ * NaN, the conversion will also clamp it to zero. It is not safe to
+ * propagate the GE back to the ADD.
+ */
+ test_mov_prop(BRW_CONDITIONAL_GE,
+ BRW_REGISTER_TYPE_F,
+ BRW_REGISTER_TYPE_D,
+ false);
+}
+
void
cmod_propagation_test::test_saturate_prop(enum brw_conditional_mod before,
enum brw_conditional_mod after,
More information about the mesa-commit
mailing list