[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