Generalize getUnaryFloatFunction to handle any FP unary function, automatically
authorChris Lattner <sabre@nondot.org>
Wed, 9 Apr 2008 17:48:11 +0000 (17:48 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 9 Apr 2008 17:48:11 +0000 (17:48 +0000)
figuring out the suffix to use.  implement pow(2,x) -> exp2(x).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@49437 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/IPO/SimplifyLibCalls.cpp
test/Transforms/SimplifyLibCalls/pow2.ll

index ce536a8a530f98fada50f344db9984db01d9f16f..f7bc59fd2ee858ad053c64cf8134396449197b4f 100644 (file)
@@ -328,18 +328,36 @@ public:
     return memcpy_func;
   }
 
-  Constant *getUnaryFloatFunction(const char *Name, Constant *&Cache) {
-    if (!Cache)
-      Cache = M->getOrInsertFunction(Name, Type::FloatTy, Type::FloatTy, NULL);
-    return Cache;
+  Constant *getUnaryFloatFunction(const char *BaseName, const Type *T = 0) {
+    if (T == 0) T = Type::FloatTy;
+    
+    char NameBuffer[20];
+    const char *Name;
+    if (T == Type::DoubleTy)
+      Name = BaseName;              // floor
+    else {
+      Name = NameBuffer;
+      unsigned NameLen = strlen(BaseName);
+      assert(NameLen < sizeof(NameBuffer)-2 && "Buffer too small");
+      memcpy(NameBuffer, BaseName, NameLen);
+      if (T == Type::FloatTy)
+        NameBuffer[NameLen] = 'f';  // floorf
+      else
+        NameBuffer[NameLen] = 'l';  // floorl
+      NameBuffer[NameLen+1] = 0;
+    }
+    
+    return M->getOrInsertFunction(Name, T, T, NULL);
   }
   
-  Constant *get_floorf() { return getUnaryFloatFunction("floorf", floorf_func);}
-  Constant *get_ceilf()  { return getUnaryFloatFunction( "ceilf",  ceilf_func);}
-  Constant *get_roundf() { return getUnaryFloatFunction("roundf", roundf_func);}
-  Constant *get_rintf()  { return getUnaryFloatFunction( "rintf",  rintf_func);}
-  Constant *get_nearbyintf() { return getUnaryFloatFunction("nearbyintf",
-                                                            nearbyintf_func); }
+  Constant *get_floorf() { return getUnaryFloatFunction("floor"); }
+  Constant *get_ceilf()  { return getUnaryFloatFunction( "ceil"); }
+  Constant *get_roundf() { return getUnaryFloatFunction("round"); }
+  Constant *get_rintf()  { return getUnaryFloatFunction( "rint"); }
+  Constant *get_nearbyintf() { return getUnaryFloatFunction("nearbyint"); }
+
+  
+  
 private:
   /// @brief Reset our cached data for a new Module
   void reset(Module& mod) {
@@ -355,11 +373,6 @@ private:
     sqrt_func   = 0;
     strcpy_func = 0;
     strlen_func = 0;
-    floorf_func = 0;
-    ceilf_func = 0;
-    roundf_func = 0;
-    rintf_func = 0;
-    nearbyintf_func = 0;
   }
 
 private:
@@ -369,8 +382,6 @@ private:
   Constant *memcpy_func, *memchr_func;
   Constant *sqrt_func;
   Constant *strcpy_func, *strlen_func;
-  Constant *floorf_func, *ceilf_func, *roundf_func;
-  Constant *rintf_func, *nearbyintf_func;
   Module *M;             ///< Cached Module
   TargetData *TD;        ///< Cached TargetData
 };
@@ -1154,6 +1165,11 @@ public:
     if (ConstantFP *Op1C = dyn_cast<ConstantFP>(Op1)) {
       if (Op1C->isExactlyValue(1.0)) // pow(1.0, x) -> 1.0
         return ReplaceCallWith(CI, Op1C);
+      if (Op1C->isExactlyValue(2.0)) {// pow(2.0, x) -> exp2(x)
+        Value *Exp2 = SLC.getUnaryFloatFunction("exp2", CI->getType());
+        Value *Res = CallInst::Create(Exp2, Op2, CI->getName()+"exp2", CI);
+        return ReplaceCallWith(CI, Res);
+      }
     }
     
     ConstantFP *Op2C = dyn_cast<ConstantFP>(Op2);
index c039d80a2c9043f2e73c44f3e8d5778a10242a5b..a48abbaf1e7492415980bfc8e6fd08efb385b3f6 100644 (file)
@@ -30,3 +30,8 @@ define float @test4f(float %X) {
        %Y = call float @powf( float %X, float 2.0)
        ret float %Y
 }
+
+define float @test5f(float %X) {
+       %Y = call float @powf(float 2.0, float %X)  ;; exp2
+       ret float %Y
+}