[LLVMdev] Spilling of partly (un)defined registers

Patrik Hägglund patrik.h.hagglund at ericsson.com
Thu Jan 5 06:39:09 PST 2012


Hi,

I have a problem in our 3.0-based backend that I'm not sure how it 
should be handled.

In summary, I don't know if
* The regalloc verifier is too picky?
* The register allocator is at fault for spilling the full register when
only parts of it are defined?
* Something else?

The architecture I'm compiling for has registers with three disjoint
parts: g, h and l. In one function we receive a value that resides in
the g and h part of a register.

# *** IR Dump Before Linear Scan Register Allocator ***:
# Machine code for function accumconv:
Function Live Ins: %a0_gh in %vreg0, %a1_gh in %vreg1

BB#0: derived from LLVM BB %0
Live Ins: %a0_gh %a1_gh

%vreg1<def>  = COPY %a1_gh; aNgh_0_7:%vreg1

[...]

%vreg56<def>  = mv_any16 0; aNl_0_7:%vreg56
%vreg57<def>  = REG_SEQUENCE %vreg1, hi24, %vreg56, lo16;
aN40_0_7:%vreg57 aNgh_0_7:%vreg1 aNl_0_7:%vreg56

So the in-argument in a1_gh is saved in vreg1, and used later in a
REG_SEQUENCE instruction to write a full register, vreg57.

After the REG_SEQUENCE has been eliminated we instead get

16 %vreg57:hi24<def>  = COPY %a1_gh<kill>; aN40_0_7:%vreg57
[...]
832 %vreg57:lo16<def>  = mv_any16 0; aN40_0_7:%vreg57

So both REG_SEQUENCE and the temporary vreg1 have been removed, and
a1_gh is written directly at the right place in vreg57 in the function
entry and the l part of vreg57 is written much later.

During register allocation a new temporary vreg59 seems to be introduced 
for some part of vreg57 and we get

16L %vreg59:hi24<def,undef>  = COPY %a1_gh<kill>, %vreg59<imp-def>;
aN40_0_7:%vreg59

Due to high register pressure vreg59 is spilled

**** Local spiller rewriting MBB '':
%vreg59:hi24<def,undef>  = COPY %a1_gh<kill>, %vreg59<imp-def>;
aN40_0_7:%vreg59
Store: Store40FI %a1_40<kill>,<fi#0>;
mem:ST6[FixedStack0](align=2)

And now the verifier complains:

*** Bad machine code: Using an undefined physical register ***
- function: accumconv
- basic block: 0x97baae0 (BB#0)
- instruction: Store40FI %a1_40<kill>,<fi#0>;
mem:ST6[FixedStack0](align=2)
- operand 0: %a1_40<kill>
LLVM ERROR: Found 1 machine code errors.

Since the g and h parts of a1 are live in to the function I suppose that 
the issue here is that we have a use of the full a1 register in the 
spill instruction Store40FI, while the l part of it is undefined.



More information about the llvm-dev mailing list