<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>