2/4 seems to be doing two things: one is, as declared in the subject, dividing by four `deref->offset` (BTW, what is the reason? Maybe that should be explained in the commit message); the other is introducing `offset_const` and partially populating it in `new_offset_instr_from_deref()`. Could these two be splitted?
Right, I am splitting the patch in two and adding an explanation to the patch description. The main reason for these changes is that SM4 relative addressing (using a register as an index of a src or dst register) is done with a whole-register granularity, so we store the register-component part of the offset with this new uint. Also, storing the offset in this way (node + uint) allows us to latter move all the offset to the uint in case the node is constant (what 3/4 does), removing the offset nodes and making the IR more readable.
WRT Zeb's comment, I also think that the current implementation is a bit more complicated than it should be. But I think that a simpler implementation might be acceptable. What I would do is to avoid touching `offset_const` in `new_offset_instr_from_deref()`, and rather have `clean_constant_deref_offset_srcs()` from 3/4 shove every additive constant it can find into `offset_const` (basically to recurse on both arguments as long as you find `HLSL_OP2_ADD` expressions, and remove all the addends that are constants, adding them to `offset_const`).
Does this make sense to you?
I don't think that idea would be better. The offset node, if it is to contain all the offset information until `clean_constant_deref_offset_srcs()`, would have to be in components and not in whole-registers, which means we would have to introduce HLSL_OP2_DIVs to get a node in whole-registers. Also, it may be a little brittle, since we would be asserting that we are always capable of extracting the component part of the offset as a constant there.