diff options
| -rw-r--r-- | clang/include/clang/AST/Builtins.def | 3 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGBuiltin.cpp | 41 | ||||
| -rw-r--r-- | clang/test/CodeGen/builtin-memfns.c | 11 |
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; +} |

