Transform floor((double)FLT) -> (double)floorf(FLT), implementing
authorChris Lattner <sabre@nondot.org>
Wed, 24 Aug 2005 17:22:17 +0000 (17:22 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 24 Aug 2005 17:22:17 +0000 (17:22 +0000)
Regression/Transforms/SimplifyLibCalls/floor.ll.  This triggers 19 times in
177.mesa.

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

lib/Transforms/IPO/SimplifyLibCalls.cpp

index b8337d6f25070091d176b47ecfc5556bc8d46fb3..19e2f6c820a842b3abb8d1e8814138600e30d74e 100644 (file)
@@ -129,7 +129,8 @@ private:
 /// instances to all the call sites in a module, relatively efficiently. The
 /// purpose of this pass is to provide optimizations for calls to well-known
 /// functions with well-known semantics, such as those in the c library. The
-/// class provides the basic infrastructure for handling runOnModule.  Whenever /// this pass finds a function call, it asks the appropriate optimizer to
+/// class provides the basic infrastructure for handling runOnModule.  Whenever
+/// this pass finds a function call, it asks the appropriate optimizer to
 /// validate the call (ValidateLibraryCall). If it is validated, then
 /// the OptimizeCall method is also called.
 /// @brief A ModulePass for optimizing well-known function calls.
@@ -306,22 +307,22 @@ public:
   }
 
   /// @brief Return a Function* for the memcpy libcall
-  Function* get_memcpy()
-  {
-    if (!memcpy_func)
-    {
-      // Note: this is for llvm.memcpy intrinsic
-      std::vector<const Type*> args;
-      args.push_back(PointerType::get(Type::SByteTy));
-      args.push_back(PointerType::get(Type::SByteTy));
-      args.push_back(Type::UIntTy);
-      args.push_back(Type::UIntTy);
-      FunctionType* memcpy_type = FunctionType::get(Type::VoidTy, args, false);
-      memcpy_func = M->getOrInsertFunction("llvm.memcpy",memcpy_type);
+  Function* get_memcpy() {
+    if (!memcpy_func) {
+      const Type *SBP = PointerType::get(Type::SByteTy);
+      memcpy_func = M->getOrInsertFunction("llvm.memcpy", Type::VoidTy,SBP, SBP,
+                                           Type::UIntTy, Type::UIntTy, 0);
     }
     return memcpy_func;
   }
 
+  Function* get_floorf() {
+    if (!floorf_func)
+      floorf_func = M->getOrInsertFunction("floorf", Type::FloatTy,
+                                           Type::FloatTy, 0);
+    return floorf_func;
+  }
+  
 private:
   /// @brief Reset our cached data for a new Module
   void reset(Module& mod)
@@ -335,6 +336,7 @@ private:
     sqrt_func   = 0;
     strcpy_func = 0;
     strlen_func = 0;
+    floorf_func = 0;
   }
 
 private:
@@ -345,6 +347,7 @@ private:
   Function* sqrt_func;   ///< Cached sqrt function
   Function* strcpy_func; ///< Cached strcpy function
   Function* strlen_func; ///< Cached strlen function
+  Function* floorf_func; ///< Cached floorf function
   Module* M;             ///< Cached Module
   TargetData* TD;        ///< Cached TargetData
 };
@@ -1238,7 +1241,7 @@ public:
       else if (Op2V == -1.0)
       {
         // pow(x,-1.0)    -> 1.0/x
-        BinaryOperator* div_inst= BinaryOperator::create(Instruction::Div,
+        BinaryOperator* div_inst= BinaryOperator::createDiv(
           ConstantFP::get(Ty,1.0), base, ci->getName()+".pow", ci);
         ci->replaceAllUsesWith(div_inst);
         ci->eraseFromParent();
@@ -1641,7 +1644,7 @@ public:
     CastInst* cast =
       new CastInst(ci->getOperand(1),Type::UIntTy,
         ci->getOperand(1)->getName()+".uint",ci);
-    BinaryOperator* sub_inst = BinaryOperator::create(Instruction::Sub,cast,
+    BinaryOperator* sub_inst = BinaryOperator::createSub(cast,
         ConstantUInt::get(Type::UIntTy,0x30),
         ci->getOperand(1)->getName()+".sub",ci);
     SetCondInst* setcond_inst = new SetCondInst(Instruction::SetLE,sub_inst,
@@ -1682,7 +1685,7 @@ public:
   {
     // toascii(c)   -> (c & 0x7f)
     Value* chr = ci->getOperand(1);
-    BinaryOperator* and_inst = BinaryOperator::create(Instruction::And,chr,
+    BinaryOperator* and_inst = BinaryOperator::createAnd(chr,
         ConstantInt::get(chr->getType(),0x7F),ci->getName()+".toascii",ci);
     ci->replaceAllUsesWith(and_inst);
     ci->eraseFromParent();
@@ -1753,7 +1756,7 @@ public:
       new CallInst(F, ci->getOperand(1), inst_name, ci);
     if (arg_type != Type::IntTy)
       call = new CastInst(call, Type::IntTy, inst_name, ci);
-    BinaryOperator* add = BinaryOperator::create(Instruction::Add, call,
+    BinaryOperator* add = BinaryOperator::createAdd(call,
       ConstantSInt::get(Type::IntTy,1), inst_name, ci);
     SetCondInst* eq = new SetCondInst(Instruction::SetEQ,ci->getOperand(1),
       ConstantSInt::get(ci->getOperand(1)->getType(),0),inst_name,ci);
@@ -1791,6 +1794,41 @@ public:
 
 } FFSLLOptimizer;
 
+
+/// This LibCallOptimization will simplify calls to the "floor" library
+/// function.
+/// @brief Simplify the floor library function.
+struct FloorOptimization : public LibCallOptimization {
+  FloorOptimization()
+    : LibCallOptimization("floor", "Number of 'floor' calls simplified") {}
+  
+  /// @brief Make sure that the "floor" function has the right prototype
+  virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
+    return F->arg_size() == 1 && F->arg_begin()->getType() == Type::DoubleTy &&
+           F->getReturnType() == Type::DoubleTy;
+  }
+  
+  virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
+    // If this is a float argument passed in, convert to floorf.
+    // e.g. floor((double)FLT) -> (double)floorf(FLT).  There can be no loss of
+    // precision due to this.
+    if (CastInst *Cast = dyn_cast<CastInst>(CI->getOperand(1)))
+      if (Cast->getOperand(0)->getType() == Type::FloatTy) {
+        Value *New = new CallInst(SLC.get_floorf(), Cast->getOperand(0),
+                                  CI->getName(), CI);
+        New = new CastInst(New, Type::DoubleTy, CI->getName(), CI);
+        CI->replaceAllUsesWith(New);
+        CI->eraseFromParent();
+        if (Cast->use_empty())
+          Cast->eraseFromParent();
+        return true;
+      }
+    return false; // opt failed
+  }
+} FloorOptimizer;
+
+
+
 /// A function to compute the length of a null-terminated constant array of
 /// integers.  This function can't rely on the size of the constant array
 /// because there could be a null terminator in the middle of the array.