Unused argument registers can not be reused ?

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;

void

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

test:

push.w r11

mov.w &b, r11

add.w &a, r11

sub.w r11, &r

pop.w r11

ret

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]

40 RET

Any help or hints would be much welcome !

Best regards,

test_unused_regs.ll (909 Bytes)

test_unused_regs.c (115 Bytes)

It looks like you found a bug, R12-R15 should be usable inside the function.

Please file a PR against the code generator.

I think that unused arguments shouldn't have been marked live in at all.

Thanks,
/jakob

Oops. Forgot the mailing list in the reply.