diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp index 5b22b23b6b0..43c6f6dda25 100644 --- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp +++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp @@ -1345,6 +1345,34 @@ struct FPrintFOpt : public LibCallOptimization { } }; +//===---------------------------------------===// +// 'puts' Optimizations + +struct PutsOpt : public LibCallOptimization { + virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { + // Require one fixed pointer argument and an integer/void result. + const FunctionType *FT = Callee->getFunctionType(); + if (FT->getNumParams() < 1 || !FT->getParamType(0)->isPointerTy() || + !(FT->getReturnType()->isIntegerTy() || + FT->getReturnType()->isVoidTy())) + return 0; + + // Check for a constant string. + std::string Str; + if (!GetConstantStringInfo(CI->getArgOperand(0), Str)) + return 0; + + if (Str.empty()) { + // puts("") -> putchar('\n') + Value *Res = EmitPutChar(B.getInt32('\n'), B, TD); + if (CI->use_empty()) return CI; + return B.CreateIntCast(Res, CI->getType(), true); + } + + return 0; + } +}; + } // end anonymous namespace. //===----------------------------------------------------------------------===// @@ -1370,6 +1398,7 @@ namespace { // Formatting and IO Optimizations SPrintFOpt SPrintF; PrintFOpt PrintF; FWriteOpt FWrite; FPutsOpt FPuts; FPrintFOpt FPrintF; + PutsOpt Puts; bool Modified; // This is only used by doInitialization. public: @@ -1484,6 +1513,7 @@ void SimplifyLibCalls::InitOptimizations() { Optimizations["fwrite"] = &FWrite; Optimizations["fputs"] = &FPuts; Optimizations["fprintf"] = &FPrintF; + Optimizations["puts"] = &Puts; } @@ -2298,9 +2328,6 @@ bool SimplifyLibCalls::doInitialization(Module &M) { // * pow(sqrt(x),y) -> pow(x,y*0.5) // * pow(pow(x,y),z)-> pow(x,y*z) // -// puts: -// * puts("") -> putchar('\n') -// // round, roundf, roundl: // * round(cnst) -> cnst' // diff --git a/test/Transforms/SimplifyLibCalls/Puts.ll b/test/Transforms/SimplifyLibCalls/Puts.ll new file mode 100644 index 00000000000..48431434cc6 --- /dev/null +++ b/test/Transforms/SimplifyLibCalls/Puts.ll @@ -0,0 +1,15 @@ +; Test that the PutsOptimizer works correctly +; RUN: opt < %s -simplify-libcalls -S | FileCheck %s + +target datalayout = "-p:64:64:64" + +@.str = private constant [1 x i8] zeroinitializer + +declare i32 @puts(i8*) + +define void @foo() { +entry: +; CHECK: call i32 @putchar(i32 10) + %call = call i32 @puts(i8* getelementptr inbounds ([1 x i8]* @.str, i32 0, i32 0)) + ret void +}