intel/eu/validate: Add some validation of ADD3
authorIan Romanick <ian.d.romanick@intel.com>
Thu, 25 May 2023 02:35:40 +0000 (19:35 -0700)
committerMarge Bot <emma+marge@anholt.net>
Tue, 6 Jun 2023 06:10:53 +0000 (06:10 +0000)
v2: Remove spurious ALIGN_1 checks. Suggested by Matt.

Reviewed-by: Matt Turner <mattst88@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23262>

src/intel/compiler/brw_eu_validate.c
src/intel/compiler/test_eu_validate.cpp

index b30c9ba..cad582b 100644 (file)
@@ -2279,6 +2279,47 @@ instruction_restrictions(const struct brw_isa_info *isa,
 
    }
 
+   if (brw_inst_opcode(isa, inst) == BRW_OPCODE_ADD3) {
+      const enum brw_reg_type dst_type = inst_dst_type(isa, inst);
+
+      ERROR_IF(dst_type != BRW_REGISTER_TYPE_D &&
+               dst_type != BRW_REGISTER_TYPE_UD &&
+               dst_type != BRW_REGISTER_TYPE_W &&
+               dst_type != BRW_REGISTER_TYPE_UW,
+               "Destination must be integer D, UD, W, or UW type.");
+
+      for (unsigned i = 0; i < 3; i++) {
+         enum brw_reg_type src_type;
+
+         switch (i) {
+         case 0: src_type = brw_inst_3src_a1_src0_type(devinfo, inst); break;
+         case 1: src_type = brw_inst_3src_a1_src1_type(devinfo, inst); break;
+         case 2: src_type = brw_inst_3src_a1_src2_type(devinfo, inst); break;
+         default: unreachable("invalid src");
+         }
+
+         ERROR_IF(src_type != BRW_REGISTER_TYPE_D &&
+                  src_type != BRW_REGISTER_TYPE_UD &&
+                  src_type != BRW_REGISTER_TYPE_W &&
+                  src_type != BRW_REGISTER_TYPE_UW,
+                  "Source must be integer D, UD, W, or UW type.");
+
+         if (i == 0) {
+            if (brw_inst_3src_a1_src0_is_imm(devinfo, inst)) {
+               ERROR_IF(src_type != BRW_REGISTER_TYPE_W &&
+                        src_type != BRW_REGISTER_TYPE_UW,
+                        "Immediate source must be integer W or UW type.");
+            }
+         } else if (i == 2) {
+            if (brw_inst_3src_a1_src2_is_imm(devinfo, inst)) {
+               ERROR_IF(src_type != BRW_REGISTER_TYPE_W &&
+                        src_type != BRW_REGISTER_TYPE_UW,
+                        "Immediate source must be integer W or UW type.");
+            }
+         }
+      }
+   }
+
    if (brw_inst_opcode(isa, inst) == BRW_OPCODE_OR ||
        brw_inst_opcode(isa, inst) == BRW_OPCODE_AND ||
        brw_inst_opcode(isa, inst) == BRW_OPCODE_XOR ||
index bb26208..1a78a29 100644 (file)
@@ -3001,3 +3001,110 @@ TEST_P(validation_test, gfx11_no_byte_src_1_2)
       clear_instructions(p);
    }
 }
+
+TEST_P(validation_test, add3_source_types)
+{
+   static const struct {
+      enum brw_reg_type dst_type;
+      enum brw_reg_type src0_type;
+      enum brw_reg_type src1_type;
+      enum brw_reg_type src2_type;
+      bool expected_result;
+   } inst[] = {
+#define INST(dst_type, src0_type, src1_type, src2_type, expected_result)  \
+      {                                                                   \
+         BRW_REGISTER_TYPE_##dst_type,                                    \
+         BRW_REGISTER_TYPE_##src0_type,                                   \
+         BRW_REGISTER_TYPE_##src1_type,                                   \
+         BRW_REGISTER_TYPE_##src2_type,                                   \
+         expected_result,                                                 \
+      }
+
+      INST( F,  F,  F,  F, false),
+      INST(HF, HF, HF, HF, false),
+      INST( B,  B,  B,  B, false),
+      INST(UB, UB, UB, UB, false),
+
+      INST( W,  W,  W,  W, true),
+      INST(UW, UW, UW, UW, true),
+      INST( D,  D,  D,  D, true),
+      INST(UD, UD, UD, UD, true),
+
+      INST( W,  D,  W,  W, true),
+      INST(UW, UW, UD, UW, true),
+      INST( D,  D,  W,  D, true),
+      INST(UD, UD, UD, UW, true),
+#undef INST
+   };
+
+
+   if (devinfo.verx10 < 125)
+      return;
+
+   for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) {
+      brw_ADD3(p,
+               retype(g0, inst[i].dst_type),
+               retype(g0, inst[i].src0_type),
+               retype(g0, inst[i].src1_type),
+               retype(g0, inst[i].src2_type));
+
+      EXPECT_EQ(inst[i].expected_result, validate(p));
+
+      clear_instructions(p);
+   }
+}
+
+TEST_P(validation_test, add3_immediate_types)
+{
+   static const struct {
+      enum brw_reg_type reg_type;
+      enum brw_reg_type imm_type;
+      unsigned imm_src;
+      bool expected_result;
+   } inst[] = {
+#define INST(reg_type, imm_type, imm_src, expected_result)                \
+      {                                                                   \
+         BRW_REGISTER_TYPE_##reg_type,                                    \
+         BRW_REGISTER_TYPE_##imm_type,                                    \
+         imm_src,                                                         \
+         expected_result,                                                 \
+      }
+
+      INST( W,  W,  0, true),
+      INST( W,  W,  2, true),
+      INST(UW, UW,  0, true),
+      INST(UW, UW,  2, true),
+      INST( D,  W,  0, true),
+      INST(UD,  W,  2, true),
+      INST( D, UW,  0, true),
+      INST(UW, UW,  2, true),
+
+      INST( W,  D,  0, false),
+      INST( W,  D,  2, false),
+      INST(UW, UD,  0, false),
+      INST(UW, UD,  2, false),
+      INST( D,  D,  0, false),
+      INST(UD,  D,  2, false),
+      INST( D, UD,  0, false),
+      INST(UW, UD,  2, false),
+#undef INST
+   };
+
+
+   if (devinfo.verx10 < 125)
+      return;
+
+   for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) {
+      brw_ADD3(p,
+               retype(g0, inst[i].reg_type),
+               inst[i].imm_src == 0 ? retype(brw_imm_d(0x1234), inst[i].imm_type)
+                                    : retype(g0, inst[i].reg_type),
+               retype(g0, inst[i].reg_type),
+               inst[i].imm_src == 2 ? retype(brw_imm_d(0x2143), inst[i].imm_type)
+                                    : retype(g0, inst[i].reg_type));
+
+      EXPECT_EQ(inst[i].expected_result, validate(p));
+
+      clear_instructions(p);
+   }
+}