Module: Mesa
Branch: main
Commit: 8f8cde4c6050d1e91101ec66e8982036da9d7700
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=8f8cde4c6050d1e91101ec66e8982036da9d7700

Author: Sviatoslav Peleshko <sviatoslav.peles...@globallogic.com>
Date:   Fri Oct 13 05:02:22 2023 +0300

intel/fs: Don't optimize DW*1 MUL if it stores value to the accumulator

Fixes: a8b86459 ("i965/fs: Optimize a * 1.0 -> a.")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/9570
Signed-off-by: Sviatoslav Peleshko <sviatoslav.peles...@globallogic.com>
Reviewed-by: Ian Romanick <ian.d.roman...@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25710>

---

 src/intel/compiler/brw_fs.cpp | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/src/intel/compiler/brw_fs.cpp b/src/intel/compiler/brw_fs.cpp
index 9dd660a1a81..ce43e53f2d3 100644
--- a/src/intel/compiler/brw_fs.cpp
+++ b/src/intel/compiler/brw_fs.cpp
@@ -2444,6 +2444,29 @@ fs_visitor::opt_algebraic()
          if (brw_reg_type_is_floating_point(inst->src[1].type))
             break;
 
+         /* From the BDW PRM, Vol 2a, "mul - Multiply":
+          *
+          *    "When multiplying integer datatypes, if src0 is DW and src1
+          *    is W, irrespective of the destination datatype, the
+          *    accumulator maintains full 48-bit precision."
+          *    ...
+          *    "When multiplying integer data types, if one of the sources
+          *    is a DW, the resulting full precision data is stored in
+          *    the accumulator."
+          *
+          * There are also similar notes in earlier PRMs.
+          *
+          * The MOV instruction can copy the bits of the source, but it
+          * does not clear the higher bits of the accumulator. So, because
+          * we might use the full accumulator in the MUL/MACH macro, we
+          * shouldn't replace such MULs with MOVs.
+          */
+         if ((brw_reg_type_to_size(inst->src[0].type) == 4 ||
+              brw_reg_type_to_size(inst->src[1].type) == 4) &&
+             (inst->dst.is_accumulator() ||
+              inst->writes_accumulator_implicitly(devinfo)))
+            break;
+
          /* a * 1.0 = a */
          if (inst->src[1].is_one()) {
             inst->opcode = BRW_OPCODE_MOV;

Reply via email to