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; _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits