-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Emit a warning if inline assembly with a clobber list is used inside a naked function. #29015
Comments
Alternatively we could avoid generating code around inline asm if it appears in a naked function. |
Yes, I think it depends whether clobbered list are meant to be supported inside naked functions, or are their behaviour undefined? This gcc documentation https://gcc.gnu.org/onlinedocs/gcc/ARM-Function-Attributes.html#ARM-Function-Attributes seems to suggest that only "basic asm" is allowed in a naked function, clobbered list are considered "extended asm" I think. Does it mean we could emit an undefined behaviour warning whenever a non "basic asm" statement is found in a naked function? |
FTR, we've got a use for simple input arguments in inline asm in naked functions, like this: define void @f() #0 { attributes #0 = { naked } We use this to emit CFI jumptables, see https://reviews.llvm.org/D28012 for more context. Without the input argument, we'd have to do asm name mangling in IR transform pass, which is ugly and wrong. Btw, win32 backend is not happy about any assembly in a naked function right now. target triple = "x86_64-pc-windows-msvc" define void @f() #0 { attributes #0 = { naked } include/llvm/CodeGen/MachineFunction.h:452: bool llvm::MachineFunction::hasWinCFI() const: Assertion `HasWinCFI.hasValue() && "HasWinCFI not set yet!"' failed. |
It looks like the register spill instruction is nothing to do with the inline assembler statement register clobber list. The extra instruction is a spill of a function input argument: Consider the source: It produces the following assembler: %bb.0: # %entry
As can be seen the spilled registers are the function input arguments. It happens only if the clang uses Fast registry allocator, which produces spill to the stack frame instruction for every function input argument. Other registry allocators in similar situation, mark those registers as "dead", replace them with "KILL %%reg" instructions and no machine instructions will be produced for them during the instruction selection phase. |
potential fix on Phabricator: |
Extended Description
Having inline assembly with a clobber list in a function marked naked seems dangerous as this will alter the stack but only at -O0 in the case below, higher optimisations level are fine.
eg:
$ clang --version
clang version 3.9.0 @r276109
Target: x86_64-unknown-linux-gnu
#include <stdlib.h>
attribute((naked, noinline)) int foo(size_t)
{
asm volatile (
"ret" : : : "rdi"
);
}
$ clang -O0 -S test.cpp
BB#0: # %entry
The text was updated successfully, but these errors were encountered: