diff --git a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h index 4e7c97194cc59..6bcc9b69c4102 100644 --- a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h +++ b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h @@ -65,7 +65,7 @@ class FortifiedLibCallSimplifier { Value *optimizeMemPCpyChk(CallInst *CI, IRBuilderBase &B); Value *optimizeMemCCpyChk(CallInst *CI, IRBuilderBase &B); Value *optimizeSNPrintfChk(CallInst *CI, IRBuilderBase &B); - Value *optimizeSPrintfChk(CallInst *CI,IRBuilderBase &B); + Value *optimizeSPrintfChk(CallInst *CI, IRBuilderBase &B); Value *optimizeStrCatChk(CallInst *CI, IRBuilderBase &B); Value *optimizeStrLCat(CallInst *CI, IRBuilderBase &B); Value *optimizeStrNCatChk(CallInst *CI, IRBuilderBase &B); @@ -214,6 +214,9 @@ class LibCallSimplifier { Value *optimizeSymmetric(CallInst *CI, LibFunc Func, IRBuilderBase &B); Value *optimizeRemquo(CallInst *CI, IRBuilderBase &B); Value *optimizeFdim(CallInst *CI, IRBuilderBase &B); + + Value *foldLdexp(CallInst *CI, IRBuilderBase &B); + // Wrapper for all floating point library call optimizations Value *optimizeFloatingPointLibCall(CallInst *CI, LibFunc Func, IRBuilderBase &B); @@ -240,7 +243,7 @@ class LibCallSimplifier { Value *optimizePuts(CallInst *CI, IRBuilderBase &B); // Helper methods - Value* emitSnPrintfMemCpy(CallInst *CI, Value *StrArg, StringRef Str, + Value *emitSnPrintfMemCpy(CallInst *CI, Value *StrArg, StringRef Str, uint64_t N, IRBuilderBase &B); Value *emitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len, IRBuilderBase &B); @@ -264,6 +267,6 @@ class LibCallSimplifier { Value *optimizeStringLength(CallInst *CI, IRBuilderBase &B, unsigned CharSize, Value *Bound = nullptr); }; -} // End llvm namespace +} // namespace llvm #endif diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index 4a1565977b91c..549240a392368 100644 --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -110,8 +110,8 @@ static cl::opt AmbiguousNewHintValue( //===----------------------------------------------------------------------===// static bool ignoreCallingConv(LibFunc Func) { - return Func == LibFunc_abs || Func == LibFunc_labs || - Func == LibFunc_llabs || Func == LibFunc_strlen; + return Func == LibFunc_abs || Func == LibFunc_labs || Func == LibFunc_llabs || + Func == LibFunc_strlen; } /// Return true if it is only used in equality comparisons with With. @@ -133,9 +133,8 @@ static bool callHasFloatingPointArgument(const CallInst *CI) { } static bool callHasFP128Argument(const CallInst *CI) { - return any_of(CI->operands(), [](const Use &OI) { - return OI->getType()->isFP128Ty(); - }); + return any_of(CI->operands(), + [](const Use &OI) { return OI->getType()->isFP128Ty(); }); } // Convert the entire string Str representing an integer in Base, up to @@ -155,7 +154,7 @@ static Value *convertStrToInt(CallInst *CI, StringRef &Str, Value *EndPtr, // Current offset into the original string to reflect in EndPtr. size_t Offset = 0; // Strip leading whitespace. - for ( ; Offset != Str.size(); ++Offset) + for (; Offset != Str.size(); ++Offset) if (!isSpace((unsigned char)Str[Offset])) { Str = Str.substr(Offset); break; @@ -195,13 +194,11 @@ static Value *convertStrToInt(CallInst *CI, StringRef &Str, Value *EndPtr, Str = Str.drop_front(2); Offset += 2; Base = 16; - } - else if (Base == 0) + } else if (Base == 0) Base = 8; } else if (Base == 0) Base = 10; - } - else if (Base == 0) + } else if (Base == 0) Base = 10; // Convert the rest of the subject sequence, not including the sign, @@ -299,7 +296,7 @@ static void annotateDereferenceableBytes(CallInst *CI, } static void annotateNonNullNoUndefBasedOnAccess(CallInst *CI, - ArrayRef ArgNos) { + ArrayRef ArgNos) { Function *F = CI->getCaller(); if (!F) return; @@ -320,8 +317,10 @@ static void annotateNonNullNoUndefBasedOnAccess(CallInst *CI, } } -static void annotateNonNullAndDereferenceable(CallInst *CI, ArrayRef ArgNos, - Value *Size, const DataLayout &DL) { +static void annotateNonNullAndDereferenceable(CallInst *CI, + ArrayRef ArgNos, + Value *Size, + const DataLayout &DL) { if (ConstantInt *LenC = dyn_cast(Size)) { annotateNonNullNoUndefBasedOnAccess(CI, ArgNos); annotateDereferenceableBytes(CI, ArgNos, LenC->getZExtValue()); @@ -458,9 +457,8 @@ Value *LibCallSimplifier::optimizeStrNCat(CallInst *CI, IRBuilderBase &B) { // Helper to transform memchr(S, C, N) == S to N && *S == C and, when // NBytes is null, strchr(S, C) to *S == C. A precondition of the function // is that either S is dereferenceable or the value of N is nonzero. -static Value* memChrToCharCompare(CallInst *CI, Value *NBytes, - IRBuilderBase &B, const DataLayout &DL) -{ +static Value *memChrToCharCompare(CallInst *CI, Value *NBytes, IRBuilderBase &B, + const DataLayout &DL) { Value *Src = CI->getArgOperand(0); Value *CharVal = CI->getArgOperand(1); @@ -508,8 +506,7 @@ Value *LibCallSimplifier::optimizeStrChr(CallInst *CI, IRBuilderBase &B) { Type *SizeTTy = IntegerType::get(CI->getContext(), SizeTBits); return copyFlags(*CI, emitMemChr(SrcStr, CharVal, // include nul. - ConstantInt::get(SizeTTy, Len), B, - DL, TLI)); + ConstantInt::get(SizeTTy, Len), B, DL, TLI)); } if (CharC->isZero()) { @@ -561,7 +558,7 @@ Value *LibCallSimplifier::optimizeStrRChr(CallInst *CI, IRBuilderBase &B) { // Try to expand strrchr to the memrchr nonstandard extension if it's // available, or simply fail otherwise. - uint64_t NBytes = Str.size() + 1; // Include the terminating nul. + uint64_t NBytes = Str.size() + 1; // Include the terminating nul. Value *Size = ConstantInt::get(SizeTTy, NBytes); return copyFlags(*CI, emitMemRChr(SrcStr, CharVal, Size, B, DL, TLI)); } @@ -623,8 +620,8 @@ Value *LibCallSimplifier::optimizeStrCmp(CallInst *CI, IRBuilderBase &B) { // Optimize a memcmp or, when StrNCmp is true, strncmp call CI with constant // arrays LHS and RHS and nonconstant Size. static Value *optimizeMemCmpVarSize(CallInst *CI, Value *LHS, Value *RHS, - Value *Size, bool StrNCmp, - IRBuilderBase &B, const DataLayout &DL); + Value *Size, bool StrNCmp, IRBuilderBase &B, + const DataLayout &DL); Value *LibCallSimplifier::optimizeStrNCmp(CallInst *CI, IRBuilderBase &B) { Value *Str1P = CI->getArgOperand(0); @@ -889,9 +886,10 @@ Value *LibCallSimplifier::optimizeStringNCpy(CallInst *CI, bool RetEnd, if (SrcLen == 0) { // Transform st{p,r}ncpy(D, "", N) to memset(D, '\0', N) for any N. Align MemSetAlign = - CI->getAttributes().getParamAttrs(0).getAlignment().valueOrOne(); + CI->getAttributes().getParamAttrs(0).getAlignment().valueOrOne(); CallInst *NewCI = B.CreateMemSet(Dst, B.getInt8('\0'), Size, MemSetAlign); - AttrBuilder ArgAttrs(CI->getContext(), CI->getAttributes().getParamAttrs(0)); + AttrBuilder ArgAttrs(CI->getContext(), + CI->getAttributes().getParamAttrs(0)); NewCI->setAttributes(NewCI->getAttributes().addParamAttributes( CI->getContext(), 0, ArgAttrs)); copyFlags(*CI, NewCI); @@ -943,8 +941,7 @@ Value *LibCallSimplifier::optimizeStringLength(CallInst *CI, IRBuilderBase &B, // and likewise strnlen with constant N > 0: // strnlen(x, N) != 0 --> *x != 0 // strnlen(x, N) == 0 --> *x == 0 - return B.CreateZExt(B.CreateLoad(CharTy, Src, "char0"), - CI->getType()); + return B.CreateZExt(B.CreateLoad(CharTy, Src, "char0"), CI->getType()); } if (Bound) { @@ -1364,8 +1361,8 @@ Value *LibCallSimplifier::optimizeMemChr(CallInst *CI, IRBuilderBase &B) { Str = substr(Str, LenC->getZExtValue()); size_t Pos = Str.find_first_not_of(Str[0]); - if (Pos == StringRef::npos - || Str.find_first_not_of(Str[Pos], Pos) == StringRef::npos) { + if (Pos == StringRef::npos || + Str.find_first_not_of(Str[Pos], Pos) == StringRef::npos) { // If the source array consists of at most two consecutive sequences // of the same characters, then for any C and N (whether in bounds or // not), fold memchr(S, C, N) to @@ -1498,8 +1495,8 @@ Value *LibCallSimplifier::optimizeMemChr(CallInst *CI, IRBuilderBase &B) { // Optimize a memcmp or, when StrNCmp is true, strncmp call CI with constant // arrays LHS and RHS and nonconstant Size. static Value *optimizeMemCmpVarSize(CallInst *CI, Value *LHS, Value *RHS, - Value *Size, bool StrNCmp, - IRBuilderBase &B, const DataLayout &DL) { + Value *Size, bool StrNCmp, IRBuilderBase &B, + const DataLayout &DL) { if (LHS == RHS) // memcmp(s,s,x) -> 0 return Constant::getNullValue(CI->getType()); @@ -1515,7 +1512,7 @@ static Value *optimizeMemCmpVarSize(CallInst *CI, Value *LHS, Value *RHS, uint64_t Pos = 0; Value *Zero = ConstantInt::get(CI->getType(), 0); - for (uint64_t MinSize = std::min(LStr.size(), RStr.size()); ; ++Pos) { + for (uint64_t MinSize = std::min(LStr.size(), RStr.size());; ++Pos) { if (Pos == MinSize || (StrNCmp && (LStr[Pos] == '\0' && RStr[Pos] == '\0'))) { // One array is a leading part of the other of equal or greater @@ -1671,8 +1668,8 @@ Value *LibCallSimplifier::optimizeMemCCpy(CallInst *CI, IRBuilderBase &B) { return nullptr; } - Value *NewN = - ConstantInt::get(N->getType(), std::min(uint64_t(Pos + 1), N->getZExtValue())); + Value *NewN = ConstantInt::get( + N->getType(), std::min(uint64_t(Pos + 1), N->getZExtValue())); // memccpy -> llvm.memcpy copyFlags(*CI, B.CreateMemCpy(Dst, Align(1), Src, Align(1), NewN)); return Pos + 1 <= N->getZExtValue() @@ -1956,8 +1953,8 @@ static Value *valueHasFloatPrecision(Value *Val) { } /// Shrink double -> float functions. -static Value *optimizeDoubleFP(CallInst *CI, IRBuilderBase &B, - bool isBinary, const TargetLibraryInfo *TLI, +static Value *optimizeDoubleFP(CallInst *CI, IRBuilderBase &B, bool isBinary, + const TargetLibraryInfo *TLI, bool isPrecise = false) { Function *CalleeFn = CI->getCalledFunction(); if (!CI->getType()->isDoubleTy() || !CalleeFn) @@ -2007,9 +2004,9 @@ static Value *optimizeDoubleFP(CallInst *CI, IRBuilderBase &B, : B.CreateIntrinsic(IID, B.getFloatTy(), V[0]); } else { AttributeList CalleeAttrs = CalleeFn->getAttributes(); - R = isBinary ? emitBinaryFloatFnCall(V[0], V[1], TLI, CalleeName, B, - CalleeAttrs) - : emitUnaryFloatFnCall(V[0], TLI, CalleeName, B, CalleeAttrs); + R = isBinary + ? emitBinaryFloatFnCall(V[0], V[1], TLI, CalleeName, B, CalleeAttrs) + : emitUnaryFloatFnCall(V[0], TLI, CalleeName, B, CalleeAttrs); } return B.CreateFPExt(R, B.getDoubleTy()); } @@ -2464,6 +2461,24 @@ Value *LibCallSimplifier::optimizePow(CallInst *Pow, IRBuilderBase &B) { return nullptr; } +Value *LibCallSimplifier::foldLdexp(CallInst *CI, IRBuilderBase &B) { + + Type *RequiredType = CI->getType(); + if (!RequiredType->isFPOrFPVectorTy()) + return nullptr; + + Value *x = CI->getArgOperand(0); + Value *exp = CI->getArgOperand(1); + Module *M = CI->getModule(); + + Function *ldexpDecl = llvm::Intrinsic::getOrInsertDeclaration( + M, Intrinsic::ldexp, {RequiredType, exp->getType()}); + + CallInst *NewCall = B.CreateCall(ldexpDecl, {x, exp}, CI->getName()); + NewCall->setAttributes(CI->getAttributes()); + return copyFlags(*CI, NewCall); +} + Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilderBase &B) { Module *M = CI->getModule(); Function *Callee = CI->getCalledFunction(); @@ -2689,7 +2704,7 @@ Value *LibCallSimplifier::optimizeLog(CallInst *Log, IRBuilderBase &B) { // log(exp{,2,10}(y)) -> y*log({e,2,10}) // TODO: There is no exp10() intrinsic yet. if (ArgLb == ExpLb || ArgLb == Exp2Lb || ArgLb == Exp10Lb || - ArgID == Intrinsic::exp || ArgID == Intrinsic::exp2) { + ArgID == Intrinsic::exp || ArgID == Intrinsic::exp2) { Constant *Eul; if (ArgLb == ExpLb || ArgID == Intrinsic::exp) // FIXME: Add more precise value of e for long double. @@ -3045,7 +3060,8 @@ Value *LibCallSimplifier::optimizeSymmetric(CallInst *CI, LibFunc Func, } } -Value *LibCallSimplifier::optimizeSinCosPi(CallInst *CI, bool IsSin, IRBuilderBase &B) { +Value *LibCallSimplifier::optimizeSinCosPi(CallInst *CI, bool IsSin, + IRBuilderBase &B) { // Make sure the prototype is as expected, otherwise the rest of the // function is probably invalid and likely to abort. if (!isTrigLibCall(CI)) @@ -3107,8 +3123,7 @@ void LibCallSimplifier::classifyArgUse( Function *Callee = CI->getCalledFunction(); LibFunc Func; if (!Callee || !TLI->getLibFunc(*Callee, Func) || - !isLibFuncEmittable(M, TLI, Func) || - !isTrigLibCall(CI)) + !isLibFuncEmittable(M, TLI, Func) || !isTrigLibCall(CI)) return; if (IsFloat) { @@ -3429,8 +3444,8 @@ Value *LibCallSimplifier::optimizePrintF(CallInst *CI, IRBuilderBase &B) { return New; } - // printf(format, ...) -> __small_printf(format, ...) if no 128-bit floating point - // arguments. + // printf(format, ...) -> __small_printf(format, ...) if no 128-bit floating + // point arguments. if (isLibFuncEmittable(M, TLI, LibFunc_small_printf) && !callHasFP128Argument(CI)) { auto SmallPrintFFn = getOrInsertLibFunc(M, *TLI, LibFunc_small_printf, FT, @@ -3546,8 +3561,8 @@ Value *LibCallSimplifier::optimizeSPrintF(CallInst *CI, IRBuilderBase &B) { return New; } - // sprintf(str, format, ...) -> __small_sprintf(str, format, ...) if no 128-bit - // floating point arguments. + // sprintf(str, format, ...) -> __small_sprintf(str, format, ...) if no + // 128-bit floating point arguments. if (isLibFuncEmittable(M, TLI, LibFunc_small_sprintf) && !callHasFP128Argument(CI)) { auto SmallSPrintFFn = getOrInsertLibFunc(M, *TLI, LibFunc_small_sprintf, FT, @@ -3769,9 +3784,8 @@ Value *LibCallSimplifier::optimizeFPrintF(CallInst *CI, IRBuilderBase &B) { // 128-bit floating point arguments. if (isLibFuncEmittable(M, TLI, LibFunc_small_fprintf) && !callHasFP128Argument(CI)) { - auto SmallFPrintFFn = - getOrInsertLibFunc(M, *TLI, LibFunc_small_fprintf, FT, - Callee->getAttributes()); + auto SmallFPrintFFn = getOrInsertLibFunc(M, *TLI, LibFunc_small_fprintf, FT, + Callee->getAttributes()); CallInst *New = cast(CI->clone()); New->setCalledFunction(SmallFPrintFFn); B.Insert(New); @@ -3829,11 +3843,9 @@ Value *LibCallSimplifier::optimizeFPuts(CallInst *CI, IRBuilderBase &B) { // Known to have no uses (see above). unsigned SizeTBits = TLI->getSizeTSize(*CI->getModule()); Type *SizeTTy = IntegerType::get(CI->getContext(), SizeTBits); - return copyFlags( - *CI, - emitFWrite(CI->getArgOperand(0), - ConstantInt::get(SizeTTy, Len - 1), - CI->getArgOperand(1), B, DL, TLI)); + return copyFlags(*CI, emitFWrite(CI->getArgOperand(0), + ConstantInt::get(SizeTTy, Len - 1), + CI->getArgOperand(1), B, DL, TLI)); } Value *LibCallSimplifier::optimizePuts(CallInst *CI, IRBuilderBase &B) { @@ -4019,10 +4031,10 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI, switch (Func) { case LibFunc_sinpif: case LibFunc_sinpi: - return optimizeSinCosPi(CI, /*IsSin*/true, Builder); + return optimizeSinCosPi(CI, /*IsSin*/ true, Builder); case LibFunc_cospif: case LibFunc_cospi: - return optimizeSinCosPi(CI, /*IsSin*/false, Builder); + return optimizeSinCosPi(CI, /*IsSin*/ false, Builder); case LibFunc_powf: case LibFunc_pow: case LibFunc_powl: @@ -4031,6 +4043,17 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI, case LibFunc_exp2: case LibFunc_exp2f: return optimizeExp2(CI, Builder); + // New ldexp / scalbn / scalbln family: + case LibFunc_ldexp: + case LibFunc_: + case LibFunc_ldexpl: + case LibFunc_scalbn: + case LibFunc_scalbnf: + case LibFunc_scalbnl: + case LibFunc_scalbln: + case LibFunc_scalblnf: + case LibFunc_scalblnl: + return foldLdexp(CI, Builder); case LibFunc_fabsf: case LibFunc_fabs: case LibFunc_fabsl: @@ -4100,7 +4123,8 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI, case LibFunc_cos: case LibFunc_sin: case LibFunc_tanh: - if (UnsafeFPShrink && hasFloatVersion(M, CI->getCalledFunction()->getName())) + if (UnsafeFPShrink && + hasFloatVersion(M, CI->getCalledFunction()->getName())) return optimizeUnaryDoubleFP(CI, Builder, TLI, true); return nullptr; case LibFunc_copysign: @@ -4284,9 +4308,7 @@ void LibCallSimplifier::replaceAllUsesWith(Instruction *I, Value *With) { Replacer(I, With); } -void LibCallSimplifier::eraseFromParent(Instruction *I) { - Eraser(I); -} +void LibCallSimplifier::eraseFromParent(Instruction *I) { Eraser(I); } // TODO: // Additional cases that we need to add to this file: @@ -4461,8 +4483,8 @@ Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(CallInst *CI, Value *FortifiedLibCallSimplifier::optimizeStrLenChk(CallInst *CI, IRBuilderBase &B) { if (isFortifiedCallFoldable(CI, 1, std::nullopt, 0)) - return copyFlags(*CI, emitStrLen(CI->getArgOperand(0), B, - CI->getDataLayout(), TLI)); + return copyFlags( + *CI, emitStrLen(CI->getArgOperand(0), B, CI->getDataLayout(), TLI)); return nullptr; }