Destination register needs to be valid after callee saved register restore when tail calling

Hello list,

i am currently trying to implement tail call optimization in the X86 backend , so far i have it working for cases (modulo many unknown bugs :slight_smile: where the tail called function is a destination within the source file and frame pointer elimination is performed. i implemented it as a dagcombiner transformation running in post legalized phase within the X86TargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI). now to my problem:

When tail calling a function pointer the register the function pointer was loaded to might be invalidated by the restored callee saved registers.

  ...
  movl 12(%esp), %esi << 12(%esp) contains the function pointer
  movl %eax, 44(%esp)
  movl 32(%esp), %esi << *!# %esi no longer contains the function pointer to be called
  addl $44, %esp
   jmp *%esi # TAIL CALL jmpr

Is there a way to indicate that the register the tail call instruction uses as destination needs to be valid after the callee saved registers have been restored? (some X86InstrInfo.td foo magic maybe ?)
Or do i have to insert code into PEI::saveCalleeSavedRegisters to detect that there is a tail called function that uses a callee saved register and move it to another (EAX).

that's how the TAILJMP instruction looks:
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, noResults = 1 in
   def TAILJMPr : I<0xFF, MRM4r, (ops GR32:$dst), "jmp {*}$dst # TAIL CALL jmpr",
                  []>;

btw. i am currently working with llvm-2.0 codebase.

thanks for any help

regards arnold

Inserting a pseudo before your tail call that defines all the callee-saved
registers should work. See FP_REG_KILL.