From: Daniel Dunbar Date: Tue, 22 Jul 2008 00:26:45 +0000 (+0000) Subject: Implement bzero, memset, memmove builtins. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1caae959017b355e9bb61250d5a0d04edbf468b0;p=clang Implement bzero, memset, memmove builtins. This subsumes Nico Weber's patch and implements bzero in terms of llvm.memset to match llvm-gcc. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53888 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Builtins.def b/include/clang/AST/Builtins.def index f38f431d3d..126609b04d 100644 --- a/include/clang/AST/Builtins.def +++ b/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/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 87d09a981d..9de5a5acd4 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/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/test/CodeGen/builtin-memfns.c b/test/CodeGen/builtin-memfns.c new file mode 100644 index 0000000000..d28a48c537 --- /dev/null +++ b/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; +}