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:
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
mov.w &b, r11
add.w &a, r11
sub.w r11, &r
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 = MOV16rm %reg0, ga:b; mem:LD2[@b]
register: %reg1028 +[6,14:0)
12 %reg1029 = MOV16rr %reg1028
register: %reg1029 +[14,30:0)
20 %reg1029 = ADD16rm %reg1029, %reg0, ga:a, %SRW; mem:LD2[@a]
register: %reg1029 replace range with [14,22:1) RESULT: %reg1029,0.000000e+00 = [14,22:1)[22,30:0) 0@22-(30) 1@14-(22)
28 SUB16mr %reg0, ga:r, %reg1029, %SRW; mem:ST2[@r] LD2[@r]
Any help or hints would be much welcome !
test_unused_regs.ll (909 Bytes)
test_unused_regs.c (115 Bytes)