summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/intel/compiler/brw_fs_reg_allocate.cpp27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/intel/compiler/brw_fs_reg_allocate.cpp b/src/intel/compiler/brw_fs_reg_allocate.cpp
index 5db5242452e..6961cb1caf4 100644
--- a/src/intel/compiler/brw_fs_reg_allocate.cpp
+++ b/src/intel/compiler/brw_fs_reg_allocate.cpp
@@ -695,6 +695,33 @@ fs_visitor::assign_regs(bool allow_spilling, bool spill_all)
}
}
+ /* From the Skylake PRM Vol. 2a docs for sends:
+ *
+ * "It is required that the second block of GRFs does not overlap with
+ * the first block."
+ *
+ * Normally, this is taken care of by fixup_sends_duplicate_payload() but
+ * in the case where one of the registers is an undefined value, the
+ * register allocator may decide that they don't interfere even though
+ * they're used as sources in the same instruction. We also need to add
+ * interference here.
+ */
+ if (devinfo->gen >= 9) {
+ foreach_block_and_inst(block, fs_inst, inst, cfg) {
+ if (inst->opcode == SHADER_OPCODE_SEND && inst->ex_mlen > 0 &&
+ inst->src[2].file == VGRF &&
+ inst->src[3].file == VGRF &&
+ inst->src[2].nr != inst->src[3].nr) {
+ for (unsigned i = 0; i < inst->mlen; i++) {
+ for (unsigned j = 0; j < inst->ex_mlen; j++) {
+ ra_add_node_interference(g, inst->src[2].nr + i,
+ inst->src[3].nr + j);
+ }
+ }
+ }
+ }
+ }
+
/* Debug of register spilling: Go spill everything. */
if (unlikely(spill_all)) {
int reg = choose_spill_reg(g);