Three fixes to register allocation relating to register formats
Tickets: #26411 (closed), #26526 (closed)
Commit 0: a bugfix for assign_eax_sse_regs
Subsequent commits affect format computations in a way that rendered incorrect the (X86-specific) logic in assign_eax_sse_regs. This preparatory commit makes sure we don't fall over because of that, by casing on the register class rather than the format (and certainly not by using the old logic, is_sse_reg (RegWithFormat _ fmt) = isFloatFormat fmt, which is totally wrong for vectors).
Commit 1: keeping track of formats in liveness analysis
The first commit updates the register allocator to be a bit more careful in situations in which a single register is used at multiple different formats, e.g. when xmm1 is used both to store a Double# and a DoubleX2#.
This is done by introducing the Regs newtype around UniqSet RegWithFormat, for which the combining operations take the larger of the two formats instead of overriding the format.
Further details are in Note [Register formats in liveness analysis] in GHC.CmmToAsm.Reg.Liveness.
This fixes #26526 (closed)
Commit 2: use spilled format when reloading
The second commit ensures we always reload a register at the same width that we spilled it.
Further details are provided in Note [Use spilled format when reloading] in GHC.CmmToAsm.Reg.Linear.
This fixes #26411 (closed).
Commit 3: writes redefine register format
The last commit makes write operations redefine register format in the linear register allocator, fixing the variant of #26411 (closed) provided by @aratamizuki in !15121 (comment 647685).
The overall design is explained in Note [Allocated register formats] in GHC.CmmToAsm.Reg.Linear.