I didn't thought of making `copy_propagation_compute_replacement()` and `copy_propagation_compute_load_constant_replacement()` replace the instruction themselves while calling `copy_propagation_compute_replacement()` directly from `copy_propagation_transform_object_load()`, that makes the code more clear and makes us avoid the output swizzle argument. So I think it is a very good arrangement of the solution.
To be fair, I didn't either immediately; I had to play around with the code for a bit :-)
Also, I think the included comment is a good summary of all this conundrum! I would rewrote the pseudo code examples to make them more clear, using one line for each instruction:
X is stored to V There is a load from V
X (constant) is stored to a part of V Y (constant) is stored to another part of V There is a load from V
Perhaps, although I was also writing them in terms of actual IR instructions, so I'd at least visually separate the constant and store instructions no matter how it's written.