[llvm] r340061 - [InstCombine] Refactor the simplification of pow() (NFC)
Evandro Menezes via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 17 10:59:54 PDT 2018
Author: evandro
Date: Fri Aug 17 10:59:53 2018
New Revision: 340061
URL: http://llvm.org/viewvc/llvm-project?rev=340061&view=rev
Log:
[InstCombine] Refactor the simplification of pow() (NFC)
Refactor all cases dealing with `exp{,2,10}()` into one function in
preparation for D49273. Otherwise, NFC.
Modified:
llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h
llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
Modified: llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h?rev=340061&r1=340060&r2=340061&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h Fri Aug 17 10:59:53 2018
@@ -132,6 +132,7 @@ private:
// Math Library Optimizations
Value *optimizeCAbs(CallInst *CI, IRBuilder<> &B);
Value *optimizePow(CallInst *CI, IRBuilder<> &B);
+ Value *replacePowWithExp(CallInst *Pow, IRBuilder<> &B);
Value *replacePowWithSqrt(CallInst *Pow, IRBuilder<> &B);
Value *optimizeExp2(CallInst *CI, IRBuilder<> &B);
Value *optimizeFMinFMax(CallInst *CI, IRBuilder<> &B);
Modified: llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp?rev=340061&r1=340060&r2=340061&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp Fri Aug 17 10:59:53 2018
@@ -1182,6 +1182,55 @@ static Value *getPow(Value *InnerChain[3
return InnerChain[Exp];
}
+/// Use exp{,2}(x * y) for pow(exp{,2}(x), y);
+/// exp2(x) for pow(2.0, x); exp10(x) for pow(10.0, x).
+Value *LibCallSimplifier::replacePowWithExp(CallInst *Pow, IRBuilder<> &B) {
+ Value *Base = Pow->getArgOperand(0), *Expo = Pow->getArgOperand(1);
+ AttributeList Attrs = Pow->getCalledFunction()->getAttributes();
+ Module *Mod = Pow->getModule();
+ Type *Ty = Pow->getType();
+
+ // Evaluate special cases related to a nested function as the base.
+
+ // pow(exp(x), y) -> exp(x * y)
+ // pow(exp2(x), y) -> exp2(x * y)
+ // Only with fully relaxed math semantics, since, besides rounding
+ // differences, the transformation changes overflow and underflow behavior
+ // quite dramatically.
+ // For example:
+ // pow(exp(1000), 0.001) = pow(inf, 0.001) = inf
+ // Whereas:
+ // exp(1000 * 0.001) = exp(1)
+ // TODO: Loosen the requirement for fully relaxed math semantics.
+ // TODO: Handle exp10() when more targets have it available.
+ CallInst *BaseFn = dyn_cast<CallInst>(Base);
+ if (BaseFn && BaseFn->isFast() && Pow->isFast()) {
+ LibFunc LibFn;
+ Function *CalleeFn = BaseFn->getCalledFunction();
+ if (CalleeFn && TLI->getLibFunc(CalleeFn->getName(), LibFn) &&
+ (LibFn == LibFunc_exp || LibFn == LibFunc_exp2) && TLI->has(LibFn)) {
+ Value *FMul = B.CreateFMul(BaseFn->getArgOperand(0), Expo, "mul");
+ return emitUnaryFloatFnCall(FMul, CalleeFn->getName(), B, Attrs);
+ }
+ }
+
+ // Evaluate special cases related to a constant base.
+
+ // pow(2.0, x) -> exp2(x)
+ if (match(Base, m_SpecificFP(2.0))) {
+ Value *Exp2 = Intrinsic::getDeclaration(Mod, Intrinsic::exp2, Ty);
+ return B.CreateCall(Exp2, Expo, "exp2");
+ }
+
+ // pow(10.0, x) -> exp10(x)
+ // TODO: There is no exp10() intrinsic yet, but some day there shall be one.
+ if (match(Base, m_SpecificFP(10.0)) &&
+ hasUnaryFloatFn(TLI, Ty, LibFunc_exp10, LibFunc_exp10f, LibFunc_exp10l))
+ return emitUnaryFloatFnCall(Expo, TLI->getName(LibFunc_exp10), B, Attrs);
+
+ return nullptr;
+}
+
/// Use square root in place of pow(x, +/-0.5).
Value *LibCallSimplifier::replacePowWithSqrt(CallInst *Pow, IRBuilder<> &B) {
Value *Sqrt, *Base = Pow->getArgOperand(0), *Expo = Pow->getArgOperand(1);
@@ -1234,9 +1283,7 @@ Value *LibCallSimplifier::replacePowWith
Value *LibCallSimplifier::optimizePow(CallInst *Pow, IRBuilder<> &B) {
Value *Base = Pow->getArgOperand(0), *Expo = Pow->getArgOperand(1);
Function *Callee = Pow->getCalledFunction();
- AttributeList Attrs = Callee->getAttributes();
StringRef Name = Callee->getName();
- Module *Module = Pow->getModule();
Type *Ty = Pow->getType();
Value *Shrunk = nullptr;
bool Ignored;
@@ -1261,36 +1308,8 @@ Value *LibCallSimplifier::optimizePow(Ca
if (match(Base, m_FPOne()))
return Base;
- // pow(2.0, x) -> exp2(x)
- if (match(Base, m_SpecificFP(2.0))) {
- Value *Exp2 = Intrinsic::getDeclaration(Module, Intrinsic::exp2, Ty);
- return B.CreateCall(Exp2, Expo, "exp2");
- }
-
- // pow(10.0, x) -> exp10(x)
- if (ConstantFP *BaseC = dyn_cast<ConstantFP>(Base))
- // There's no exp10 intrinsic yet, but, maybe, some day there shall be one.
- if (BaseC->isExactlyValue(10.0) &&
- hasUnaryFloatFn(TLI, Ty, LibFunc_exp10, LibFunc_exp10f, LibFunc_exp10l))
- return emitUnaryFloatFnCall(Expo, TLI->getName(LibFunc_exp10), B, Attrs);
-
- // pow(exp(x), y) -> exp(x * y)
- // pow(exp2(x), y) -> exp2(x * y)
- // We enable these only with fast-math. Besides rounding differences, the
- // transformation changes overflow and underflow behavior quite dramatically.
- // Example: x = 1000, y = 0.001.
- // pow(exp(x), y) = pow(inf, 0.001) = inf, whereas exp(x * y) = exp(1).
- auto *BaseFn = dyn_cast<CallInst>(Base);
- if (BaseFn && BaseFn->isFast() && Pow->isFast()) {
- LibFunc LibFn;
- Function *CalleeFn = BaseFn->getCalledFunction();
- if (CalleeFn && TLI->getLibFunc(CalleeFn->getName(), LibFn) &&
- (LibFn == LibFunc_exp || LibFn == LibFunc_exp2) && TLI->has(LibFn)) {
- Value *FMul = B.CreateFMul(BaseFn->getArgOperand(0), Expo, "mul");
- return emitUnaryFloatFnCall(FMul, CalleeFn->getName(), B,
- CalleeFn->getAttributes());
- }
- }
+ if (Value *Exp = replacePowWithExp(Pow, B))
+ return Exp;
// Evaluate special cases related to the exponent.
More information about the llvm-commits
mailing list