Fix some casts. isdigit(c) returns 0 or 1, not 0 or -1
[oota-llvm.git] / lib / Transforms / IPO / SimplifyLibCalls.cpp
index fefb100c37f56d6ac1cea9a043f1e591e4300955..2c3b66600b6f89aae5a4e3476b72793c8574f726 100644 (file)
@@ -35,7 +35,7 @@ namespace {
 
 /// This statistic keeps track of the total number of library calls that have
 /// been simplified regardless of which call it is.
-Statistic<> SimplifiedLibCalls("simplify-libcalls",
+Statistic SimplifiedLibCalls("simplify-libcalls",
   "Number of library calls simplified");
 
 // Forward declarations
@@ -68,7 +68,7 @@ class LibCallOptimization {
   LibCallOptimization **Prev, *Next;
   const char *FunctionName; ///< Name of the library call we optimize
 #ifndef NDEBUG
-  Statistic<> occurrences; ///< debug statistic (-debug-only=simplify-libcalls)
+  Statistic occurrences; ///< debug statistic (-debug-only=simplify-libcalls)
 #endif
 public:
   /// The \p fname argument must be the name of the library function being
@@ -178,8 +178,10 @@ public:
         // All the "well-known" functions are external and have external linkage
         // because they live in a runtime library somewhere and were (probably)
         // not compiled by LLVM.  So, we only act on external functions that
-        // have external linkage and non-empty uses.
-        if (!FI->isExternal() || !FI->hasExternalLinkage() || FI->use_empty())
+        // have external or dllimport linkage and non-empty uses.
+        if (!FI->isExternal() ||
+            !(FI->hasExternalLinkage() || FI->hasDLLImportLinkage()) ||
+            FI->use_empty())
           continue;
 
         // Get the optimization class that pertains to this function
@@ -221,6 +223,23 @@ public:
   /// @brief Return the size_t type -- syntactic shortcut
   const Type* getIntPtrType() const { return TD->getIntPtrType(); }
 
+  /// @brief Return a Function* for the putchar libcall
+  Function* get_putchar() {
+    if (!putchar_func)
+      putchar_func = M->getOrInsertFunction("putchar", Type::IntTy, Type::IntTy,
+                                            NULL);
+    return putchar_func;
+  }
+
+  /// @brief Return a Function* for the puts libcall
+  Function* get_puts() {
+    if (!puts_func)
+      puts_func = M->getOrInsertFunction("puts", Type::IntTy,
+                                         PointerType::get(Type::SByteTy),
+                                         NULL);
+    return puts_func;
+  }
+
   /// @brief Return a Function* for the fputc libcall
   Function* get_fputc(const Type* FILEptr_type) {
     if (!fputc_func)
@@ -229,6 +248,15 @@ public:
     return fputc_func;
   }
 
+  /// @brief Return a Function* for the fputs libcall
+  Function* get_fputs(const Type* FILEptr_type) {
+    if (!fputs_func)
+      fputs_func = M->getOrInsertFunction("fputs", Type::IntTy,
+                                          PointerType::get(Type::SByteTy),
+                                          FILEptr_type, NULL);
+    return fputs_func;
+  }
+
   /// @brief Return a Function* for the fwrite libcall
   Function* get_fwrite(const Type* FILEptr_type) {
     if (!fwrite_func)
@@ -309,7 +337,10 @@ private:
   void reset(Module& mod) {
     M = &mod;
     TD = &getAnalysis<TargetData>();
+    putchar_func = 0;
+    puts_func = 0;
     fputc_func = 0;
+    fputs_func = 0;
     fwrite_func = 0;
     memcpy_func = 0;
     memchr_func = 0;
@@ -325,7 +356,8 @@ private:
 
 private:
   /// Caches for function pointers.
-  Function *fputc_func, *fwrite_func;
+  Function *putchar_func, *puts_func;
+  Function *fputc_func, *fputs_func, *fwrite_func;
   Function *memcpy_func, *memchr_func;
   Function* sqrt_func;
   Function *strcpy_func, *strlen_func;
@@ -336,8 +368,8 @@ private:
 };
 
 // Register the pass
-RegisterOpt<SimplifyLibCalls>
-X("simplify-libcalls","Simplify well-known library calls");
+RegisterPass<SimplifyLibCalls>
+X("simplify-libcalls", "Simplify well-known library calls");
 
 } // anonymous namespace
 
@@ -485,8 +517,8 @@ public:
     std::vector<Value*> vals;
     vals.push_back(gep); // destination
     vals.push_back(ci->getOperand(2)); // source
-    vals.push_back(ConstantUInt::get(SLC.getIntPtrType(),len)); // length
-    vals.push_back(ConstantUInt::get(Type::UIntTy,1)); // alignment
+    vals.push_back(ConstantInt::get(SLC.getIntPtrType(),len)); // length
+    vals.push_back(ConstantInt::get(Type::UIntTy,1)); // alignment
     new CallInst(SLC.get_memcpy(), vals, "", ci);
 
     // Finally, substitute the first operand of the strcat call for the
@@ -524,38 +556,38 @@ public:
     // Check that the first argument to strchr is a constant array of sbyte.
     // If it is, get the length and data, otherwise return false.
     uint64_t len = 0;
-    ConstantArray* CA;
+    ConstantArray* CA = 0;
     if (!getConstantStringLength(ci->getOperand(1),len,&CA))
       return false;
 
-    // Check that the second argument to strchr is a constant int, return false
-    // if it isn't
-    ConstantSInt* CSI = dyn_cast<ConstantSInt>(ci->getOperand(2));
-    if (!CSI) {
-      // Just lower this to memchr since we know the length of the string as
-      // it is constant.
+    // Check that the second argument to strchr is a constant int. If it isn't
+    // a constant signed integer, we can try an alternate optimization
+    ConstantInt* CSI = dyn_cast<ConstantInt>(ci->getOperand(2));
+    if (!CSI || CSI->getType()->isUnsigned() ) {
+      // The second operand is not constant, or not signed. Just lower this to 
+      // memchr since we know the length of the string since it is constant.
       Function* f = SLC.get_memchr();
       std::vector<Value*> args;
       args.push_back(ci->getOperand(1));
       args.push_back(ci->getOperand(2));
-      args.push_back(ConstantUInt::get(SLC.getIntPtrType(),len));
+      args.push_back(ConstantInt::get(SLC.getIntPtrType(),len));
       ci->replaceAllUsesWith( new CallInst(f,args,ci->getName(),ci));
       ci->eraseFromParent();
       return true;
     }
 
     // Get the character we're looking for
-    int64_t chr = CSI->getValue();
+    int64_t chr = CSI->getSExtValue();
 
     // Compute the offset
     uint64_t offset = 0;
     bool char_found = false;
     for (uint64_t i = 0; i < len; ++i) {
-      if (ConstantSInt* CI = dyn_cast<ConstantSInt>(CA->getOperand(i))) {
+      if (ConstantInt* CI = dyn_cast<ConstantInt>(CA->getOperand(i))) {
         // Check for the null terminator
         if (CI->isNullValue())
           break; // we found end of string
-        else if (CI->getValue() == chr) {
+        else if (CI->getSExtValue() == chr) {
           char_found = true;
           offset = i;
           break;
@@ -567,7 +599,7 @@ public:
     //    (if c is a constant integer and s is a constant string)
     if (char_found) {
       std::vector<Value*> indices;
-      indices.push_back(ConstantUInt::get(Type::ULongTy,offset));
+      indices.push_back(ConstantInt::get(Type::ULongTy,offset));
       GetElementPtrInst* GEP = new GetElementPtrInst(ci->getOperand(1),indices,
           ci->getOperand(1)->getName()+".strchr",ci);
       ci->replaceAllUsesWith(GEP);
@@ -618,7 +650,8 @@ public:
         LoadInst* load =
           new LoadInst(CastToCStr(s2,*ci), ci->getName()+".load",ci);
         CastInst* cast =
-          new CastInst(load,Type::IntTy,ci->getName()+".int",ci);
+          CastInst::create(Instruction::SExt, load, Type::IntTy, 
+                           ci->getName()+".int", ci);
         ci->replaceAllUsesWith(cast);
         ci->eraseFromParent();
         return true;
@@ -635,7 +668,8 @@ public:
         LoadInst* load =
           new LoadInst(CastToCStr(s1,*ci),ci->getName()+".val",ci);
         CastInst* cast =
-          new CastInst(load,Type::IntTy,ci->getName()+".int",ci);
+          CastInst::create(Instruction::SExt, load, Type::IntTy, 
+                           ci->getName()+".int", ci);
         ci->replaceAllUsesWith(cast);
         ci->eraseFromParent();
         return true;
@@ -647,7 +681,7 @@ public:
       std::string str1 = A1->getAsString();
       std::string str2 = A2->getAsString();
       int result = strcmp(str1.c_str(), str2.c_str());
-      ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,result));
+      ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,result));
       ci->eraseFromParent();
       return true;
     }
@@ -691,7 +725,7 @@ public:
     bool len_arg_is_const = false;
     if (ConstantInt* len_CI = dyn_cast<ConstantInt>(ci->getOperand(3))) {
       len_arg_is_const = true;
-      len_arg = len_CI->getRawValue();
+      len_arg = len_CI->getZExtValue();
       if (len_arg == 0) {
         // strncmp(x,y,0)   -> 0
         ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,0));
@@ -709,7 +743,8 @@ public:
         // strncmp("",x) -> *x
         LoadInst* load = new LoadInst(s1,ci->getName()+".load",ci);
         CastInst* cast =
-          new CastInst(load,Type::IntTy,ci->getName()+".int",ci);
+          CastInst::create(Instruction::SExt, load, Type::IntTy, 
+                           ci->getName()+".int", ci);
         ci->replaceAllUsesWith(cast);
         ci->eraseFromParent();
         return true;
@@ -725,7 +760,8 @@ public:
         // strncmp(x,"") -> *x
         LoadInst* load = new LoadInst(s2,ci->getName()+".val",ci);
         CastInst* cast =
-          new CastInst(load,Type::IntTy,ci->getName()+".int",ci);
+          CastInst::create(Instruction::SExt, load, Type::IntTy, 
+                           ci->getName()+".int", ci);
         ci->replaceAllUsesWith(cast);
         ci->eraseFromParent();
         return true;
@@ -737,7 +773,7 @@ public:
       std::string str1 = A1->getAsString();
       std::string str2 = A2->getAsString();
       int result = strncmp(str1.c_str(), str2.c_str(), len_arg);
-      ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,result));
+      ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,result));
       ci->eraseFromParent();
       return true;
     }
@@ -811,8 +847,8 @@ public:
     std::vector<Value*> vals;
     vals.push_back(dest); // destination
     vals.push_back(src); // source
-    vals.push_back(ConstantUInt::get(SLC.getIntPtrType(),len)); // length
-    vals.push_back(ConstantUInt::get(Type::UIntTy,1)); // alignment
+    vals.push_back(ConstantInt::get(SLC.getIntPtrType(),len)); // length
+    vals.push_back(ConstantInt::get(Type::UIntTy,1)); // alignment
     new CallInst(SLC.get_memcpy(), vals, "", ci);
 
     // Finally, substitute the first operand of the strcat call for the
@@ -859,7 +895,7 @@ struct StrLenOptimization : public LibCallOptimization {
         if (ConstantInt* CI = dyn_cast<ConstantInt>(bop->getOperand(1)))
         {
           // Get the value the strlen result is compared to
-          uint64_t val = CI->getRawValue();
+          uint64_t val = CI->getZExtValue();
 
           // If its compared against length 0 with == or !=
           if (val == 0 &&
@@ -870,7 +906,7 @@ struct StrLenOptimization : public LibCallOptimization {
             // strlen(x) == 0 -> *x == 0
             LoadInst* load = new LoadInst(str,str->getName()+".first",ci);
             BinaryOperator* rbop = BinaryOperator::create(bop->getOpcode(),
-              load, ConstantSInt::get(Type::SByteTy,0),
+              load, ConstantInt::get(Type::SByteTy,0),
               bop->getName()+".strlen", ci);
             bop->replaceAllUsesWith(rbop);
             bop->eraseFromParent();
@@ -887,9 +923,9 @@ struct StrLenOptimization : public LibCallOptimization {
     // strlen("xyz") -> 3 (for example)
     const Type *Ty = SLC.getTargetData()->getIntPtrType();
     if (Ty->isSigned())
-      ci->replaceAllUsesWith(ConstantSInt::get(Ty, len));
+      ci->replaceAllUsesWith(ConstantInt::get(Ty, len));
     else
-      ci->replaceAllUsesWith(ConstantUInt::get(Ty, len));
+      ci->replaceAllUsesWith(ConstantInt::get(Ty, len));
      
     ci->eraseFromParent();
     return true;
@@ -953,7 +989,7 @@ struct memcmpOptimization : public LibCallOptimization {
     // Make sure we have a constant length.
     ConstantInt *LenC = dyn_cast<ConstantInt>(CI->getOperand(3));
     if (!LenC) return false;
-    uint64_t Len = LenC->getRawValue();
+    uint64_t Len = LenC->getZExtValue();
       
     // If the length is zero, this returns 0.
     switch (Len) {
@@ -965,13 +1001,16 @@ struct memcmpOptimization : public LibCallOptimization {
     case 1: {
       // memcmp(S1,S2,1) -> *(ubyte*)S1 - *(ubyte*)S2
       const Type *UCharPtr = PointerType::get(Type::UByteTy);
-      CastInst *Op1Cast = new CastInst(LHS, UCharPtr, LHS->getName(), CI);
-      CastInst *Op2Cast = new CastInst(RHS, UCharPtr, RHS->getName(), CI);
+      CastInst *Op1Cast = CastInst::create(
+          Instruction::BitCast, LHS, UCharPtr, LHS->getName(), CI);
+      CastInst *Op2Cast = CastInst::create(
+          Instruction::BitCast, RHS, UCharPtr, RHS->getName(), CI);
       Value *S1V = new LoadInst(Op1Cast, LHS->getName()+".val", CI);
       Value *S2V = new LoadInst(Op2Cast, RHS->getName()+".val", CI);
       Value *RV = BinaryOperator::createSub(S1V, S2V, CI->getName()+".diff",CI);
       if (RV->getType() != CI->getType())
-        RV = new CastInst(RV, CI->getType(), RV->getName(), CI);
+        RV = CastInst::createIntegerCast(RV, CI->getType(), false, 
+                                         RV->getName(), CI);
       CI->replaceAllUsesWith(RV);
       CI->eraseFromParent();
       return true;
@@ -982,8 +1021,10 @@ struct memcmpOptimization : public LibCallOptimization {
       
         // memcmp(S1,S2,2) -> S1[0]-S2[0] | S1[1]-S2[1] iff only ==/!= 0 matters
         const Type *UCharPtr = PointerType::get(Type::UByteTy);
-        CastInst *Op1Cast = new CastInst(LHS, UCharPtr, LHS->getName(), CI);
-        CastInst *Op2Cast = new CastInst(RHS, UCharPtr, RHS->getName(), CI);
+        CastInst *Op1Cast = CastInst::create(
+            Instruction::BitCast, LHS, UCharPtr, LHS->getName(), CI);
+        CastInst *Op2Cast = CastInst::create(
+            Instruction::BitCast, RHS, UCharPtr, RHS->getName(), CI);
         Value *S1V1 = new LoadInst(Op1Cast, LHS->getName()+".val1", CI);
         Value *S2V1 = new LoadInst(Op2Cast, RHS->getName()+".val1", CI);
         Value *D1 = BinaryOperator::createSub(S1V1, S2V1,
@@ -997,7 +1038,8 @@ struct memcmpOptimization : public LibCallOptimization {
                                               CI->getName()+".d1", CI);
         Value *Or = BinaryOperator::createOr(D1, D2, CI->getName()+".res", CI);
         if (Or->getType() != CI->getType())
-          Or = new CastInst(Or, CI->getType(), Or->getName(), CI);
+          Or = CastInst::createIntegerCast(Or, CI->getType(), false /*ZExt*/, 
+                                           Or->getName(), CI);
         CI->replaceAllUsesWith(Or);
         CI->eraseFromParent();
         return true;
@@ -1043,8 +1085,8 @@ struct LLVMMemCpyMoveOptzn : public LibCallOptimization {
       return false;
 
     // If the length is larger than the alignment, we can't optimize
-    uint64_t len = LEN->getRawValue();
-    uint64_t alignment = ALIGN->getRawValue();
+    uint64_t len = LEN->getZExtValue();
+    uint64_t alignment = ALIGN->getZExtValue();
     if (alignment == 0)
       alignment = 1; // Alignment 0 is identity for alignment 1
     if (len > alignment)
@@ -1069,12 +1111,12 @@ struct LLVMMemCpyMoveOptzn : public LibCallOptimization {
     }
 
     // Cast source and dest to the right sized primitive and then load/store
-    CastInst* SrcCast =
-      new CastInst(src,PointerType::get(castType),src->getName()+".cast",ci);
-    CastInst* DestCast =
-      new CastInst(dest,PointerType::get(castType),dest->getName()+".cast",ci);
+    CastInst* SrcCast = CastInst::create(Instruction::BitCast,
+        src, PointerType::get(castType), src->getName()+".cast", ci);
+    CastInst* DestCast = CastInst::create(Instruction::BitCast,
+        dest, PointerType::get(castType),dest->getName()+".cast", ci);
     LoadInst* LI = new LoadInst(SrcCast,SrcCast->getName()+".val",ci);
-    StoreInst* SI = new StoreInst(LI, DestCast, ci);
+    new StoreInst(LI, DestCast, ci);
     ci->eraseFromParent();
     return true;
   }
@@ -1122,8 +1164,8 @@ struct LLVMMemSetOptimization : public LibCallOptimization {
       return false;
 
     // Extract the length and alignment
-    uint64_t len = LEN->getRawValue();
-    uint64_t alignment = ALIGN->getRawValue();
+    uint64_t len = LEN->getZExtValue();
+    uint64_t alignment = ALIGN->getZExtValue();
 
     // Alignment 0 is identity for alignment 1
     if (alignment == 0)
@@ -1142,7 +1184,7 @@ struct LLVMMemSetOptimization : public LibCallOptimization {
 
     // Make sure we have a constant ubyte to work with so we can extract
     // the value to be filled.
-    ConstantUInt* FILL = dyn_cast<ConstantUInt>(ci->getOperand(2));
+    ConstantInt* FILL = dyn_cast<ConstantInt>(ci->getOperand(2));
     if (!FILL)
       return false;
     if (FILL->getType() != Type::UByteTy)
@@ -1151,7 +1193,7 @@ struct LLVMMemSetOptimization : public LibCallOptimization {
     // memset(s,c,n) -> store s, c (for n=1,2,4,8)
 
     // Extract the fill character
-    uint64_t fill_char = FILL->getValue();
+    uint64_t fill_char = FILL->getZExtValue();
     uint64_t fill_value = fill_char;
 
     // Get the type we will cast to, based on size of memory area to fill, and
@@ -1181,9 +1223,9 @@ struct LLVMMemSetOptimization : public LibCallOptimization {
     }
 
     // Cast dest to the right sized primitive and then load/store
-    CastInst* DestCast =
-      new CastInst(dest,PointerType::get(castType),dest->getName()+".cast",ci);
-    new StoreInst(ConstantUInt::get(castType,fill_value),DestCast, ci);
+    CastInst* DestCast = new BitCastInst(dest, PointerType::get(castType), 
+                                         dest->getName()+".cast", ci);
+    new StoreInst(ConstantInt::get(castType,fill_value),DestCast, ci);
     ci->eraseFromParent();
     return true;
   }
@@ -1243,7 +1285,7 @@ public:
         return true;
       } else if (Op2V == -1.0) {
         // pow(x,-1.0)    -> 1.0/x
-        BinaryOperator* div_inst= BinaryOperator::createDiv(
+        BinaryOperator* div_inst= BinaryOperator::createFDiv(
           ConstantFP::get(Ty,1.0), base, ci->getName()+".pow", ci);
         ci->replaceAllUsesWith(div_inst);
         ci->eraseFromParent();
@@ -1254,10 +1296,94 @@ public:
   }
 } PowOptimizer;
 
+/// This LibCallOptimization will simplify calls to the "printf" library
+/// function. It looks for cases where the result of printf is not used and the
+/// operation can be reduced to something simpler.
+/// @brief Simplify the printf library function.
+struct PrintfOptimization : public LibCallOptimization {
+public:
+  /// @brief Default Constructor
+  PrintfOptimization() : LibCallOptimization("printf",
+      "Number of 'printf' calls simplified") {}
+
+  /// @brief Make sure that the "printf" function has the right prototype
+  virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC){
+    // Just make sure this has at least 1 arguments
+    return (f->arg_size() >= 1);
+  }
+
+  /// @brief Perform the printf optimization.
+  virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC) {
+    // If the call has more than 2 operands, we can't optimize it
+    if (ci->getNumOperands() > 3 || ci->getNumOperands() <= 2)
+      return false;
+
+    // If the result of the printf call is used, none of these optimizations
+    // can be made.
+    if (!ci->use_empty())
+      return false;
+
+    // All the optimizations depend on the length of the first argument and the
+    // fact that it is a constant string array. Check that now
+    uint64_t len = 0;
+    ConstantArray* CA = 0;
+    if (!getConstantStringLength(ci->getOperand(1), len, &CA))
+      return false;
+
+    if (len != 2 && len != 3)
+      return false;
+
+    // The first character has to be a %
+    if (ConstantInt* CI = dyn_cast<ConstantInt>(CA->getOperand(0)))
+      if (CI->getZExtValue() != '%')
+        return false;
+
+    // Get the second character and switch on its value
+    ConstantInt* CI = dyn_cast<ConstantInt>(CA->getOperand(1));
+    switch (CI->getZExtValue()) {
+      case 's':
+      {
+        if (len != 3 ||
+            dyn_cast<ConstantInt>(CA->getOperand(2))->getZExtValue() != '\n')
+          return false;
+
+        // printf("%s\n",str) -> puts(str)
+        Function* puts_func = SLC.get_puts();
+        if (!puts_func)
+          return false;
+        std::vector<Value*> args;
+        args.push_back(CastToCStr(ci->getOperand(2), *ci));
+        new CallInst(puts_func,args,ci->getName(),ci);
+        ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,len));
+        break;
+      }
+      case 'c':
+      {
+        // printf("%c",c) -> putchar(c)
+        if (len != 2)
+          return false;
+
+        Function* putchar_func = SLC.get_putchar();
+        if (!putchar_func)
+          return false;
+        CastInst* cast = CastInst::createSExtOrBitCast(
+            ci->getOperand(2), Type::IntTy, CI->getName()+".int", ci);
+        new CallInst(putchar_func, cast, "", ci);
+        ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy, 1));
+        break;
+      }
+      default:
+        return false;
+    }
+    ci->eraseFromParent();
+    return true;
+  }
+} PrintfOptimizer;
+
 /// This LibCallOptimization will simplify calls to the "fprintf" library
 /// function. It looks for cases where the result of fprintf is not used and the
 /// operation can be reduced to something simpler.
-/// @brief Simplify the pow library function.
+/// @brief Simplify the fprintf library function.
 struct FPrintFOptimization : public LibCallOptimization {
 public:
   /// @brief Default Constructor
@@ -1293,7 +1419,7 @@ public:
       for (unsigned i = 0; i < len; ++i) {
         if (ConstantInt* CI = dyn_cast<ConstantInt>(CA->getOperand(i))) {
           // Check for the null terminator
-          if (CI->getRawValue() == '%')
+          if (CI->getZExtValue() == '%')
             return false; // we found end of string
         } else {
           return false;
@@ -1314,11 +1440,11 @@ public:
 
       std::vector<Value*> args;
       args.push_back(ci->getOperand(2));
-      args.push_back(ConstantUInt::get(SLC.getIntPtrType(),len));
-      args.push_back(ConstantUInt::get(SLC.getIntPtrType(),1));
+      args.push_back(ConstantInt::get(SLC.getIntPtrType(),len));
+      args.push_back(ConstantInt::get(SLC.getIntPtrType(),1));
       args.push_back(ci->getOperand(1));
       new CallInst(fwrite_func,args,ci->getName(),ci);
-      ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,len));
+      ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,len));
       ci->eraseFromParent();
       return true;
     }
@@ -1330,46 +1456,54 @@ public:
 
     // The first character has to be a %
     if (ConstantInt* CI = dyn_cast<ConstantInt>(CA->getOperand(0)))
-      if (CI->getRawValue() != '%')
+      if (CI->getZExtValue() != '%')
         return false;
 
     // Get the second character and switch on its value
     ConstantInt* CI = dyn_cast<ConstantInt>(CA->getOperand(1));
-    switch (CI->getRawValue()) {
+    switch (CI->getZExtValue()) {
       case 's':
       {
         uint64_t len = 0;
         ConstantArray* CA = 0;
-        if (!getConstantStringLength(ci->getOperand(3), len, &CA))
-          return false;
-
-        // fprintf(file,"%s",str) -> fwrite(fmt,strlen(fmt),1,file)
-        const Type* FILEptr_type = ci->getOperand(1)->getType();
-        Function* fwrite_func = SLC.get_fwrite(FILEptr_type);
-        if (!fwrite_func)
-          return false;
-        std::vector<Value*> args;
-        args.push_back(CastToCStr(ci->getOperand(3), *ci));
-        args.push_back(ConstantUInt::get(SLC.getIntPtrType(),len));
-        args.push_back(ConstantUInt::get(SLC.getIntPtrType(),1));
-        args.push_back(ci->getOperand(1));
-        new CallInst(fwrite_func,args,ci->getName(),ci);
-        ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,len));
+        if (getConstantStringLength(ci->getOperand(3), len, &CA)) {
+          // fprintf(file,"%s",str) -> fwrite(str,strlen(str),1,file)
+          const Type* FILEptr_type = ci->getOperand(1)->getType();
+          Function* fwrite_func = SLC.get_fwrite(FILEptr_type);
+          if (!fwrite_func)
+            return false;
+          std::vector<Value*> args;
+          args.push_back(CastToCStr(ci->getOperand(3), *ci));
+          args.push_back(ConstantInt::get(SLC.getIntPtrType(),len));
+          args.push_back(ConstantInt::get(SLC.getIntPtrType(),1));
+          args.push_back(ci->getOperand(1));
+          new CallInst(fwrite_func,args,ci->getName(),ci);
+          ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,len));
+        } else {
+          // fprintf(file,"%s",str) -> fputs(str,file)
+          const Type* FILEptr_type = ci->getOperand(1)->getType();
+          Function* fputs_func = SLC.get_fputs(FILEptr_type);
+          if (!fputs_func)
+            return false;
+          std::vector<Value*> args;
+          args.push_back(CastToCStr(ci->getOperand(3), *ci));
+          args.push_back(ci->getOperand(1));
+          new CallInst(fputs_func,args,ci->getName(),ci);
+          ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,len));
+        }
         break;
       }
       case 'c':
       {
-        ConstantInt* CI = dyn_cast<ConstantInt>(ci->getOperand(3));
-        if (!CI)
-          return false;
-
+        // fprintf(file,"%c",c) -> fputc(c,file)
         const Type* FILEptr_type = ci->getOperand(1)->getType();
         Function* fputc_func = SLC.get_fputc(FILEptr_type);
         if (!fputc_func)
           return false;
-        CastInst* cast = new CastInst(CI,Type::IntTy,CI->getName()+".int",ci);
+        CastInst* cast = CastInst::createSExtOrBitCast(
+            ci->getOperand(3), Type::IntTy, CI->getName()+".int", ci);
         new CallInst(fputc_func,cast,ci->getOperand(1),"",ci);
-        ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,1));
+        ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,1));
         break;
       }
       default:
@@ -1383,7 +1517,7 @@ public:
 /// This LibCallOptimization will simplify calls to the "sprintf" library
 /// function. It looks for cases where the result of sprintf is not used and the
 /// operation can be reduced to something simpler.
-/// @brief Simplify the pow library function.
+/// @brief Simplify the sprintf library function.
 struct SPrintFOptimization : public LibCallOptimization {
 public:
   /// @brief Default Constructor
@@ -1413,7 +1547,7 @@ public:
       if (len == 0) {
         // If the length is 0, we just need to store a null byte
         new StoreInst(ConstantInt::get(Type::SByteTy,0),ci->getOperand(1),ci);
-        ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,0));
+        ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,0));
         ci->eraseFromParent();
         return true;
       }
@@ -1422,7 +1556,7 @@ public:
       for (unsigned i = 0; i < len; ++i) {
         if (ConstantInt* CI = dyn_cast<ConstantInt>(CA->getOperand(i))) {
           // Check for the null terminator
-          if (CI->getRawValue() == '%')
+          if (CI->getZExtValue() == '%')
             return false; // we found a %, can't optimize
         } else {
           return false; // initializer is not constant int, can't optimize
@@ -1439,10 +1573,10 @@ public:
       std::vector<Value*> args;
       args.push_back(ci->getOperand(1));
       args.push_back(ci->getOperand(2));
-      args.push_back(ConstantUInt::get(SLC.getIntPtrType(),len));
-      args.push_back(ConstantUInt::get(Type::UIntTy,1));
+      args.push_back(ConstantInt::get(SLC.getIntPtrType(),len));
+      args.push_back(ConstantInt::get(Type::UIntTy,1));
       new CallInst(memcpy_func,args,"",ci);
-      ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,len));
+      ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,len));
       ci->eraseFromParent();
       return true;
     }
@@ -1454,12 +1588,12 @@ public:
 
     // The first character has to be a %
     if (ConstantInt* CI = dyn_cast<ConstantInt>(CA->getOperand(0)))
-      if (CI->getRawValue() != '%')
+      if (CI->getZExtValue() != '%')
         return false;
 
     // Get the second character and switch on its value
     ConstantInt* CI = dyn_cast<ConstantInt>(CA->getOperand(1));
-    switch (CI->getRawValue()) {
+    switch (CI->getZExtValue()) {
     case 's': {
       // sprintf(dest,"%s",str) -> llvm.memcpy(dest, str, strlen(str)+1, 1)
       Function* strlen_func = SLC.get_strlen();
@@ -1473,18 +1607,20 @@ public:
                                             ConstantInt::get(Len->getType(), 1),
                                               Len->getName()+"1", ci);
       if (Len1->getType() != SLC.getIntPtrType())
-        Len1 = new CastInst(Len1, SLC.getIntPtrType(), Len1->getName(), ci);
+        Len1 = CastInst::createIntegerCast(Len1, SLC.getIntPtrType(), false,
+                                           Len1->getName(), ci);
       std::vector<Value*> args;
       args.push_back(CastToCStr(ci->getOperand(1), *ci));
       args.push_back(CastToCStr(ci->getOperand(3), *ci));
       args.push_back(Len1);
-      args.push_back(ConstantUInt::get(Type::UIntTy,1));
+      args.push_back(ConstantInt::get(Type::UIntTy,1));
       new CallInst(memcpy_func, args, "", ci);
       
       // The strlen result is the unincremented number of bytes in the string.
       if (!ci->use_empty()) {
         if (Len->getType() != ci->getType())
-          Len = new CastInst(Len, ci->getType(), Len->getName(), ci);
+          Len = CastInst::createIntegerCast(Len, ci->getType(), false, 
+                                            Len->getName(), ci);
         ci->replaceAllUsesWith(Len);
       }
       ci->eraseFromParent();
@@ -1492,13 +1628,14 @@ public:
     }
     case 'c': {
       // sprintf(dest,"%c",chr) -> store chr, dest
-      CastInst* cast = new CastInst(ci->getOperand(3),Type::SByteTy,"char",ci);
+      CastInst* cast = CastInst::createTruncOrBitCast(
+          ci->getOperand(3), Type::SByteTy, "char", ci);
       new StoreInst(cast, ci->getOperand(1), ci);
       GetElementPtrInst* gep = new GetElementPtrInst(ci->getOperand(1),
-        ConstantUInt::get(Type::UIntTy,1),ci->getOperand(1)->getName()+".end",
+        ConstantInt::get(Type::UIntTy,1),ci->getOperand(1)->getName()+".end",
         ci);
       new StoreInst(ConstantInt::get(Type::SByteTy,0),gep,ci);
-      ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,1));
+      ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,1));
       ci->eraseFromParent();
       return true;
     }
@@ -1510,7 +1647,7 @@ public:
 /// This LibCallOptimization will simplify calls to the "fputs" library
 /// function. It looks for cases where the result of fputs is not used and the
 /// operation can be reduced to something simpler.
-/// @brief Simplify the pow library function.
+/// @brief Simplify the puts library function.
 struct PutsOptimization : public LibCallOptimization {
 public:
   /// @brief Default Constructor
@@ -1548,8 +1685,8 @@ public:
           return false;
         LoadInst* loadi = new LoadInst(ci->getOperand(1),
           ci->getOperand(1)->getName()+".byte",ci);
-        CastInst* casti = new CastInst(loadi,Type::IntTy,
-          loadi->getName()+".int",ci);
+        CastInst* casti = new SExtInst(loadi, Type::IntTy, 
+                                       loadi->getName()+".int", ci);
         new CallInst(fputc_func,casti,ci->getOperand(2),"",ci);
         break;
       }
@@ -1562,8 +1699,8 @@ public:
           return false;
         std::vector<Value*> parms;
         parms.push_back(ci->getOperand(1));
-        parms.push_back(ConstantUInt::get(SLC.getIntPtrType(),len));
-        parms.push_back(ConstantUInt::get(SLC.getIntPtrType(),1));
+        parms.push_back(ConstantInt::get(SLC.getIntPtrType(),len));
+        parms.push_back(ConstantInt::get(SLC.getIntPtrType(),1));
         parms.push_back(ci->getOperand(2));
         new CallInst(fwrite_func,parms,"",ci);
         break;
@@ -1592,28 +1729,26 @@ public:
   virtual bool OptimizeCall(CallInst *ci, SimplifyLibCalls &SLC) {
     if (ConstantInt* CI = dyn_cast<ConstantInt>(ci->getOperand(1))) {
       // isdigit(c)   -> 0 or 1, if 'c' is constant
-      uint64_t val = CI->getRawValue();
+      uint64_t val = CI->getZExtValue();
       if (val >= '0' && val <='9')
-        ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,1));
+        ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,1));
       else
-        ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,0));
+        ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,0));
       ci->eraseFromParent();
       return true;
     }
 
     // isdigit(c)   -> (unsigned)c - '0' <= 9
-    CastInst* cast =
-      new CastInst(ci->getOperand(1),Type::UIntTy,
-        ci->getOperand(1)->getName()+".uint",ci);
+    CastInst* cast = CastInst::createIntegerCast(ci->getOperand(1),
+        Type::UIntTy, false/*ZExt*/, ci->getOperand(1)->getName()+".uint", ci);
     BinaryOperator* sub_inst = BinaryOperator::createSub(cast,
-        ConstantUInt::get(Type::UIntTy,0x30),
+        ConstantInt::get(Type::UIntTy,0x30),
         ci->getOperand(1)->getName()+".sub",ci);
     SetCondInst* setcond_inst = new SetCondInst(Instruction::SetLE,sub_inst,
-        ConstantUInt::get(Type::UIntTy,9),
+        ConstantInt::get(Type::UIntTy,9),
         ci->getOperand(1)->getName()+".cmp",ci);
-    CastInst* c2 =
-      new CastInst(setcond_inst,Type::IntTy,
-        ci->getOperand(1)->getName()+".isdigit",ci);
+    CastInst* c2 = new ZExtInst(setcond_inst, Type::IntTy, 
+        ci->getOperand(1)->getName()+".isdigit", ci);
     ci->replaceAllUsesWith(c2);
     ci->eraseFromParent();
     return true;
@@ -1635,12 +1770,13 @@ public:
     // isascii(c)   -> (unsigned)c < 128
     Value *V = CI->getOperand(1);
     if (V->getType()->isSigned())
-      V = new CastInst(V, V->getType()->getUnsignedVersion(), V->getName(), CI);
-    Value *Cmp = BinaryOperator::createSetLT(V, ConstantUInt::get(V->getType(),
+      V = new BitCastInst(V, V->getType()->getUnsignedVersion(), V->getName(), 
+                          CI);
+    Value *Cmp = BinaryOperator::createSetLT(V, ConstantInt::get(V->getType(),
                                                                   128),
                                              V->getName()+".isascii", CI);
     if (Cmp->getType() != CI->getType())
-      Cmp = new CastInst(Cmp, CI->getType(), Cmp->getName(), CI);
+      Cmp = new BitCastInst(Cmp, CI->getType(), Cmp->getName(), CI);
     CI->replaceAllUsesWith(Cmp);
     CI->eraseFromParent();
     return true;
@@ -1704,7 +1840,7 @@ public:
       // ffs(cnst)  -> bit#
       // ffsl(cnst) -> bit#
       // ffsll(cnst) -> bit#
-      uint64_t val = CI->getRawValue();
+      uint64_t val = CI->getZExtValue();
       int result = 0;
       if (val) {
         ++result;
@@ -1713,7 +1849,7 @@ public:
           val >>= 1;
         }
       }
-      TheCall->replaceAllUsesWith(ConstantSInt::get(Type::IntTy, result));
+      TheCall->replaceAllUsesWith(ConstantInt::get(Type::IntTy, result));
       TheCall->eraseFromParent();
       return true;
     }
@@ -1734,10 +1870,12 @@ public:
     
     Function *F = SLC.getModule()->getOrInsertFunction(CTTZName, ArgType,
                                                        ArgType, NULL);
-    Value *V = new CastInst(TheCall->getOperand(1), ArgType, "tmp", TheCall);
+    Value *V = CastInst::createIntegerCast(TheCall->getOperand(1), ArgType, 
+                                           false/*ZExt*/, "tmp", TheCall);
     Value *V2 = new CallInst(F, V, "tmp", TheCall);
-    V2 = new CastInst(V2, Type::IntTy, "tmp", TheCall);
-    V2 = BinaryOperator::createAdd(V2, ConstantSInt::get(Type::IntTy, 1),
+    V2 = CastInst::createIntegerCast(V2, Type::IntTy, false/*ZExt*/, 
+                                     "tmp", TheCall);
+    V2 = BinaryOperator::createAdd(V2, ConstantInt::get(Type::IntTy, 1),
                                    "tmp", TheCall);
     Value *Cond = 
       BinaryOperator::createSetEQ(V, Constant::getNullValue(V->getType()),
@@ -1796,7 +1934,7 @@ struct UnaryDoubleFPOptimizer : public LibCallOptimization {
       if (Cast->getOperand(0)->getType() == Type::FloatTy) {
         Value *New = new CallInst((SLC.*FP)(), Cast->getOperand(0),
                                   CI->getName(), CI);
-        New = new CastInst(New, Type::DoubleTy, CI->getName(), CI);
+        New = new FPExtInst(New, Type::DoubleTy, CI->getName(), CI);
         CI->replaceAllUsesWith(New);
         CI->eraseFromParent();
         if (Cast->use_empty())
@@ -1924,7 +2062,7 @@ bool getConstantStringLength(Value *V, uint64_t &len, ConstantArray **CA) {
   // value. We'll need this later for indexing the ConstantArray.
   uint64_t start_idx = 0;
   if (ConstantInt* CI = dyn_cast<ConstantInt>(GEP->getOperand(2)))
-    start_idx = CI->getRawValue();
+    start_idx = CI->getZExtValue();
   else
     return false;
 
@@ -1939,7 +2077,7 @@ bool getConstantStringLength(Value *V, uint64_t &len, ConstantArray **CA) {
   Constant* INTLZR = GV->getInitializer();
 
   // Handle the ConstantAggregateZero case
-  if (ConstantAggregateZero *CAZ = dyn_cast<ConstantAggregateZero>(INTLZR)) {
+  if (isa<ConstantAggregateZero>(INTLZR)) {
     // This is a degenerate case. The initializer is constant zero so the
     // length of the string must be zero.
     len = 0;
@@ -1979,9 +2117,11 @@ bool getConstantStringLength(Value *V, uint64_t &len, ConstantArray **CA) {
 /// inserting the cast before IP, and return the cast.
 /// @brief Cast a value to a "C" string.
 Value *CastToCStr(Value *V, Instruction &IP) {
+  assert(isa<PointerType>(V->getType()) && 
+         "Can't cast non-pointer type to C string type");
   const Type *SBPTy = PointerType::get(Type::SByteTy);
   if (V->getType() != SBPTy)
-    return new CastInst(V, SBPTy, V->getName(), &IP);
+    return new BitCastInst(V, SBPTy, V->getName(), &IP);
   return V;
 }