From: Jason Ekstrand Date: Tue, 16 Sep 2014 23:34:23 +0000 (-0700) Subject: i965/fs: Fix a bug in register coalesce X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=27d7ef094a55d6aeac22a11f20a9e819af4dd633;p=mesa.git i965/fs: Fix a bug in register coalesce This commit fixes a bug in register coalesce that happens when one register is moved to another the proper number of times but the channels are re-arranged. When this happens, the previous code would happily coalesce the registers regardless of the fact that the channel mappins were wrong. Signed-off-by: Jason Ekstrand Reviewed-by: Matt Turner --- diff --git a/src/mesa/drivers/dri/i965/brw_fs_register_coalesce.cpp b/src/mesa/drivers/dri/i965/brw_fs_register_coalesce.cpp index 9546dcdf06a..69d105a85c9 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_register_coalesce.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_register_coalesce.cpp @@ -200,6 +200,16 @@ fs_visitor::register_coalesce() channels_remaining -= inst->regs_written; } else { const int offset = inst->src[0].reg_offset; + if (mov[offset]) { + /* This is the second time that this offset in the register has + * been set. This means, in particular, that inst->dst was + * live before this instruction and that the live ranges of + * inst->dst and inst->src[0] overlap and we can't coalesce the + * two variables. Let's ensure that doesn't happen. + */ + channels_remaining = -1; + continue; + } reg_to_offset[offset] = inst->dst.reg_offset; if (inst->src[0].width == 16) reg_to_offset[offset + 1] = inst->dst.reg_offset + 1; @@ -212,6 +222,13 @@ fs_visitor::register_coalesce() bool can_coalesce = true; for (int i = 0; i < src_size; i++) { + if (reg_to_offset[i] != reg_to_offset[0] + i) { + /* Registers are out-of-order. */ + can_coalesce = false; + reg_from = -1; + break; + } + var_to[i] = live_intervals->var_from_vgrf[reg_to] + reg_to_offset[i]; var_from[i] = live_intervals->var_from_vgrf[reg_from] + i;