From: Eric Anholt Date: Mon, 9 Jan 2012 21:30:55 +0000 (-0800) Subject: glsl: Fix copy_propagation_elements bug in handling self-copies. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=057f9ae54b5efb0020cc0c049d50e778de3f3f7a;p=mesa.git glsl: Fix copy_propagation_elements bug in handling self-copies. We were doing the kill of the updated channels, then adding our copy to the list of available stuff to copy. But if the copy was updating its own source channels, we didn't notice, breaking this code: R0.xyzw = arg0 + arg1; R0.xyzw = R0.wwwx; gl_FragColor.xyzw = clamp(R0.xyzw, 0.0, 1.0); Fixes piglit glsl-copy-propagation-self-2. Reviewed-by: Kenneth Graunke --- diff --git a/src/glsl/opt_copy_propagation_elements.cpp b/src/glsl/opt_copy_propagation_elements.cpp index be446bc08ba..ebfd4fd3fe1 100644 --- a/src/glsl/opt_copy_propagation_elements.cpp +++ b/src/glsl/opt_copy_propagation_elements.cpp @@ -461,7 +461,20 @@ ir_copy_propagation_elements_visitor::add_copy(ir_assignment *ir) swizzle[i] = orig_swizzle[j++]; } - entry = new(this->mem_ctx) acp_entry(lhs->var, rhs->var, ir->write_mask, + int write_mask = ir->write_mask; + if (lhs->var == rhs->var) { + /* If this is a copy from the variable to itself, then we need + * to be sure not to include the updated channels from this + * instruction in the set of new source channels to be + * copy-propagated from. + */ + for (int i = 0; i < 4; i++) { + if (ir->write_mask & (1 << orig_swizzle[i])) + write_mask &= ~(1 << i); + } + } + + entry = new(this->mem_ctx) acp_entry(lhs->var, rhs->var, write_mask, swizzle); this->acp->push_tail(entry); }