<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - [X86_64] Variadic functions unconditionally spill %XMM registers"
href="https://bugs.llvm.org/show_bug.cgi?id=42219">42219</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>[X86_64] Variadic functions unconditionally spill %XMM registers
</td>
</tr>
<tr>
<th>Product</th>
<td>new-bugs
</td>
</tr>
<tr>
<th>Version</th>
<td>8.0
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>new bugs
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>salim.nasser@windriver.com
</td>
</tr>
<tr>
<th>CC</th>
<td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>Created <span class=""><a href="attachment.cgi?id=22082" name="attach_22082" title="Testcase">attachment 22082</a> <a href="attachment.cgi?id=22082&action=edit" title="Testcase">[details]</a></span>
Testcase
The X86_64 ABI provides a way to determine at runtime whether any "vector"
registers (e.g. SSE XMM registers) have been used to pass arguments to a
variadic function. Specifically the incoming value of %al is non-zero in this
case.
This allows variadic functions to avoid referencing XMM registers unless the
caller "expects" such a use.
LLVM correctly guards the va_start code to save %XMM registers with a test of
%al.
Unfortunately, when compiling without optimization, the va_start setup code is
itself done in several parts:
1. Spill registers to temporary stack slots
2. Reload registers from stack
3. Store reloaded values to varargs area
Unfortunately (1) is done unconditionally, i.e. regardless of the outcome of
the %al test. Here's an extract from the attached variadic.s:
##### ABI defined test: %al non-zero if any vector registers used for
arguments
testb %al, %al
##### But the following %xmm spills run regardless of the result of the
previous test!
movaps %xmm7, -224(%rbp) # 16-byte Spill
movaps %xmm6, -240(%rbp) # 16-byte Spill
...
##### Skip following code if no floating point arguments
je .LBB0_2
# %bb.1:
##### The following is the "regular" varargs spill code and is only run
when vector argument registers are used
##### Restore original value of %xmm from stack ...
movaps -336(%rbp), %xmm0 # 16-byte Reload
##### ... and store in varargs area
movaps %xmm0, -160(%rbp)
movaps -320(%rbp), %xmm1 # 16-byte Reload
movaps %xmm1, -144(%rbp)
...
Specifically this behavior may become a problem for OS kernel code compiled
with -no-implicit-float when <a class="bz_bug_link
bz_status_NEW "
title="NEW - Floating point varargs are not handled correctly with -mno-implicit-float"
href="show_bug.cgi?id=36507">bug 36507</a> is fixed
(<a href="https://reviews.llvm.org/D62639">https://reviews.llvm.org/D62639</a>).
Previously, variadic functions compiled with -no-implicit-float could safely be
used even with the SSE unit disabled. If we fix 36507 without fixing the
present bug, such code will lead to a crash at runtime due to reading XMM
registers.
I understand that it is arguable whether or not that would be a bug. For
example AArch64 variadic functions always unconditionally access the vector
registers. But that is because the AArch64 ABI does not provide a way to avoid
this. Whereas the X86_64 ABI *does*.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>