From e818f770bb4f6617612e5b61cc067aa7da9e1395 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 2 May 2008 18:43:35 +0000 Subject: [PATCH] strength reduce exp2 into ldexp, rdar://5852514 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50586 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/SimplifyLibCalls.cpp | 53 +++++++++++++++++++++- test/Transforms/SimplifyLibCalls/exp2.ll | 38 ++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 test/Transforms/SimplifyLibCalls/exp2.ll diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp index e9c089dbd07..d43a181d732 100644 --- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp +++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp @@ -837,6 +837,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(Op)) { + if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() <= 32) + LdExpArg = B.CreateSExt(OpC->getOperand(0), Type::Int32Ty, "tmp"); + } else if (UIToFPInst *OpC = dyn_cast(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' @@ -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 diff --git a/test/Transforms/SimplifyLibCalls/exp2.ll b/test/Transforms/SimplifyLibCalls/exp2.ll new file mode 100644 index 00000000000..dea3df4b51b --- /dev/null +++ b/test/Transforms/SimplifyLibCalls/exp2.ll @@ -0,0 +1,38 @@ +; RUN: llvm-as < %s | opt -simplify-libcalls | llvm-dis | grep {call.*ldexp} | count 4 +; rdar://5852514 + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin8" + +define double @t1(i32 %x) nounwind { +entry: + %tmp12 = sitofp i32 %x to double ; [#uses=1] + %exp2 = tail call double @exp2( double %tmp12 ) ; [#uses=1] + ret double %exp2 +} + +define float @t4(i8 zeroext %x) nounwind { +entry: + %tmp12 = uitofp i8 %x to float ; [#uses=1] + %tmp3 = tail call float @exp2f( float %tmp12 ) nounwind readonly ; [#uses=1] + ret float %tmp3 +} + +declare float @exp2f(float) nounwind readonly + +define double @t3(i16 zeroext %x) nounwind { +entry: + %tmp12 = uitofp i16 %x to double ; [#uses=1] + %exp2 = tail call double @exp2( double %tmp12 ) ; [#uses=1] + ret double %exp2 +} + +define double @t2(i16 signext %x) nounwind { +entry: + %tmp12 = sitofp i16 %x to double ; [#uses=1] + %exp2 = tail call double @exp2( double %tmp12 ) ; [#uses=1] + ret double %exp2 +} + +declare double @exp2(double) +