Commit 11260cc5 authored by Francisco Jerez's avatar Francisco Jerez

i965/fs: Set exec_all on spills not matching the channel layout of the instruction.

This prevents the application of an incorrect channel mask by the
scratch write instruction for spilled variables that don't have an
exact one-to-one correspondence between channels of the variable and
32-bit components of the scratch write instruction.
Reviewed-by: Jason Ekstrand's avatarJason Ekstrand <jason@jlekstrand.net>
parent bb67c467
......@@ -977,14 +977,27 @@ fs_visitor::spill_reg(int spill_reg)
const unsigned width =
dispatch_width == 16 && inst->regs_written % 2 == 0 ? 16 : 8;
/* Spills should only write data initialized by the instruction for
* whichever channels are enabled in the excution mask. If that's
* not possible we'll have to emit a matching unspill before the
* instruction and set force_writemask_all on the spill.
*/
const bool per_channel =
inst->dst.is_contiguous() && type_sz(inst->dst.type) == 4 &&
inst->exec_size == width;
/* Builder used to emit the scratch messages. */
const fs_builder ubld = ibld.group(width, 0);
const fs_builder ubld = ibld.exec_all(!per_channel).group(width, 0);
/* If our write is going to affect just part of the
* inst->regs_written(), then we need to unspill the destination
* since we write back out all of the regs_written().
* since we write back out all of the regs_written(). If the
* original instruction had force_writemask_all set and is not a
* partial write, there should be no need for the unspill since the
* instruction will be overwriting the whole destination in any case.
*/
if (inst->is_partial_write())
if (inst->is_partial_write() ||
(!inst->force_writemask_all && !per_channel))
emit_unspill(ubld, spill_src, subset_spill_offset,
inst->regs_written);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment