Reading over @igor's changes in 239472, it hit me that the same scheme could be easily extended to implement one of the existing TODOs in the lowering code.
If we have an idiom that looks like assignment (i.e. a new SSA value produced from some operation where it's input is no longer used), we can reuse the stack slot of the original SSA value for the updated value. This works really nicely for GEPs on x86 because we can use an update directly against the stack slot and avoid a fill, modify, spill pattern entirely.
It doesn't work quite as cleanly for deoptimization arguments, mostly because the original spill slot is not reused for the update. I suspect this might be because we're marking the slot as being updated by the previous statepoint, but I decided to separate that into a separate patch. We at least get better stack slot usage, even if we don't yet get ideal code gen.
(The best option would of course be to directly use the register allocator, but a) that's hard, and b) this is an incremental improvement.)
Are you certain about this? I do remember experimenting with this approach, but I was seeing quite the opposite picture - almost no redundant stores were removed. But actually it was quite a while ago and I didn't dig to deep into this, maybe my code had some simple mistake. I will try to run few of my old tests on your code tomorrow.