Strange spill behaviour


While working some more on the backend, I’ve added callee register saving and have come across something odd (I assume its because i’ve not implemented something), this is with optimisations which makes it even more odd :

MOV.L [R7+ 12], R1 ; 4-byte Folded Spill
MOV.L [R7+ 8], R2 ; 4-byte Folded Spill
ADD.L R0,R0 + R1
ADD.L R0,R0 + #7
SUB.L R0,R0 - R2
MOV.L R2, [R7+ 8] ; 4-byte Folded Reload
MOV.L R1, [R7+ 12] ; 4-byte Folded Reload

I’ve isolated the epilogue and prologue away from the function (they don’t make use of R1 or R2, Calling convention states R0-R3 are used as inputs to a function. R1-R4 are marked as calleesaved. From the above code I cannot see any reason why R1 & R2 are being spilled, I assume the fault lies in my tablegen definitions (relevant ones reproduced below) :

let isCommutable=1 in
def ADD32rrr : M819Inst<(outs GR32:$dst),(ins GR32:$src1, GR32:$src2),“ADD.L\t{$dst,$src1 + $src2}”,[(set GR32:$dst, (add GR32:$src1, GR32:$src2))]>;
def ADD32rri : M819Inst<(outs GR32:$dst),(ins GR32:$src1, i32imm:$src2),“ADD.L\t{$dst,$src1 + $src2}”,[(set GR32:$dst, (add GR32:$src1, imm:$src2))]>;

def SUB32rrr : M819Inst<(outs GR32:$dst),(ins GR32:$src1, GR32:$src2),“SUB.L\t{$dst,$src1 - $src2}”,[(set GR32:$dst, (sub GR32:$src1, GR32:$src2))]>;

def MOV32rm : M819Inst<(outs GR32:$dst), (ins memsrc:$src),“MOV.L\t{$dst, [$src]}”,[(set GR32:$dst,(load addr:$src))]>;

def MOV32mr : M819Inst<(outs), (ins memdst:$dst, GR32:$src),“MOV.L\t{[$dst], $src}”,[(store GR32:$src, addr:$dst)]>;

Am I misunderstanding something here?


This is not enough information to help you. Try llc -debug-only=regalloc.


Those spills and reloads are not created by the register allocator, they are inserted by PrologEpilogInsertion, presumably because you have declared them as callee saved.

Does your target really use R1 and R2 for function arguments AND require them to be callee saved?