[llvm-commits] CVS: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp

Chris Lattner sabre at nondot.org
Fri Apr 6 18:18:54 PDT 2007



Changes in directory llvm/lib/Transforms/IPO:

SimplifyLibCalls.cpp updated: 1.103 -> 1.104
---
Log message:

fix a miscompilation in printf optimizer.


---
Diffs of the changes:  (+36 -38)

 SimplifyLibCalls.cpp |   74 ++++++++++++++++++++++++---------------------------
 1 files changed, 36 insertions(+), 38 deletions(-)


Index: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp
diff -u llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.103 llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.104
--- llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.103	Fri Apr  6 20:03:46 2007
+++ llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp	Fri Apr  6 20:18:36 2007
@@ -1189,67 +1189,65 @@
       "Number of 'printf' calls simplified") {}
 
   /// @brief Make sure that the "printf" function has the right prototype
-  virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC){
+  virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
     // Just make sure this has at least 1 arguments
-    return (f->arg_size() >= 1);
+    return F->arg_size() >= 1;
   }
 
   /// @brief Perform the printf optimization.
-  virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC) {
+  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)
+    if (CI->getNumOperands() != 3)
       return false;
 
     // If the result of the printf call is used, none of these optimizations
     // can be made.
-    if (!ci->use_empty())
+    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, StartIdx;
-    ConstantArray* CA = 0;
-    if (!GetConstantStringInfo(ci->getOperand(1), CA, len, StartIdx))
+    uint64_t FormatLen, FormatIdx;
+    ConstantArray *CA = 0;
+    if (!GetConstantStringInfo(CI->getOperand(1), CA, FormatLen, FormatIdx))
       return false;
 
-    if (len != 2 && len != 3)
+    if (FormatLen != 2 && FormatLen != 3)
       return false;
 
     // The first character has to be a %
-    if (ConstantInt* CI = dyn_cast<ConstantInt>(CA->getOperand(0)))
-      if (CI->getZExtValue() != '%')
-        return false;
+    if (cast<ConstantInt>(CA->getOperand(FormatIdx))->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)
-        std::vector<Value*> args;
-        new CallInst(SLC.get_puts(), CastToCStr(ci->getOperand(2), *ci),
-                     ci->getName(), ci);
-        return ReplaceCallWith(ci, ConstantInt::get(Type::Int32Ty, len));
-      }
-      case 'c':
-      {
-        // printf("%c",c) -> putchar(c)
-        if (len != 2)
-          return false;
+    switch (cast<ConstantInt>(CA->getOperand(FormatIdx+1))->getZExtValue()) {
+    default:  return false;
+    case 's': {
+      if (FormatLen != 3 ||
+          cast<ConstantInt>(CA->getOperand(FormatIdx+2))->getZExtValue() !='\n')
+        return false;
 
-        CastInst *Char = CastInst::createSExtOrBitCast(
-            ci->getOperand(2), Type::Int32Ty, CI->getName()+".int", ci);
-        new CallInst(SLC.get_putchar(), Char, "", ci);
-        return ReplaceCallWith(ci, ConstantInt::get(Type::Int32Ty, 1));
-      }
-      default:
+      // printf("%s\n",str) -> puts(str)
+      new CallInst(SLC.get_puts(), CastToCStr(CI->getOperand(2), *CI),
+                   CI->getName(), CI);
+      return ReplaceCallWith(CI, 0);
+    }
+    case 'c': {
+      // printf("%c",c) -> putchar(c)
+      if (FormatLen != 2)
+        return false;
+      
+      Value *V = CI->getOperand(2);
+      if (!isa<IntegerType>(V->getType()) ||
+          cast<IntegerType>(V->getType())->getBitWidth() < 32)
         return false;
+
+      V = CastInst::createSExtOrBitCast(V, Type::Int32Ty, CI->getName()+".int",
+                                        CI);
+      new CallInst(SLC.get_putchar(), V, "", CI);
+      return ReplaceCallWith(CI, 0);
+    }
     }
-    return false;
   }
 } PrintfOptimizer;
 






More information about the llvm-commits mailing list