[llvm-bugs] [Bug 31525] New: Unnecessarily selects memory operand and misaligns stack

via llvm-bugs llvm-bugs at lists.llvm.org
Wed Jan 4 00:15:42 PST 2017


https://llvm.org/bugs/show_bug.cgi?id=31525

            Bug ID: 31525
           Summary: Unnecessarily selects memory operand and misaligns
                    stack
           Product: clang
           Version: 3.8
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: -New Bugs
          Assignee: unassignedclangbugs at nondot.org
          Reporter: doug16k at gmail.com
                CC: llvm-bugs at lists.llvm.org
    Classification: Unclassified

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: https://godbolt.org/g/ijwQ7K

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.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20170104/c6ac9231/attachment-0001.html>


More information about the llvm-bugs mailing list