[LLVMdev] Unused argument registers can not be reused ?

Arnaud Allard de Grandmaison Arnaud.AllardDeGrandMaison at dibcom.com
Thu Jun 3 06:33:15 PDT 2010

While migrating my codebase from llvm-2.6 to llvm-2.7, I found a different behaviour in the register allocation. I have been able to reproduce it using the msp430 backend, with the 2.7 release as well as the svn head.

For the msp430, the first four parameters of a function are passed thru registers. What I observe is that if those parameters are not used inside the function, those registers can not be used.

For example, with the following C code:
> cat test_unused_regs.c
short a = 2;
short b = 32;
short r = 1024;

test(short w, short x, short y, short z)
  r -= a+b;

I get the following assembly code for the test function after running thru clang:
> clang -ccc-host-triple msp430-unknown-unknown -O2 -fomit-frame-pointer -S -o test_unused_regs.s test_unused_regs.c
> cat test_unused_regs.s
      push.w      r11
      mov.w &b, r11
      add.w &a, r11
      sub.w r11, &r
      pop.w r11

Instead of using r11, llvm should have used r12/r13/r14 or r15. This was my expectation, and the behaviour with llvm-2.6. This would have spared saving/restoring r11.

Although this is not a functionnal regression, this looks to me like a performance regression, unless the calling convention has changed (i.e. the arguments can not be clobbered anymore).

I have not yet understood why, but the liveIntervals analysis dump looks dubious to me (R12W,R13W,R14W and R15W should be dead/killed livein registers) :
> llc -march=msp430 -debug-only=liveintervals -o test_unused_regs.s test_unused_regs.ll
********** COMPUTING LIVE INTERVALS **********
********** Function: test
BB#0:       # derived from entry
            livein register: R15W live through +[0,40:0)
            livein register: R15B dead +[0,3:0)
            livein register: R14W live through +[0,40:0)
            livein register: R14B dead +[0,3:0)
            livein register: R13W live through +[0,40:0)
            livein register: R13B dead +[0,3:0)
            livein register: R12W live through +[0,40:0)
            livein register: R12B dead +[0,3:0)
4     %reg1028<def> = MOV16rm %reg0, <ga:@b>; mem:LD2[@b]
            register: %reg1028 +[6,14:0)
12    %reg1029<def> = MOV16rr %reg1028<kill>
            register: %reg1029 +[14,30:0)
20    %reg1029<def> = ADD16rm %reg1029, %reg0, <ga:@a>, %SRW<imp-def>; mem:LD2[@a]
            register: %reg1029 replace range with [14,22:1) RESULT: %reg1029,0.000000e+00 = [14,22:1)[22,30:0)  0 at 22-(30) 1 at 14-(22)
28    SUB16mr %reg0, <ga:@r>, %reg1029<kill>, %SRW<imp-def>; mem:ST2[@r] LD2[@r]
40    RET

Any help or hints would be much welcome !

Best regards,
Arnaud de Grandmaison
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100603/1db8a188/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test_unused_regs.ll
Type: application/octet-stream
Size: 909 bytes
Desc: test_unused_regs.ll
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100603/1db8a188/attachment.obj>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: test_unused_regs.c
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100603/1db8a188/attachment.c>

More information about the llvm-dev mailing list