diff options
author | Chris Lattner <sabre@nondot.org> | 2008-05-02 18:43:35 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-05-02 18:43:35 +0000 |
commit | e818f770bb4f6617612e5b61cc067aa7da9e1395 (patch) | |
tree | d3b05a5b59f3423406e66a4bca96b7bdc71d8b42 /lib/Transforms | |
parent | 4446997e0a23c58940f587eaf5d2f6d745821a02 (diff) |
strength reduce exp2 into ldexp, rdar://5852514
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50586 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/Scalar/SimplifyLibCalls.cpp | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp index e9c089dbd0..d43a181d73 100644 --- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp +++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp @@ -838,6 +838,53 @@ struct VISIBILITY_HIDDEN PowOpt : public LibCallOptimization { }; //===---------------------------------------===// +// 'exp2' Optimizations + +struct VISIBILITY_HIDDEN Exp2Opt : public LibCallOptimization { + virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder &B) { + const FunctionType *FT = Callee->getFunctionType(); + // Just make sure this has 1 argument of FP type, which matches the + // result type. + if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) || + !FT->getParamType(0)->isFloatingPoint()) + return 0; + + Value *Op = CI->getOperand(1); + // Turn exp2(sitofp(x)) -> ldexp(1.0, sext(x)) if sizeof(x) <= 32 + // Turn exp2(uitofp(x)) -> ldexp(1.0, zext(x)) if sizeof(x) < 32 + Value *LdExpArg = 0; + if (SIToFPInst *OpC = dyn_cast<SIToFPInst>(Op)) { + if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() <= 32) + LdExpArg = B.CreateSExt(OpC->getOperand(0), Type::Int32Ty, "tmp"); + } else if (UIToFPInst *OpC = dyn_cast<UIToFPInst>(Op)) { + if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() < 32) + LdExpArg = B.CreateZExt(OpC->getOperand(0), Type::Int32Ty, "tmp"); + } + + if (LdExpArg) { + const char *Name; + if (Op->getType() == Type::FloatTy) + Name = "ldexpf"; + else if (Op->getType() == Type::DoubleTy) + Name = "ldexp"; + else + Name = "ldexpl"; + + Constant *One = ConstantFP::get(APFloat(1.0f)); + if (Op->getType() != Type::FloatTy) + One = ConstantExpr::getFPExtend(One, Op->getType()); + + Module *M = Caller->getParent(); + Value *Callee = M->getOrInsertFunction(Name, Op->getType(), + Op->getType(), Type::Int32Ty,NULL); + return B.CreateCall2(Callee, One, LdExpArg); + } + return 0; + } +}; + + +//===---------------------------------------===// // Double -> Float Shrinking Optimizations for Unary Functions like 'floor' struct VISIBILITY_HIDDEN UnaryDoubleFPOpt : public LibCallOptimization { @@ -1205,7 +1252,7 @@ namespace { StrCatOpt StrCat; StrChrOpt StrChr; StrCmpOpt StrCmp; StrNCmpOpt StrNCmp; StrCpyOpt StrCpy; StrLenOpt StrLen; MemCmpOpt MemCmp; MemCpyOpt MemCpy; // Math Library Optimizations - PowOpt Pow; UnaryDoubleFPOpt UnaryDoubleFP; + PowOpt Pow; Exp2Opt Exp2; UnaryDoubleFPOpt UnaryDoubleFP; // Integer Optimizations FFSOpt FFS; IsDigitOpt IsDigit; IsAsciiOpt IsAscii; ToAsciiOpt ToAscii; // Formatting and IO Optimizations @@ -1253,6 +1300,10 @@ void SimplifyLibCalls::InitOptimizations() { Optimizations["powf"] = &Pow; Optimizations["pow"] = &Pow; Optimizations["powl"] = &Pow; + Optimizations["exp2l"] = &Exp2; + Optimizations["exp2"] = &Exp2; + Optimizations["exp2f"] = &Exp2; + #ifdef HAVE_FLOORF Optimizations["floor"] = &UnaryDoubleFP; #endif |