<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </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 --- - Unnecessarily selects memory operand and misaligns stack"
   href="https://llvm.org/bugs/show_bug.cgi?id=31525">31525</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Unnecessarily selects memory operand and misaligns stack
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>3.8
          </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>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>doug16k@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>I am writing code that will run in kernel mode on x86-64. I have a function
which uses inline assembly to load the task register. This is my function:

typedef unsigned short uint16_t;
void cpu_set_tr(uint16_t tr)
{
    __asm__ __volatile__ (
        "ltr %w0\n\t"
        :
        : "rm" (tr)
        : "memory"
    );
}

Here's a link to godbolt for your convenience: <a href="https://godbolt.org/g/ijwQ7K">https://godbolt.org/g/ijwQ7K</a>

This is the generated code:

cpu_set_tr(unsigned short):                        # @cpu_set_tr(unsigned
short)
        subq    $2, %rsp
        movw    %di, (%rsp)
        ltrw    (%rsp)

        addq    $2, %rsp
        retq

Note that I am using -mno-red-zone because in kernel mode, it won't switch to
another stack when an interrupt or exception occurs.

Note that there are two problems with the code:

1) It misaligns the stack. It subtracts 2 from rsp. If an interrupt occurs
here, the CPU will do many (about 46, counting context save and restore)
misaligned accesses.

2) It unnecessarily selects the memory operand alternative.

There's no reason for it to select a memory operand for this code. I expected
this:

        ltr %di
        retq

If I remove the "m" constraint, it does just that. This seems like a really
trivial case for it to be misaligning the stack to store a value to memory
unnecessarily, followed by reloading the stored value, due to a poorly selected
memory operand alternative.

I suspect that this bug has went unnoticed because it usually doesn't need to
adjust the stack pointer when the red zone is enabled. I have no hypothesis for
its selection of the memory operand. clang usually generates better code than
this.</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>