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);