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