[PATCH] D49040: [SLC] Simplify pow(x, 0.333...) to cbrt(x)
Evandro Menezes via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 6 13:38:09 PDT 2018
evandro created this revision.
evandro added reviewers: spatel, davide.
Herald added subscribers: llvm-commits, hiraditya.
This transformation helps some benchmarks in SPEC CPU200 and CPU2006, such as 188.ammp, 447.dealII, 453.povray, and especially 300.twolf, as well as some proprietary benchmarks. Otherwise, no regressions on x86-64 or A64.
At the moment, it only handles `double`, as I'm having a hard time matching the exponent when it's a `float`. Suggestions are welcome.
Repository:
rL LLVM
https://reviews.llvm.org/D49040
Files:
llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
Index: llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
===================================================================
--- llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -1119,6 +1119,48 @@
return InnerChain[Exp];
}
+/// Use cube root in place of pow(x, +/-0.333...).
+Value *LibCallSimplifier::replacePowWithCbrt(CallInst *Pow, IRBuilder<> &B) {
+ // Only in finite and normal math.
+ if (!Pow->hasNoInfs() || !Pow->hasNoNaNs())
+ return nullptr;
+
+ Type *Ty = Pow->getType();
+ Type::TypeID TyID = Ty->getTypeID();
+ // TODO: Handle SP FP as well, though the argument seems to never match below.
+ if (TyID != Type::DoubleTyID)
+ return nullptr;
+
+ ConstantFP *Arg2C = dyn_cast<ConstantFP>(Pow->getArgOperand(1));
+ if (!Arg2C)
+ return nullptr;
+
+ const APFloat SPPlusThird(1.0f / 3.0f), SPMinusThird(-1.0f / 3.0f),
+ DPPlusThird(1.0 / 3.0), DPMinusThird(-1.0 / 3.0);
+ bool isPlusThird = Arg2C->isExactlyValue((TyID == Type::FloatTyID)
+ ? SPPlusThird : DPPlusThird),
+ isMinusThird = Arg2C->isExactlyValue((TyID == Type::FloatTyID)
+ ? SPMinusThird : DPMinusThird);
+ if (!isPlusThird && !isMinusThird)
+ return nullptr;
+
+ if (!hasUnaryFloatFn(TLI, Ty, LibFunc_cbrt, LibFunc_cbrtf, LibFunc_cbrtl))
+ return nullptr;
+
+ // Fast-math flags from the pow() are propagated to all replacement ops.
+ IRBuilder<>::FastMathFlagGuard Guard(B);
+ B.setFastMathFlags(Pow->getFastMathFlags());
+ Value *Cbrt = emitUnaryFloatFnCall(Pow->getArgOperand(0),
+ TLI->getName(LibFunc_cbrt), B,
+ Pow->getCalledFunction()->getAttributes());
+
+ // If this is pow(x, -0.333...), get the reciprocal.
+ if (isMinusThird)
+ Cbrt = B.CreateFDiv(ConstantFP::get(Ty, 1.0), Cbrt);
+
+ return Cbrt;
+}
+
/// Use square root in place of pow(x, +/-0.5).
Value *LibCallSimplifier::replacePowWithSqrt(CallInst *Pow, IRBuilder<> &B) {
// TODO: There is some subset of 'fast' under which these transforms should
@@ -1217,6 +1259,9 @@
if (Value *Sqrt = replacePowWithSqrt(CI, B))
return Sqrt;
+ if (Value *Cbrt = replacePowWithCbrt(CI, B))
+ return Cbrt;
+
ConstantFP *Op2C = dyn_cast<ConstantFP>(Op2);
if (!Op2C)
return Ret;
Index: llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
===================================================================
--- llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
+++ llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
@@ -133,6 +133,7 @@
Value *optimizeCAbs(CallInst *CI, IRBuilder<> &B);
Value *optimizeCos(CallInst *CI, IRBuilder<> &B);
Value *optimizePow(CallInst *CI, IRBuilder<> &B);
+ Value *replacePowWithCbrt(CallInst *Pow, IRBuilder<> &B);
Value *replacePowWithSqrt(CallInst *Pow, IRBuilder<> &B);
Value *optimizeExp2(CallInst *CI, IRBuilder<> &B);
Value *optimizeFMinFMax(CallInst *CI, IRBuilder<> &B);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D49040.154448.patch
Type: text/x-patch
Size: 3073 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180706/b0a600bd/attachment.bin>
More information about the llvm-commits
mailing list