diff --git a/src/intel/compiler/brw_fs.cpp b/src/intel/compiler/brw_fs.cpp index 20b89035e1f..5b87991652d 100644 --- a/src/intel/compiler/brw_fs.cpp +++ b/src/intel/compiler/brw_fs.cpp @@ -5115,6 +5115,25 @@ get_fpu_lowered_simd_width(const struct gen_device_info *devinfo, } } + if (devinfo->gen < 6) { + /* From the G45 PRM, Volume 4 Page 361: + * + * "Operand Alignment Rule: With the exceptions listed below, a + * source/destination operand in general should be aligned to even + * 256-bit physical register with a region size equal to two 256-bit + * physical registers." + * + * Normally we enforce this by allocating virtual registers to the + * even-aligned class. But we need to handle payload registers. + */ + for (unsigned i = 0; i < inst->sources; i++) { + if (inst->src[i].file == FIXED_GRF && (inst->src[i].nr & 1) && + inst->size_read(i) > REG_SIZE) { + max_width = MIN2(max_width, 8); + } + } + } + /* From the IVB PRMs: * "When an instruction is SIMD32, the low 16 bits of the execution mask * are applied for both halves of the SIMD32 instruction. If different @@ -6321,6 +6340,7 @@ fs_visitor::optimize() if (OPT(lower_load_payload)) { split_virtual_grfs(); OPT(register_coalesce); + OPT(lower_simd_width); OPT(compute_to_mrf); OPT(dead_code_eliminate); }