From 7672d04f770c88b7b9152327a85936c01bab8035 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Sat, 23 Jan 2010 05:29:06 +0000 Subject: Reapply 94059 while fixing the calling convention setup for strcpy. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@94287 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/SimplifyLibCalls.cpp | 47 ++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp index 9183f3aac1..a49da9ce9e 100644 --- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp +++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp @@ -81,6 +81,10 @@ public: /// and the return value has 'i8*' type. Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B); + /// EmitStrCpy - Emit a call to the strcpy function to the builder, for the + /// specified pointer arguments. + Value *EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B); + /// EmitMemCpy - Emit a call to the memcpy function to the builder. This /// always expects that the size has type 'intptr_t' and Dst/Src are pointers. Value *EmitMemCpy(Value *Dst, Value *Src, Value *Len, @@ -176,6 +180,22 @@ Value *LibCallOptimization::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B) { return CI; } +/// EmitStrCpy - Emit a call to the strcpy function to the builder, for the +/// specified pointer arguments. +Value *LibCallOptimization::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B) { + Module *M = Caller->getParent(); + AttributeWithIndex AWI[2]; + AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture); + AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind); + const Type *I8Ptr = Type::getInt8PtrTy(*Context); + Value *StrCpy = M->getOrInsertFunction("strcpy", AttrListPtr::get(AWI, 2), + I8Ptr, I8Ptr, I8Ptr, NULL); + CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B), + "strcpy"); + if (const Function *F = dyn_cast(StrCpy->stripPointerCasts())) + CI->setCallingConv(F->getCallingConv()); + return CI; +} /// EmitMemCpy - Emit a call to the memcpy function to the builder. This always /// expects that the size has type 'intptr_t' and Dst/Src are pointers. @@ -1181,6 +1201,31 @@ struct MemMoveChkOpt : public LibCallOptimization { } }; +struct StrCpyChkOpt : public LibCallOptimization { + virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { + // These optimizations require TargetData. + if (!TD) return 0; + + const FunctionType *FT = Callee->getFunctionType(); + if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || + !isa(FT->getParamType(0)) || + !isa(FT->getParamType(1)) || + !isa(FT->getParamType(2))) + return 0; + + ConstantInt *SizeCI = dyn_cast(CI->getOperand(3)); + if (!SizeCI) + return 0; + + // We don't have any length information, just lower to a plain strcpy. + if (SizeCI->isAllOnesValue()) + return EmitStrCpy(CI->getOperand(1), CI->getOperand(2), B); + + return 0; + } +}; + + //===----------------------------------------------------------------------===// // Math Library Optimizations //===----------------------------------------------------------------------===// @@ -1725,6 +1770,7 @@ namespace { // Object Size Checking MemCpyChkOpt MemCpyChk; MemSetChkOpt MemSetChk; MemMoveChkOpt MemMoveChk; + StrCpyChkOpt StrCpyChk; bool Modified; // This is only used by doInitialization. public: @@ -1836,6 +1882,7 @@ void SimplifyLibCalls::InitOptimizations() { Optimizations["__memcpy_chk"] = &MemCpyChk; Optimizations["__memset_chk"] = &MemSetChk; Optimizations["__memmove_chk"] = &MemMoveChk; + Optimizations["__strcpy_chk"] = &StrCpyChk; } -- cgit v1.2.3