intel/eu: Handle compaction when inserting validation errors
authorKenneth Graunke <kenneth@whitecape.org>
Tue, 19 Jul 2022 07:27:29 +0000 (00:27 -0700)
committerMarge Bot <emma+marge@anholt.net>
Thu, 28 Jul 2022 21:31:45 +0000 (21:31 +0000)
When the EU validator encountered an error, it would add an annotation
to the disassembly.  Unfortunately, the code to insert an error assumed
that the next instruction would start at (offset + sizeof(brw_inst)),
which is not true if the instruction with an error is compacted.

This could lead to cascading disassembly errors, where we started trying
to decode the next instruction at the wrong offset, and getting lots of
scary looking output:

   ERROR: Register Regioning patterns where [...]
   (-f0.1.any16h) illegal(*** invalid execution size value 6 )      { align1 $7.src atomic };
   (+f0.1.any16h) illegal.sat(*** invalid execution size value 6 )  { align1 $9.src AccWrEnable };
   illegal(*** invalid execution size value 6 )                     { align1 $11.src };
   (+f0.1) illegal.sat(*** invalid execution size value 6 )         { align1 F@2 AccWrEnable };
   (+f0.1) illegal.sat(*** invalid execution size value 6 )         { align1 F@2 AccWrEnable };
   (+f0.1) illegal.sat(*** invalid execution size value 6 )         { align1 $15.src AccWrEnable };
   illegal(*** invalid execution size value 6 )                     { align1 $15.src };
   (+f0.1) illegal.sat.g.f0.1(*** invalid execution size value 6 )  { align1 $13.src AccWrEnable };

Only the first instruction was actually wrong - the rest are just a
result of starting the disassembler at the wrong offset.  Trash ensues!

To fix this, just pass the instruction size in a few layers so we can
record the next offset properly.

Cc: mesa-stable
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17624>

src/intel/compiler/brw_disasm_info.c
src/intel/compiler/brw_disasm_info.h
src/intel/compiler/brw_eu.h
src/intel/compiler/brw_eu_validate.c
src/intel/compiler/test_eu_compact.cpp

index 779e25f..9ee365f 100644 (file)
@@ -170,7 +170,7 @@ disasm_annotate(struct disasm_info *disasm,
 
 void
 disasm_insert_error(struct disasm_info *disasm, unsigned offset,
-                    const char *error)
+                    unsigned inst_size, const char *error)
 {
    foreach_list_typed(struct inst_group, cur, link, &disasm->group_list) {
       struct exec_node *next_node = exec_node_get_next(&cur->link);
@@ -183,7 +183,7 @@ disasm_insert_error(struct disasm_info *disasm, unsigned offset,
       if (next->offset <= offset)
          continue;
 
-      if (offset + sizeof(brw_inst) != next->offset) {
+      if (offset + inst_size != next->offset) {
          struct inst_group *new = ralloc(disasm, struct inst_group);
          memcpy(new, cur, sizeof(struct inst_group));
 
@@ -191,7 +191,7 @@ disasm_insert_error(struct disasm_info *disasm, unsigned offset,
          cur->error_length = 0;
          cur->block_end = NULL;
 
-         new->offset = offset + sizeof(brw_inst);
+         new->offset = offset + inst_size;
          new->block_start = NULL;
 
          exec_node_insert_after(&cur->link, &new->link);
index c45b98a..937180b 100644 (file)
@@ -81,7 +81,7 @@ disasm_annotate(struct disasm_info *disasm,
 
 void
 disasm_insert_error(struct disasm_info *disasm, unsigned offset,
-                    const char *error);
+                    unsigned inst_size, const char *error);
 
 #ifdef __cplusplus
 } /* extern "C" */
index 72c0bc8..e27b506 100644 (file)
@@ -1883,6 +1883,7 @@ void brw_debug_compact_uncompact(const struct brw_isa_info *isa,
 /* brw_eu_validate.c */
 bool brw_validate_instruction(const struct brw_isa_info *isa,
                               const brw_inst *inst, int offset,
+                              unsigned inst_size,
                               struct disasm_info *disasm);
 bool brw_validate_instructions(const struct brw_isa_info *isa,
                                const void *assembly, int start_offset, int end_offset,
index 4c26889..0db30a4 100644 (file)
@@ -2270,6 +2270,7 @@ send_descriptor_restrictions(const struct brw_isa_info *isa,
 bool
 brw_validate_instruction(const struct brw_isa_info *isa,
                          const brw_inst *inst, int offset,
+                         unsigned inst_size,
                          struct disasm_info *disasm)
 {
    struct string error_msg = { .str = NULL, .len = 0 };
@@ -2295,7 +2296,7 @@ brw_validate_instruction(const struct brw_isa_info *isa,
    }
 
    if (error_msg.str && disasm) {
-      disasm_insert_error(disasm, offset, error_msg.str);
+      disasm_insert_error(disasm, offset, inst_size, error_msg.str);
    }
    free(error_msg.str);
 
@@ -2323,7 +2324,8 @@ brw_validate_instructions(const struct brw_isa_info *isa,
          inst = &uncompacted;
       }
 
-      bool v = brw_validate_instruction(isa, inst, src_offset, disasm);
+      bool v = brw_validate_instruction(isa, inst, src_offset,
+                                        inst_size, disasm);
       valid = valid && v;
 
       src_offset += inst_size;
index fde3747..59ad71f 100644 (file)
@@ -189,7 +189,7 @@ test_fuzz_compact_instruction(struct brw_codegen *p, brw_inst src)
 
          clear_pad_bits(p->isa, &instr);
 
-         if (!brw_validate_instruction(p->isa, &instr, 0, NULL))
+         if (!brw_validate_instruction(p->isa, &instr, 0, sizeof(brw_inst), NULL))
             continue;
 
         if (!test_compact_instruction(p, instr)) {