I think you don't want to do register coalescing for argument passing moves from virtual register to argument register regarding function call actual arguments (or, for function call formal arguments copied vice versa on function entry) before register allocation.
However, when you see such a move, you can tag a hint to the allocator that that move target argument register is the preferred choice. When the preferred choice doesn't interfere appropriately*, you can use it for the allocation, with the result that after allocation you'll have a move rx,rx
, which you can easily eliminate later.
(Of course, you may find more than one such hint, so then you take the most applicable one, most (and often all) of them will be ruled out from other interference: same register passed to multiple calls; call in a loop, etc..)
(*appropriately means that the argument (real) register isn't otherwise used or trashed in during the lifetime of the virtual register, e.g. by a nested function call or some other. (Identifying this can be as easy as inspecting interferences of the virtual register.))