summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGBuiltin.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2011-04-17 00:40:24 +0000
committerChris Lattner <sabre@nondot.org>2011-04-17 00:40:24 +0000
commit30107ed600da4cd3a5bbb5d70cd6e97b618fff38 (patch)
treea72a8fd2b52eea827543e569054af05728bd2f1c /clang/lib/CodeGen/CGBuiltin.cpp
parent55b0acd624a3c26b2e2510934997cd98ddbd126f (diff)
downloadbcm5719-llvm-30107ed600da4cd3a5bbb5d70cd6e97b618fff38.tar.gz
bcm5719-llvm-30107ed600da4cd3a5bbb5d70cd6e97b618fff38.zip
fold memcpy/set/move_chk to llvm.memcpy/set/move when the sizes
are trivial. This exposes opportunities earlier, and allows fastisel to do good things with these at -O0. This addresses rdar://9289468 - clang doesn't fold memset_chk at -O0 llvm-svn: 129651
Diffstat (limited to 'clang/lib/CodeGen/CGBuiltin.cpp')
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp51
1 files changed, 50 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 97b93d50300..51d9eebaba1 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -543,6 +543,22 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
return RValue::get(Address);
}
+ case Builtin::BI__builtin___memcpy_chk: {
+ // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memset iff cst1<=cst2.
+ if (!E->getArg(2)->isEvaluatable(CGM.getContext()) ||
+ !E->getArg(3)->isEvaluatable(CGM.getContext()))
+ break;
+ llvm::APSInt Size = E->getArg(2)->EvaluateAsInt(CGM.getContext());
+ llvm::APSInt DstSize = E->getArg(3)->EvaluateAsInt(CGM.getContext());
+ if (Size.ugt(DstSize))
+ break;
+ Value *Dest = EmitScalarExpr(E->getArg(0));
+ Value *Src = EmitScalarExpr(E->getArg(1));
+ Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
+ Builder.CreateMemCpy(Dest, Src, SizeVal, 1, false);
+ return RValue::get(0);
+ }
+
case Builtin::BI__builtin_objc_memmove_collectable: {
Value *Address = EmitScalarExpr(E->getArg(0));
Value *SrcAddr = EmitScalarExpr(E->getArg(1));
@@ -551,7 +567,23 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Address, SrcAddr, SizeVal);
return RValue::get(Address);
}
-
+
+ case Builtin::BI__builtin___memmove_chk: {
+ // fold __builtin_memmove_chk(x, y, cst1, cst2) to memset iff cst1<=cst2.
+ if (!E->getArg(2)->isEvaluatable(CGM.getContext()) ||
+ !E->getArg(3)->isEvaluatable(CGM.getContext()))
+ break;
+ llvm::APSInt Size = E->getArg(2)->EvaluateAsInt(CGM.getContext());
+ llvm::APSInt DstSize = E->getArg(3)->EvaluateAsInt(CGM.getContext());
+ if (Size.ugt(DstSize))
+ break;
+ Value *Dest = EmitScalarExpr(E->getArg(0));
+ Value *Src = EmitScalarExpr(E->getArg(1));
+ Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
+ Builder.CreateMemMove(Dest, Src, SizeVal, 1, false);
+ return RValue::get(0);
+ }
+
case Builtin::BImemmove:
case Builtin::BI__builtin_memmove: {
Value *Address = EmitScalarExpr(E->getArg(0));
@@ -569,6 +601,23 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Builder.CreateMemSet(Address, ByteVal, SizeVal, 1, false);
return RValue::get(Address);
}
+ case Builtin::BI__builtin___memset_chk: {
+ // fold __builtin_memset_chk(x, y, cst1, cst2) to memset iff cst1<=cst2.
+ if (!E->getArg(2)->isEvaluatable(CGM.getContext()) ||
+ !E->getArg(3)->isEvaluatable(CGM.getContext()))
+ break;
+ llvm::APSInt Size = E->getArg(2)->EvaluateAsInt(CGM.getContext());
+ llvm::APSInt DstSize = E->getArg(3)->EvaluateAsInt(CGM.getContext());
+ if (Size.ugt(DstSize))
+ break;
+ Value *Address = EmitScalarExpr(E->getArg(0));
+ Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
+ Builder.getInt8Ty());
+ Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
+ Builder.CreateMemSet(Address, ByteVal, SizeVal, 1, false);
+
+ return RValue::get(0);
+ }
case Builtin::BI__builtin_dwarf_cfa: {
// The offset in bytes from the first argument to the CFA.
//
OpenPOWER on IntegriCloud