Index: include/llvm/Target/TargetLibraryInfo.h =================================================================== --- include/llvm/Target/TargetLibraryInfo.h +++ include/llvm/Target/TargetLibraryInfo.h @@ -73,6 +73,11 @@ dunder_isoc99_sscanf, /// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size); memcpy_chk, + /// void *__memmove_chk(void *s1, const void *s2, size_t n, + /// size_t s1size); + memmove_chk, + /// void *__memset_chk(void *s, char v, size_t n, size_t s1size); + memset_chk, /// double __sincospi_stret(double x); sincospi_stret, /// float __sincospif_stret(float x); @@ -87,8 +92,18 @@ sqrtf_finite, /// long double __sqrt_finite(long double x); sqrtl_finite, + /// char *__stpcpy_chk(char *s1, const char *s2, size_t s1size); + stpcpy_chk, + /// char *__stpncpy_chk(char *s1, const char *s2, size_t n, + /// size_t s1size); + stpncpy_chk, + /// char *__strcpy_chk(char *s1, const char *s2, size_t s1size); + strcpy_chk, /// char * __strdup(const char *s); dunder_strdup, + /// char *__strncpy_chk(char *s1, const char *s2, size_t n, + /// size_t s1size); + strncpy_chk, /// char *__strndup(const char *s, size_t n); dunder_strndup, /// char * __strtok_r(char *s, const char *delim, char **save_ptr); Index: include/llvm/Transforms/Utils/SimplifyLibCalls.h =================================================================== --- include/llvm/Transforms/Utils/SimplifyLibCalls.h +++ include/llvm/Transforms/Utils/SimplifyLibCalls.h @@ -35,12 +35,14 @@ const DataLayout *DL; const TargetLibraryInfo *TLI; bool UnsafeFPShrink; + bool OnlyLowerFortified; protected: ~LibCallSimplifier() {} public: - LibCallSimplifier(const DataLayout *TD, const TargetLibraryInfo *TLI); + LibCallSimplifier(const DataLayout *TD, const TargetLibraryInfo *TLI, + bool OnlyLowerFortified = false); /// optimizeCall - Take the given call instruction and return a more /// optimal value to replace the instruction with or 0 if a more Index: lib/Target/TargetLibraryInfo.cpp =================================================================== --- lib/Target/TargetLibraryInfo.cpp +++ lib/Target/TargetLibraryInfo.cpp @@ -51,6 +51,8 @@ "__isoc99_scanf", "__isoc99_sscanf", "__memcpy_chk", + "__memmove_chk", + "__memset_chk", "__sincospi_stret", "__sincospif_stret", "__sinpi", @@ -58,7 +60,11 @@ "__sqrt_finite", "__sqrtf_finite", "__sqrtl_finite", + "__stpcpy_chk", + "__stpncpy_chk", + "__strcpy_chk", "__strdup", + "__strncpy_chk", "__strndup", "__strtok_r", "abs", Index: lib/Transforms/Utils/SimplifyLibCalls.cpp =================================================================== --- lib/Transforms/Utils/SimplifyLibCalls.cpp +++ lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -219,7 +219,7 @@ return nullptr; Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1); - if (Dst == Src) // __strcpy_chk(x,x) -> x + if (!OnlyLowerFortified && Dst == Src) // __strcpy_chk(x,x) -> x return Src; // If a) we don't have any length information, or b) we know this will @@ -230,7 +230,7 @@ if (isFortifiedCallFoldable(CI, 2, 1, true)) { Value *Ret = EmitStrCpy(Dst, Src, B, DL, TLI, Name.substr(2, 6)); return Ret; - } else { + } else if (!OnlyLowerFortified) { // Maybe we can stil fold __strcpy_chk to __memcpy_chk. uint64_t Len = GetStringLength(Src); if (Len == 0) @@ -262,7 +262,7 @@ return nullptr; Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1); - if (Dst == Src) { // stpcpy(x,x) -> x+strlen(x) + if (!OnlyLowerFortified && Dst == Src) { // stpcpy(x,x) -> x+strlen(x) Value *StrLen = EmitStrLen(Src, B, DL, TLI); return StrLen ? B.CreateInBoundsGEP(Dst, StrLen) : nullptr; } @@ -275,7 +275,7 @@ if (isFortifiedCallFoldable(CI, 2, 1, true)) { Value *Ret = EmitStrCpy(Dst, Src, B, DL, TLI, Name.substr(2, 6)); return Ret; - } else { + } else if (!OnlyLowerFortified) { // Maybe we can stil fold __stpcpy_chk to __memcpy_chk. uint64_t Len = GetStringLength(Src); if (Len == 0) @@ -2019,29 +2019,33 @@ UnsafeFPShrink = true; } - // First, check for intrinsics. - if (IntrinsicInst *II = dyn_cast(CI)) { - if (!isCallingConvC) - return nullptr; - switch (II->getIntrinsicID()) { - case Intrinsic::pow: - return optimizePow(CI, Builder); - case Intrinsic::exp2: - return optimizeExp2(CI, Builder); - case Intrinsic::fabs: - return optimizeFabs(CI, Builder); - case Intrinsic::sqrt: - return optimizeSqrt(CI, Builder); - default: - return nullptr; - } - } - - // Then check for known library functions. + // First, check for known library functions. if (TLI->getLibFunc(FuncName, Func) && TLI->has(Func)) { // We never change the calling convention. if (!ignoreCallingConv(Func) && !isCallingConvC) return nullptr; + + switch (Func) { + case LibFunc::memcpy_chk: + return optimizeMemCpyChk(CI, Builder); + case LibFunc::memmove_chk: + return optimizeMemMoveChk(CI, Builder); + case LibFunc::memset_chk: + return optimizeMemSetChk(CI, Builder); + case LibFunc::strcpy_chk: + return optimizeStrCpyChk(CI, Builder); + case LibFunc::stpcpy_chk: + return optimizeStpCpyChk(CI, Builder); + case LibFunc::stpncpy_chk: + case LibFunc::strncpy_chk: + return optimizeStrNCpyChk(CI, Builder); + default: + break; + } + + if (OnlyLowerFortified) + return nullptr; + switch (Func) { case LibFunc::strcat: return optimizeStrCat(CI, Builder); @@ -2182,40 +2186,41 @@ if (hasFloatVersion(FuncName)) return optimizeBinaryDoubleFP(CI, Builder); return nullptr; - case LibFunc::memcpy_chk: - return optimizeMemCpyChk(CI, Builder); default: return nullptr; } } - if (!isCallingConvC) + if (OnlyLowerFortified) return nullptr; - // Finally check for fortified library calls. - if (FuncName.endswith("_chk")) { - if (FuncName == "__memmove_chk") - return optimizeMemMoveChk(CI, Builder); - else if (FuncName == "__memset_chk") - return optimizeMemSetChk(CI, Builder); - else if (FuncName == "__strcpy_chk") - return optimizeStrCpyChk(CI, Builder); - else if (FuncName == "__stpcpy_chk") - return optimizeStpCpyChk(CI, Builder); - else if (FuncName == "__strncpy_chk") - return optimizeStrNCpyChk(CI, Builder); - else if (FuncName == "__stpncpy_chk") - return optimizeStrNCpyChk(CI, Builder); + // Then check for intrinsics. + if (IntrinsicInst *II = dyn_cast(CI)) { + if (!isCallingConvC) + return nullptr; + switch (II->getIntrinsicID()) { + case Intrinsic::pow: + return optimizePow(CI, Builder); + case Intrinsic::exp2: + return optimizeExp2(CI, Builder); + case Intrinsic::fabs: + return optimizeFabs(CI, Builder); + case Intrinsic::sqrt: + return optimizeSqrt(CI, Builder); + default: + return nullptr; + } } - return nullptr; } LibCallSimplifier::LibCallSimplifier(const DataLayout *DL, - const TargetLibraryInfo *TLI) : + const TargetLibraryInfo *TLI, + bool OnlyLowerFortified) : DL(DL), TLI(TLI), - UnsafeFPShrink(false) { + UnsafeFPShrink(false), + OnlyLowerFortified(OnlyLowerFortified) { } void LibCallSimplifier::replaceAllUsesWith(Instruction *I, Value *With) const {