https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64164
--- Comment #14 from Jeffrey A. Law <law at redhat dot com> --- So, forgive me, but is -DOPT supposed to be the good or the bad code? >From looking at the results I get, -DOPT is supposed to be the good code, but that seems to conflict with c#6. For -DOPT I get this PHI: # _28 = PHI <0(2), _29(3), _29(7), _10(8), _29(6)> For -UOPT I get this: # _28 = PHI <0(2), value_29(3), value_29(7), _10(8), value_29(6)> Note that _10 from BB 8 is known to have the value 0. That equivalency comes from the path 2->3->4->8. Coalescing _10 with anything is probably the least interesting. Coalescing _28 and _29 seems more profitable. Would we get better code if we left the constant in place? Can we come up with a reasonable heuristic to determine if we're better off with _10 or the constant in that PHI argument? Right now uncprop will always replace a constant with an SSA_NAME having the right value if the SSA_NAME could potentially coalesce with the result of the PHI. The theory being that a constant will always need initialization, but if the SSA_NAME coalesces with the result, then the SSA_NAME will likely be "free". The obvious exception is when that coalescing prevents other things from coalescing. I also wonder if we could be cleaning things up in RTL to make this less of an issue. For example, would optimizing the obvious tail-merge/crossjump earlier in the RTL pipeline help the register allocator coalesce things better?