summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2008-07-22 00:26:45 +0000
committerDaniel Dunbar <daniel@zuster.org>2008-07-22 00:26:45 +0000
commit327acd7a6cff9c949b9744179f35e2f15760165d (patch)
tree36b0bddd599b1f7123ed20b4fd370b62604556da
parentd5d24f63fd2096a14aa4aedeaa49d370030a5375 (diff)
downloadbcm5719-llvm-327acd7a6cff9c949b9744179f35e2f15760165d.tar.gz
bcm5719-llvm-327acd7a6cff9c949b9744179f35e2f15760165d.zip
Implement bzero, memset, memmove builtins.
This subsumes Nico Weber's patch and implements bzero in terms of llvm.memset to match llvm-gcc. llvm-svn: 53888
-rw-r--r--clang/include/clang/AST/Builtins.def3
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp41
-rw-r--r--clang/test/CodeGen/builtin-memfns.c11
3 files changed, 45 insertions, 10 deletions
diff --git a/clang/include/clang/AST/Builtins.def b/clang/include/clang/AST/Builtins.def
index f38f431d3d2..126609b04dc 100644
--- a/clang/include/clang/AST/Builtins.def
+++ b/clang/include/clang/AST/Builtins.def
@@ -117,7 +117,10 @@ BUILTIN(__builtin_va_start, "va&.", "n")
BUILTIN(__builtin_va_end, "va&", "n")
BUILTIN(__builtin_va_copy, "va&a", "n")
BUILTIN(__builtin_stdarg_start, "va&a", "n")
+BUILTIN(__builtin_bzero, "vv*z", "n")
BUILTIN(__builtin_memcpy, "v*v*vC*z", "n")
+BUILTIN(__builtin_memmove, "v*v*vC*z", "n")
+BUILTIN(__builtin_memset, "v*v*cz", "n")
BUILTIN(__builtin_return_address, "v*Ui", "n")
BUILTIN(__builtin_frame_address, "v*Ui", "n")
// GCC Object size checking builtins
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 87d09a981d2..9de5a5acd4b 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -291,18 +291,39 @@ RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) {
// FIXME: LLVM IR Should allow alloca with an i64 size!
Value *Size = EmitScalarExpr(E->getArg(0));
Size = Builder.CreateIntCast(Size, llvm::Type::Int32Ty, false, "tmp");
- return RValue::get(Builder.CreateAlloca(llvm::Type::Int8Ty, Size,
- "tmp"));
+ return RValue::get(Builder.CreateAlloca(llvm::Type::Int8Ty, Size, "tmp"));
+ }
+ case Builtin::BI__builtin_bzero: {
+ Value *Address = EmitScalarExpr(E->getArg(0));
+ Builder.CreateCall4(CGM.getMemSetFn(), Address,
+ llvm::ConstantInt::get(llvm::Type::Int8Ty, 0),
+ EmitScalarExpr(E->getArg(1)),
+ llvm::ConstantInt::get(llvm::Type::Int32Ty, 1));
+ return RValue::get(Address);
}
case Builtin::BI__builtin_memcpy: {
- Value* MemCpyOps[4] = {
- EmitScalarExpr(E->getArg(0)),
- EmitScalarExpr(E->getArg(1)),
- EmitScalarExpr(E->getArg(2)),
- llvm::ConstantInt::get(llvm::Type::Int32Ty, 0)
- };
- Builder.CreateCall(CGM.getMemCpyFn(), MemCpyOps, MemCpyOps+4);
- return RValue::get(MemCpyOps[0]);
+ Value *Address = EmitScalarExpr(E->getArg(0));
+ Builder.CreateCall4(CGM.getMemCpyFn(), Address,
+ EmitScalarExpr(E->getArg(1)),
+ EmitScalarExpr(E->getArg(2)),
+ llvm::ConstantInt::get(llvm::Type::Int32Ty, 1));
+ return RValue::get(Address);
+ }
+ case Builtin::BI__builtin_memmove: {
+ Value *Address = EmitScalarExpr(E->getArg(0));
+ Builder.CreateCall4(CGM.getMemMoveFn(), Address,
+ EmitScalarExpr(E->getArg(1)),
+ EmitScalarExpr(E->getArg(2)),
+ llvm::ConstantInt::get(llvm::Type::Int32Ty, 1));
+ return RValue::get(Address);
+ }
+ case Builtin::BI__builtin_memset: {
+ Value *Address = EmitScalarExpr(E->getArg(0));
+ Builder.CreateCall4(CGM.getMemSetFn(), Address,
+ EmitScalarExpr(E->getArg(1)),
+ EmitScalarExpr(E->getArg(2)),
+ llvm::ConstantInt::get(llvm::Type::Int32Ty, 1));
+ return RValue::get(Address);
}
case Builtin::BI__builtin_return_address: {
Value *F = CGM.getIntrinsic(Intrinsic::returnaddress, 0, 0);
diff --git a/clang/test/CodeGen/builtin-memfns.c b/clang/test/CodeGen/builtin-memfns.c
new file mode 100644
index 00000000000..d28a48c5374
--- /dev/null
+++ b/clang/test/CodeGen/builtin-memfns.c
@@ -0,0 +1,11 @@
+// RUN: clang -emit-llvm -o - %s | not grep __builtin
+
+int main(int argc, char **argv) {
+ unsigned char a = 0x11223344;
+ unsigned char b = 0x11223344;
+ __builtin_bzero(&a, sizeof(a));
+ __builtin_memset(&a, 0, sizeof(a));
+ __builtin_memcpy(&a, &b, sizeof(a));
+ __builtin_memmove(&a, &b, sizeof(a));
+ return 0;
+}
OpenPOWER on IntegriCloud