i965/vec4: fix record clearing in copy propagation

Given

  mov vgrf7, vgrf9.xyxz
  add vgrf9.xyz, vgrf4.xyzw, vgrf5.xyzw
  add vgrf10.x, vgrf6.xyzw, vgrf7.wwww

the last instruction would be wrongly changed to

  add vgrf10.x, vgrf6.xyzw, vgrf9.zzzz

during copy propagation.

The issue is that when deciding if a record should be cleared, the old code
checked for

  inst->dst.writemask & (1 << ch)

instead of

  inst->dst.writemask & (1 << BRW_GET_SWZ(src->swizzle, ch))

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=76749
Signed-off-by: Chia-I Wu <olv@lunarg.com>
Cc: Jordan Justen <jljusten@gmail.com>
Cc: Matt Turner <mattst88@gmail.com>
Reviewed-by: Ian Romainck <ian.d.romanick@intel.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Cc: "10.1" <mesa-stable@freedesktop.org>
This commit is contained in:
Chia-I Wu 2014-04-07 12:31:14 +08:00 committed by Chia-I Wu
parent 57d6e7b7ee
commit 4ddf51db6a

View file

@ -57,6 +57,21 @@ is_dominated_by_previous_instruction(vec4_instruction *inst)
inst->opcode != BRW_OPCODE_ENDIF);
}
static bool
is_channel_updated(vec4_instruction *inst, src_reg *values[4], int ch)
{
const src_reg *src = values[ch];
/* consider GRF only */
assert(inst->dst.file == GRF);
if (!src || src->file != GRF)
return false;
return (src->reg == inst->dst.reg &&
src->reg_offset == inst->dst.reg_offset &&
inst->dst.writemask & (1 << BRW_GET_SWZ(src->swizzle, ch)));
}
static bool
try_constant_propagation(vec4_instruction *inst, int arg, src_reg *values[4])
{
@ -357,11 +372,7 @@ vec4_visitor::opt_copy_propagation()
else {
for (int i = 0; i < virtual_grf_reg_count; i++) {
for (int j = 0; j < 4; j++) {
if (inst->dst.writemask & (1 << j) &&
cur_value[i][j] &&
cur_value[i][j]->file == GRF &&
cur_value[i][j]->reg == inst->dst.reg &&
cur_value[i][j]->reg_offset == inst->dst.reg_offset) {
if (is_channel_updated(inst, cur_value[i], j)){
cur_value[i][j] = NULL;
}
}