[PATCH] D111009: Update inline builtin handling to honor gnu inline attribute
Nick Desaulniers via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Sun Oct 3 11:54:29 PDT 2021
nickdesaulniers added a comment.
hmm...this seems to cause a bunch of ICEs building the kernel:
Global is external, but doesn't have external or weak linkage!
i64 (i8*)* @strlen
fatal error: error in backend: Broken module found, compilation aborted!
Global is external, but doesn't have external or weak linkage!
i8* (i8*, i8*, i64)* @strncpy
Global is external, but doesn't have external or weak linkage!
i8* (i8*, i8*)* @strcpy
Global is external, but doesn't have external or weak linkage!
i64 (i8*)* @strlen
Global is external, but doesn't have external or weak linkage!
i64 (i8*, i8*, i64)* @strlcpy
Global is external, but doesn't have external or weak linkage!
i8* (i8*, i32, i64)* @memchr
================
Comment at: clang/lib/CodeGen/CGExpr.cpp:4895
+
+ // Replaceable builtin provide their own implementation of a builtin. If we
+ // are in an inline builtin implementation, avoid trivial infinite
----------------
s/Replaceable builtin/Replaceable builtins/
================
Comment at: clang/lib/CodeGen/CGExpr.cpp:4898
// recursion.
+ StringRef FDInlineName = (FD->getName() + ".inline").str();
if (!FD->isInlineBuiltinDeclaration() ||
----------------
When building this patch (with Clang, via cmake vars `-DCMAKE_C_COMPILER=` and `-DCMAKE_CXX_COMPILER=`), I observe the following warning:
```
[99/110] Building CXX object tools/clang/lib/CodeGen/CMakeFiles/obj.clangCodeGen.dir/CGExpr.cpp.o
/android0/llvm-project/clang/lib/CodeGen/CGExpr.cpp:4898:30: warning: object backing the pointer will be destroyed at the end of the full-expression [-Wdangling-gsl]
StringRef FDInlineName = (FD->getName() + ".inline").str();
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
This leads to crashes when using the resulting image built with assertions enabled.
```
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index afed918c5c7f..cb6469d58b4c 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -4895,9 +4895,9 @@ static CGCallee EmitDirectCallee(CodeGenFunction &CGF, GlobalDecl GD) {
// Replaceable builtin provide their own implementation of a builtin. If we
// are in an inline builtin implementation, avoid trivial infinite
// recursion.
- StringRef FDInlineName = (FD->getName() + ".inline").str();
+ Twine FDInlineName = FD->getName() + ".inline";
if (!FD->isInlineBuiltinDeclaration() ||
- CGF.CurFn->getName() == FDInlineName) {
+ CGF.CurFn->getName() == FDInlineName.str()) {
return CGCallee::forBuiltin(builtinID, FD);
}
// When directing calling an inline builtin, call it through it's mangled
@@ -4906,7 +4906,7 @@ static CGCallee EmitDirectCallee(CodeGenFunction &CGF, GlobalDecl GD) {
llvm::Constant *CalleePtr = EmitFunctionDeclPointer(CGF.CGM, GD);
llvm::Function *Fn = llvm::cast<llvm::Function>(CalleePtr);
llvm::Module &M = CGF.CGM.getModule();
- llvm::Function *Clone = M.getFunction(FDInlineName);
+ llvm::Function *Clone = M.getFunction(FDInlineName.str());
if (!Clone) {
Clone = llvm::Function::Create(Fn->getFunctionType(), Fn->getLinkage(),
Fn->getAddressSpace(),
```
================
Comment at: clang/lib/CodeGen/CGExpr.cpp:4901
+ CGF.CurFn->getName() == FDInlineName) {
return CGCallee::forBuiltin(builtinID, FD);
+ }
----------------
I think if you flip the order of the branches by inverting the logic in the conditional, then you could avoid needing braces for the single statement branch. ie.
```
if (FD->isInlineBuiltinDeclaration() && CGF.CurFn->getName() != FDInlineName) {
llvm::Constant *CalleePtr = EmitFunctionDeclPointer(CGF.CGM, GD);
...
} else
return CGCallee::forBuiltin(builtinID, FD);
```
================
Comment at: clang/lib/CodeGen/CGExpr.cpp:4908
+ llvm::Function *Fn = llvm::cast<llvm::Function>(CalleePtr);
+ llvm::Module &M = CGF.CGM.getModule();
+ llvm::Function *Clone = M.getFunction(FDInlineName);
----------------
If you have a handle to a `Function`, you can get a pointer to it's module via `Function::getParent()`.
================
Comment at: clang/lib/CodeGen/CGExpr.cpp:4913
+ Fn->getAddressSpace(),
+ FD->getName() + ".inline", &M);
+ Clone->addFnAttr(llvm::Attribute::AlwaysInline);
----------------
Can we reuse `FDInlineName` here for the 4th param?
================
Comment at: clang/lib/CodeGen/CodeGenFunction.cpp:1302
+ if (FD->isInlineBuiltinDeclaration() && Fn) {
+ llvm::Module &M = CGM.getModule();
+ llvm::Function *Clone = M.getFunction((Fn->getName() + ".inline").str());
----------------
could use `Fn->getParent()` here, too.
================
Comment at: clang/lib/CodeGen/CodeGenFunction.cpp:1307
+ Fn->getAddressSpace(),
+ (Fn->getName() + ".inline").str(), &M);
+ Clone->addFnAttr(llvm::Attribute::AlwaysInline);
----------------
`Fn->getName() + ".inline"` appears twice. Want to save it in a local variable then reuse it, similar to what you do above in clang/lib/CodeGen/CGExpr.cpp?
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D111009/new/
https://reviews.llvm.org/D111009
More information about the cfe-commits
mailing list