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: unassignedclangb...@nondot.org
          Reporter: doug...@gmail.com
                CC: llvm-bugs@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.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to