aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-09-14 04:33:21 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-09-14 04:33:21 +0000
commit34771b594ca8cdf8cd2e40b27170efa4ed2833c5 (patch)
tree59529dd83c3bbeffdf83247e1579f581157202dc
parentb0d58196808aba4b3d1a7488bd5566f3c0a83e89 (diff)
Fix subtle bug in generating LLVM function declarations for builtin functions.
The decl wasn't being passed down, which meant that function attributes were not being set correctly. This is particularly important for ARM, since it wants to override the calling convention. Instead we would emit the builtin with the wrong calling convention, and instcombine would come along and merrily shred all the calls to it. :) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81756 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGBuiltin.cpp2
-rw-r--r--lib/CodeGen/CodeGenModule.cpp6
-rw-r--r--lib/CodeGen/CodeGenModule.h3
-rw-r--r--test/CodeGen/builtin-attributes.c12
4 files changed, 18 insertions, 5 deletions
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 77c408a963..e049cc890d 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -556,7 +556,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
// that function.
if (getContext().BuiltinInfo.isLibFunction(BuiltinID) ||
getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID))
- return EmitCall(CGM.getBuiltinLibFunction(BuiltinID),
+ return EmitCall(CGM.getBuiltinLibFunction(FD, BuiltinID),
E->getCallee()->getType(), E->arg_begin(),
E->arg_end());
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 05f14682d7..fca6ebefda 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -1256,7 +1256,8 @@ void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) {
/// getBuiltinLibFunction - Given a builtin id for a function like
/// "__builtin_fabsf", return a Function* for "fabsf".
-llvm::Value *CodeGenModule::getBuiltinLibFunction(unsigned BuiltinID) {
+llvm::Value *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD,
+ unsigned BuiltinID) {
assert((Context.BuiltinInfo.isLibFunction(BuiltinID) ||
Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) &&
"isn't a lib fn");
@@ -1276,8 +1277,7 @@ llvm::Value *CodeGenModule::getBuiltinLibFunction(unsigned BuiltinID) {
// Unique the name through the identifier table.
Name = getContext().Idents.get(Name).getName();
- // FIXME: param attributes for sext/zext etc.
- return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl());
+ return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl(FD));
}
llvm::Function *CodeGenModule::getIntrinsic(unsigned IID,const llvm::Type **Tys,
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index f115feba4f..ff8ffb305d 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -303,7 +303,8 @@ public:
/// getBuiltinLibFunction - Given a builtin id for a function like
/// "__builtin_fabsf", return a Function* for "fabsf".
- llvm::Value *getBuiltinLibFunction(unsigned BuiltinID);
+ llvm::Value *getBuiltinLibFunction(const FunctionDecl *FD,
+ unsigned BuiltinID);
llvm::Function *getMemCpyFn();
llvm::Function *getMemMoveFn();
diff --git a/test/CodeGen/builtin-attributes.c b/test/CodeGen/builtin-attributes.c
new file mode 100644
index 0000000000..184e9676ed
--- /dev/null
+++ b/test/CodeGen/builtin-attributes.c
@@ -0,0 +1,12 @@
+// RUN: clang-cc -triple arm-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: declare arm_aapcscc i32 @printf(i8*, ...)
+void f0() {
+ printf("a\n");
+}
+
+// CHECK: call arm_aapcscc void @exit
+// CHECK: unreachable
+void f1() {
+ exit(1);
+}