Question on using caller saved register around a library call.


For the below test case, I see LLVM allocates an XMM1 register for holding the variable “t”. My understanding is XMM1 is a caller saved register and hence it is spilled to stack and restored back around the library call.



#include <math.h>
double arr[1000000];
int n;
double foo()
double t = 0.0;
for(int i=0;i<100000;i++)
t += log(arr[i]);

return t;


Assembly Snip
.LBB0_1: # =>This Inner Loop Header: Depth=1

#DEBUG_VALUE: foo:t ← 0.000000e+00
vmovupd %ymm1, (%rsp) # 32-byte Spill
.loc 1 8 15 prologue_end # ./example.cpp:8:15
vmovupd arr+800000(%rbx), %ymm0
.loc 1 8 11 is_stmt 0 # ./example.cpp:8:11
callq __svml_log4@PLT
.loc 1 0 11 # ./example.cpp:0:11
vmovupd (%rsp), %ymm1 # 32-byte Reload
.loc 1 8 8 # ./example.cpp:8:8
vaddpd %ymm1, %ymm0, %ymm1
.loc 1 7 26 is_stmt 1 # ./example.cpp:7:26
addq $32, %rbx
jne .LBB0_1

Why is LLVM not choosing a callee saved register here? It can then avoid pushing to the stack and restoring from the stack in the loop.


Is that the case, all XMM, YMM and ZMM are caller saved or scratch only ? As per the ABI, we don’t have any Callee saved registers available?