adjust to constant folding api changes.
[oota-llvm.git] / lib / Analysis / ConstantFolding.cpp
index 4022bdda1def3609941241c65535b48a6d59a750..ef70ece7765bee26d7ca00f7d2376c79a4d9518c 100644 (file)
@@ -35,8 +35,26 @@ llvm::canConstantFoldCallTo(Function *F) {
   const std::string &Name = F->getName();
 
   switch (F->getIntrinsicID()) {
-  case Intrinsic::isunordered:
-  case Intrinsic::sqrt:
+  case Intrinsic::sqrt_f32:
+  case Intrinsic::sqrt_f64:
+  case Intrinsic::bswap_i16:
+  case Intrinsic::bswap_i32:
+  case Intrinsic::bswap_i64:
+  case Intrinsic::powi_f32:
+  case Intrinsic::powi_f64:
+  // FIXME: these should be constant folded as well
+  //case Intrinsic::ctpop_i8:
+  //case Intrinsic::ctpop_i16:
+  //case Intrinsic::ctpop_i32:
+  //case Intrinsic::ctpop_i64:
+  //case Intrinsic::ctlz_i8:
+  //case Intrinsic::ctlz_i16:
+  //case Intrinsic::ctlz_i32:
+  //case Intrinsic::ctlz_i64:
+  //case Intrinsic::cttz_i8:
+  //case Intrinsic::cttz_i16:
+  //case Intrinsic::cttz_i32:
+  //case Intrinsic::cttz_i64:
     return true;
   default: break;
   }
@@ -58,7 +76,8 @@ llvm::canConstantFoldCallTo(Function *F) {
     case 'p':
       return Name == "pow";
     case 's':
-      return Name == "sin" || Name == "sinh" || Name == "sqrt";
+      return Name == "sin" || Name == "sinh" || 
+             Name == "sqrt" || Name == "sqrtf";
     case 't':
       return Name == "tan" || Name == "tanh";
     default:
@@ -66,23 +85,24 @@ llvm::canConstantFoldCallTo(Function *F) {
   }
 }
 
-Constant *
-llvm::ConstantFoldFP(double (*NativeFP)(double), double V, const Type *Ty) {
+static Constant *ConstantFoldFP(double (*NativeFP)(double), double V, 
+                                const Type *Ty) {
   errno = 0;
   V = NativeFP(V);
   if (errno == 0)
     return ConstantFP::get(Ty, V);
+  errno = 0;
   return 0;
 }
 
 /// ConstantFoldCall - Attempt to constant fold a call to the specified function
 /// with the specified arguments, returning null if unsuccessful.
 Constant *
-llvm::ConstantFoldCall(Function *F, const std::vector<Constant*> &Operands) {
+llvm::ConstantFoldCall(Function *F, Constant** Operands, unsigned NumOperands) {
   const std::string &Name = F->getName();
   const Type *Ty = F->getReturnType();
 
-  if (Operands.size() == 1) {
+  if (NumOperands == 1) {
     if (ConstantFP *Op = dyn_cast<ConstantFP>(Operands[0])) {
       double V = Op->getValue();
       switch (Name[0])
@@ -118,7 +138,7 @@ llvm::ConstantFoldCall(Function *F, const std::vector<Constant*> &Operands) {
             return ConstantFP::get(Ty, log(V));
           else if (Name == "log10" && V > 0)
             return ConstantFoldFP(log10, V, Ty);
-          else if (Name == "llvm.sqrt") {
+          else if (Name == "llvm.sqrt.f32" || Name == "llvm.sqrt.f64") {
             if (V >= -0.0)
               return ConstantFP::get(Ty, sqrt(V));
             else // Undefined
@@ -132,6 +152,8 @@ llvm::ConstantFoldCall(Function *F, const std::vector<Constant*> &Operands) {
             return ConstantFP::get(Ty, sinh(V));
           else if (Name == "sqrt" && V >= 0)
             return ConstantFP::get(Ty, sqrt(V));
+          else if (Name == "sqrtf" && V >= 0)
+            return ConstantFP::get(Ty, sqrt((float)V));
           break;
         case 't':
           if (Name == "tan")
@@ -142,16 +164,21 @@ llvm::ConstantFoldCall(Function *F, const std::vector<Constant*> &Operands) {
         default:
           break;
       }
+    } else if (ConstantInt *Op = dyn_cast<ConstantInt>(Operands[0])) {
+      uint64_t V = Op->getZExtValue();
+      if (Name == "llvm.bswap.i16")
+        return ConstantInt::get(Ty, ByteSwap_16(V));
+      else if (Name == "llvm.bswap.i32")
+        return ConstantInt::get(Ty, ByteSwap_32(V));
+      else if (Name == "llvm.bswap.i64")
+        return ConstantInt::get(Ty, ByteSwap_64(V));
     }
-  } else if (Operands.size() == 2) {
+  } else if (NumOperands == 2) {
     if (ConstantFP *Op1 = dyn_cast<ConstantFP>(Operands[0])) {
       double Op1V = Op1->getValue();
       if (ConstantFP *Op2 = dyn_cast<ConstantFP>(Operands[1])) {
         double Op2V = Op2->getValue();
 
-        if (Name == "llvm.isunordered")
-          return ConstantBool::get(IsNAN(Op1V) || IsNAN(Op2V));
-        else
         if (Name == "pow") {
           errno = 0;
           double V = pow(Op1V, Op2V);
@@ -162,8 +189,17 @@ llvm::ConstantFoldCall(Function *F, const std::vector<Constant*> &Operands) {
           double V = fmod(Op1V, Op2V);
           if (errno == 0)
             return ConstantFP::get(Ty, V);
-        } else if (Name == "atan2")
+        } else if (Name == "atan2") {
           return ConstantFP::get(Ty, atan2(Op1V,Op2V));
+        }
+      } else if (ConstantInt *Op2C = dyn_cast<ConstantInt>(Operands[1])) {
+        if (Name == "llvm.powi.f32") {
+          return ConstantFP::get(Ty, std::pow((float)Op1V,
+                                              (int)Op2C->getZExtValue()));
+        } else if (Name == "llvm.powi.f64") {
+          return ConstantFP::get(Ty, std::pow((double)Op1V,
+                                              (int)Op2C->getZExtValue()));
+        }
       }
     }
   }