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