[PATCH] D14045: [SimplifyLibCalls] Add a new transform: pow(exp(x), y) -> exp(x*y)

Davide Italiano via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 25 02:28:39 PDT 2015


davide created this revision.
davide added a reviewer: majnemer.
davide added a subscriber: llvm-commits.

Hi David, this should save a function call. The code passes basic testing. This is my first dive into SimplifyLibCalls, I may miss some details, please bear with me.

http://reviews.llvm.org/D14045

Files:
  lib/Transforms/Utils/SimplifyLibCalls.cpp
  test/Transforms/InstCombine/pow-exp.ll

Index: test/Transforms/InstCombine/pow-exp.ll
===================================================================
--- test/Transforms/InstCombine/pow-exp.ll
+++ test/Transforms/InstCombine/pow-exp.ll
@@ -0,0 +1,28 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-freebsd11.0"
+
+define double @mypow(double %x, double %y) #0 {
+entry:
+  %x.addr = alloca double, align 8
+  %y.addr = alloca double, align 8
+  store double %x, double* %x.addr, align 8
+  store double %y, double* %y.addr, align 8
+  %0 = load double, double* %x.addr, align 8
+  %call = call double @exp(double %0) #2
+  %1 = load double, double* %y.addr, align 8
+  %2 = call double @llvm.pow.f64(double %call, double %1)
+  ret double %2
+}
+
+declare double @exp(double) #1
+declare double @llvm.pow.f64(double, double) #2
+
+; CHECK: define double @mypow(double %x, double %y) {
+; CHECK: entry:
+; CHECK:   %call = call double @exp(double %x)
+; CHECK:   %mul = fmul double %x, %y
+; CHECK:   %exp = call double @exp(double %mul)
+; CHECK:   ret double %exp
+; CHECK: }
Index: lib/Transforms/Utils/SimplifyLibCalls.cpp
===================================================================
--- lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -1091,6 +1091,20 @@
                                   Callee->getAttributes());
   }
 
+
+  // pow(exp(x), y) -> exp(x*y)
+  if (CallInst *OpC = dyn_cast<CallInst>(Op1)) {
+    LibFunc::Func Func;
+    Function *Callee = OpC->getCalledFunction();
+    StringRef FuncName = Callee->getName();
+
+    if (TLI->getLibFunc(FuncName, Func) && TLI->has(Func) &&
+        Func == LibFunc::exp && Op2->getType()->isDoubleTy())
+      return EmitUnaryFloatFnCall(
+        B.CreateFMul(OpC->getArgOperand(0), Op2, "mul"),
+        TLI->getName(LibFunc::exp), B, Callee->getAttributes());
+  }
+
   ConstantFP *Op2C = dyn_cast<ConstantFP>(Op2);
   if (!Op2C)
     return Ret;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D14045.38342.patch
Type: text/x-patch
Size: 2019 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151025/afe2c3da/attachment.bin>


More information about the llvm-commits mailing list