Problems with live intervals and spilling when having sub registers?


I'm having some trouble understanding if the live intervals calculated for one of my testcases are correct or not.

I have the following instructions:

272L %vreg67:lo<def> = mv_any16 65535; R:%vreg67
288L %vreg64:hi<def> = mv_any16 16383; R:%vreg64
304L %vreg64:lo<def> = COPY %vreg67:lo; R:%vreg64,%vreg67
320L %vreg6<def> = COPY %vreg64<kill>; R:%vreg6,%vreg64

So, %vreg64, which has two (disjunct) sub registers, gets its two parts written at 288 and 304, and then the whole %vreg64 is copied to %vreg6 at 320. And for this I get the following intervals for %vreg64:

   %vreg64 = [288d,304d:1)[304d,320d:0) 0@304d 1@288d

Later %vreg6 and %vreg64 are merged. The register allocator spills
%vreg6 (fi#14) and the resulting code is

%r0l<def> = mv_any16 65535
Store32FI %r0<kill>, <fi#14>; mem:ST4[FixedStack14] %r0h<def> = mv_any16 16383 %r1<def> = Load32FI <fi#14>; mem:LD4[FixedStack14]

So the whole %r0 register is spilled to the stack after only one half is written, and then what is supposed to go into the other half is never used. Instead the previously written value is reloaded from the stack.

I don't know what the live intervals above should look like in the case when the involved register has sub registers, but it looks suspicious to me. And if the intervals are indeed as intended, then I suppose the handling of them in the register allocator have some flaws.

I'm running on version 2.9 using the linear scan allocator.

Patrik Hägglund