[llvm-dev] Finding caller-saved registers at a function call site

Rob Lyerly via llvm-dev llvm-dev at lists.llvm.org
Mon Jun 27 07:28:45 PDT 2016

Hi Sanjoy,

I'm having trouble finding caller-saved registers using the RegMask operand
you've mentioned.  As an example, I've got a C function that looks like

double recurse(int depth, double val)
    if(depth < max_depth) return recurse(depth + 1, val * 1.2) + val;
    else return outer_func(val);

As a quick refresher, all "xmm" registers are considered caller-saved on
x86, hence values stored in these registers should be spilled to the stack
before a function call.  The generated assembly for branch containing the
call to "recurse" with clang/LLVM 3.8 (-O3) on Ubuntu 14.04 looks like this:

400694:       ff c7                   inc    %edi                   # Add 1
to depth
400696:       f2 0f 10 05 a2 92 05    movsd  0x592a2(%rip),%xmm0    # Move
constant 1.2 into xmm0
40069d:       00
40069e:       f2 0f 59 c1             mulsd  %xmm1,%xmm0            # val *
4006a2:       f2 0f 11 4d f8          movsd  %xmm1,-0x8(%rbp)       # Spill
val to the stack
4006a7:       e8 d4 ff ff ff          callq  400680 <recurse>
4006ac:       f2 0f 58 45 f8          addsd  -0x8(%rbp),%xmm0       #
recurse's return value + val
4006b1:       48 83 c4 10             add    $0x10,%rsp
4006b5:       5d                      pop    %rbp
4006b6:       c3                      retq

Notice how xmm1 (the storage location of "val", which is live across the
call to recurse) is saved onto the stack at an offset of -8 from the base
pointer.  After the call, "val" (i.e., storage location rbp - 0x8) is used
in the addition to calculate the returned value.  However, when I print the
RegMask operand for the call machine instruction, I get the following:

<regmask %BH %BL %BP %BPL %BX %EBP %EBX %RBP %RBX %R12 %R13 %R14 %R15 %R12B
%R13B %R14B %R15B %R12D %R13D %R14D %R15D %R12W %R13W %R14W %R15W>

I don't see xmm1 as being preserved across this call.  Am I missing
something?  Thanks for your help!

On Wed, Jun 22, 2016 at 5:01 PM, Sanjoy Das <sanjoy at playingwithpointers.com>

> Hi Rob,
> Rob Lyerly via llvm-dev wrote:
> > I'm looking for a way to get all the caller-saved registers (both the
> > register and the stack slot at which it was saved) for a given function
> > call site in the backend.  What's the best way to grab this
> > information?  Is it possible to get this information if I have the
> > MachineInstr of the function call?  I'm currently targeting the AArch64
> > & X86 backends.
> You should be able to use the RegMask operand to the MachineInstr to
> discover the registers that are preserved or clobbered by the call
> according to the calling convention.  For reference, you might want to
> look at `getRegMask` and `gatherMaximalPreservedRegisters` in
> http://reviews.llvm.org/D21115.
> As far as discovering the slot to which it is spilled, I have no idea.
> CC'ing Matthias for this.
> -- Sanjoy

Rob Lyerly
Graduate Research Assistant, Systems Software Research Group
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160627/7a5e8d40/attachment-0001.html>

More information about the llvm-dev mailing list