It turns out DBG_VALUEs would be sunk even if the variables location was re-specified in the block, so for example in:
%0 = someinst DBG_VALUE %0, !123, !DIExpression() %1 = anotherinst DBG_VALUE %1, !123, !DIExpression()
if %0 were to sink, the corresponding DBG_VALUE would sink too, past the next DBG_VALUE, effectively re-ordering assignments.
To fix these things: I've added a SeenDbgVars set recording what variable locations have been seen in a block already (working bottom up), and now flag DBG_VALUEs that would pass a later DBG_VALUE for the same variable.
If such a DBG_VALUE has its operand sunk, then it will now be set to undef, if it can't be copy propagated. I've split out the copy-prop code into a helper function to ease this. This patch is based on a tree with f5e1b718a6 reapplied to make it easier to read.
NB, this only works for repeated DBG_VALUEs in the same basic block, the general case involving control flow is much harder, which I've written up in .