1243789Sdim//===------ SimplifyLibCalls.cpp - Library calls simplifier ---------------===//
2243789Sdim//
3243789Sdim//                     The LLVM Compiler Infrastructure
4243789Sdim//
5243789Sdim// This file is distributed under the University of Illinois Open Source
6243789Sdim// License. See LICENSE.TXT for details.
7243789Sdim//
8243789Sdim//===----------------------------------------------------------------------===//
9243789Sdim//
10243789Sdim// This is a utility pass used for testing the InstructionSimplify analysis.
11243789Sdim// The analysis is applied to every instruction, and if it simplifies then the
12243789Sdim// instruction is replaced by the simplification.  If you are looking for a pass
13243789Sdim// that performs serious instruction folding, use the instcombine pass instead.
14243789Sdim//
15243789Sdim//===----------------------------------------------------------------------===//
16243789Sdim
17243789Sdim#include "llvm/Transforms/Utils/SimplifyLibCalls.h"
18249423Sdim#include "llvm/ADT/SmallString.h"
19243789Sdim#include "llvm/ADT/StringMap.h"
20263508Sdim#include "llvm/ADT/Triple.h"
21243789Sdim#include "llvm/Analysis/ValueTracking.h"
22249423Sdim#include "llvm/IR/DataLayout.h"
23249423Sdim#include "llvm/IR/Function.h"
24249423Sdim#include "llvm/IR/IRBuilder.h"
25249423Sdim#include "llvm/IR/IntrinsicInst.h"
26249423Sdim#include "llvm/IR/Intrinsics.h"
27249423Sdim#include "llvm/IR/LLVMContext.h"
28249423Sdim#include "llvm/IR/Module.h"
29249423Sdim#include "llvm/Support/Allocator.h"
30263508Sdim#include "llvm/Support/CommandLine.h"
31243789Sdim#include "llvm/Target/TargetLibraryInfo.h"
32243789Sdim#include "llvm/Transforms/Utils/BuildLibCalls.h"
33243789Sdim
34243789Sdimusing namespace llvm;
35243789Sdim
36263508Sdimstatic cl::opt<bool>
37263508SdimColdErrorCalls("error-reporting-is-cold",  cl::init(true),
38263508Sdim  cl::Hidden, cl::desc("Treat error-reporting calls as cold"));
39263508Sdim
40243789Sdim/// This class is the abstract base class for the set of optimizations that
41243789Sdim/// corresponds to one library call.
42243789Sdimnamespace {
43243789Sdimclass LibCallOptimization {
44243789Sdimprotected:
45243789Sdim  Function *Caller;
46243789Sdim  const DataLayout *TD;
47243789Sdim  const TargetLibraryInfo *TLI;
48243789Sdim  const LibCallSimplifier *LCS;
49243789Sdim  LLVMContext* Context;
50243789Sdimpublic:
51243789Sdim  LibCallOptimization() { }
52243789Sdim  virtual ~LibCallOptimization() {}
53243789Sdim
54243789Sdim  /// callOptimizer - This pure virtual method is implemented by base classes to
55243789Sdim  /// do various optimizations.  If this returns null then no transformation was
56243789Sdim  /// performed.  If it returns CI, then it transformed the call and CI is to be
57243789Sdim  /// deleted.  If it returns something else, replace CI with the new value and
58243789Sdim  /// delete CI.
59243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B)
60243789Sdim    =0;
61243789Sdim
62249423Sdim  /// ignoreCallingConv - Returns false if this transformation could possibly
63249423Sdim  /// change the calling convention.
64249423Sdim  virtual bool ignoreCallingConv() { return false; }
65249423Sdim
66243789Sdim  Value *optimizeCall(CallInst *CI, const DataLayout *TD,
67243789Sdim                      const TargetLibraryInfo *TLI,
68243789Sdim                      const LibCallSimplifier *LCS, IRBuilder<> &B) {
69243789Sdim    Caller = CI->getParent()->getParent();
70243789Sdim    this->TD = TD;
71243789Sdim    this->TLI = TLI;
72243789Sdim    this->LCS = LCS;
73243789Sdim    if (CI->getCalledFunction())
74243789Sdim      Context = &CI->getCalledFunction()->getContext();
75243789Sdim
76243789Sdim    // We never change the calling convention.
77249423Sdim    if (!ignoreCallingConv() && CI->getCallingConv() != llvm::CallingConv::C)
78243789Sdim      return NULL;
79243789Sdim
80243789Sdim    return callOptimizer(CI->getCalledFunction(), CI, B);
81243789Sdim  }
82243789Sdim};
83243789Sdim
84243789Sdim//===----------------------------------------------------------------------===//
85243789Sdim// Helper Functions
86243789Sdim//===----------------------------------------------------------------------===//
87243789Sdim
88243789Sdim/// isOnlyUsedInZeroEqualityComparison - Return true if it only matters that the
89243789Sdim/// value is equal or not-equal to zero.
90243789Sdimstatic bool isOnlyUsedInZeroEqualityComparison(Value *V) {
91243789Sdim  for (Value::use_iterator UI = V->use_begin(), E = V->use_end();
92243789Sdim       UI != E; ++UI) {
93243789Sdim    if (ICmpInst *IC = dyn_cast<ICmpInst>(*UI))
94243789Sdim      if (IC->isEquality())
95243789Sdim        if (Constant *C = dyn_cast<Constant>(IC->getOperand(1)))
96243789Sdim          if (C->isNullValue())
97243789Sdim            continue;
98243789Sdim    // Unknown instruction.
99243789Sdim    return false;
100243789Sdim  }
101243789Sdim  return true;
102243789Sdim}
103243789Sdim
104243789Sdim/// isOnlyUsedInEqualityComparison - Return true if it is only used in equality
105243789Sdim/// comparisons with With.
106243789Sdimstatic bool isOnlyUsedInEqualityComparison(Value *V, Value *With) {
107243789Sdim  for (Value::use_iterator UI = V->use_begin(), E = V->use_end();
108243789Sdim       UI != E; ++UI) {
109243789Sdim    if (ICmpInst *IC = dyn_cast<ICmpInst>(*UI))
110243789Sdim      if (IC->isEquality() && IC->getOperand(1) == With)
111243789Sdim        continue;
112243789Sdim    // Unknown instruction.
113243789Sdim    return false;
114243789Sdim  }
115243789Sdim  return true;
116243789Sdim}
117243789Sdim
118249423Sdimstatic bool callHasFloatingPointArgument(const CallInst *CI) {
119249423Sdim  for (CallInst::const_op_iterator it = CI->op_begin(), e = CI->op_end();
120249423Sdim       it != e; ++it) {
121249423Sdim    if ((*it)->getType()->isFloatingPointTy())
122249423Sdim      return true;
123249423Sdim  }
124249423Sdim  return false;
125249423Sdim}
126249423Sdim
127263508Sdim/// \brief Check whether the overloaded unary floating point function
128263508Sdim/// corresponing to \a Ty is available.
129263508Sdimstatic bool hasUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty,
130263508Sdim                            LibFunc::Func DoubleFn, LibFunc::Func FloatFn,
131263508Sdim                            LibFunc::Func LongDoubleFn) {
132263508Sdim  switch (Ty->getTypeID()) {
133263508Sdim  case Type::FloatTyID:
134263508Sdim    return TLI->has(FloatFn);
135263508Sdim  case Type::DoubleTyID:
136263508Sdim    return TLI->has(DoubleFn);
137263508Sdim  default:
138263508Sdim    return TLI->has(LongDoubleFn);
139263508Sdim  }
140263508Sdim}
141263508Sdim
142243789Sdim//===----------------------------------------------------------------------===//
143243789Sdim// Fortified Library Call Optimizations
144243789Sdim//===----------------------------------------------------------------------===//
145243789Sdim
146243789Sdimstruct FortifiedLibCallOptimization : public LibCallOptimization {
147243789Sdimprotected:
148243789Sdim  virtual bool isFoldable(unsigned SizeCIOp, unsigned SizeArgOp,
149243789Sdim			  bool isString) const = 0;
150243789Sdim};
151243789Sdim
152243789Sdimstruct InstFortifiedLibCallOptimization : public FortifiedLibCallOptimization {
153243789Sdim  CallInst *CI;
154243789Sdim
155243789Sdim  bool isFoldable(unsigned SizeCIOp, unsigned SizeArgOp, bool isString) const {
156243789Sdim    if (CI->getArgOperand(SizeCIOp) == CI->getArgOperand(SizeArgOp))
157243789Sdim      return true;
158243789Sdim    if (ConstantInt *SizeCI =
159243789Sdim                           dyn_cast<ConstantInt>(CI->getArgOperand(SizeCIOp))) {
160243789Sdim      if (SizeCI->isAllOnesValue())
161243789Sdim        return true;
162243789Sdim      if (isString) {
163243789Sdim        uint64_t Len = GetStringLength(CI->getArgOperand(SizeArgOp));
164243789Sdim        // If the length is 0 we don't know how long it is and so we can't
165243789Sdim        // remove the check.
166243789Sdim        if (Len == 0) return false;
167243789Sdim        return SizeCI->getZExtValue() >= Len;
168243789Sdim      }
169243789Sdim      if (ConstantInt *Arg = dyn_cast<ConstantInt>(
170243789Sdim                                                  CI->getArgOperand(SizeArgOp)))
171243789Sdim        return SizeCI->getZExtValue() >= Arg->getZExtValue();
172243789Sdim    }
173243789Sdim    return false;
174243789Sdim  }
175243789Sdim};
176243789Sdim
177243789Sdimstruct MemCpyChkOpt : public InstFortifiedLibCallOptimization {
178243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
179243789Sdim    this->CI = CI;
180243789Sdim    FunctionType *FT = Callee->getFunctionType();
181243789Sdim    LLVMContext &Context = CI->getParent()->getContext();
182243789Sdim
183243789Sdim    // Check if this has the right signature.
184243789Sdim    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
185243789Sdim        !FT->getParamType(0)->isPointerTy() ||
186243789Sdim        !FT->getParamType(1)->isPointerTy() ||
187243789Sdim        FT->getParamType(2) != TD->getIntPtrType(Context) ||
188243789Sdim        FT->getParamType(3) != TD->getIntPtrType(Context))
189243789Sdim      return 0;
190243789Sdim
191243789Sdim    if (isFoldable(3, 2, false)) {
192243789Sdim      B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
193243789Sdim                     CI->getArgOperand(2), 1);
194243789Sdim      return CI->getArgOperand(0);
195243789Sdim    }
196243789Sdim    return 0;
197243789Sdim  }
198243789Sdim};
199243789Sdim
200243789Sdimstruct MemMoveChkOpt : public InstFortifiedLibCallOptimization {
201243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
202243789Sdim    this->CI = CI;
203243789Sdim    FunctionType *FT = Callee->getFunctionType();
204243789Sdim    LLVMContext &Context = CI->getParent()->getContext();
205243789Sdim
206243789Sdim    // Check if this has the right signature.
207243789Sdim    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
208243789Sdim        !FT->getParamType(0)->isPointerTy() ||
209243789Sdim        !FT->getParamType(1)->isPointerTy() ||
210243789Sdim        FT->getParamType(2) != TD->getIntPtrType(Context) ||
211243789Sdim        FT->getParamType(3) != TD->getIntPtrType(Context))
212243789Sdim      return 0;
213243789Sdim
214243789Sdim    if (isFoldable(3, 2, false)) {
215243789Sdim      B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1),
216243789Sdim                      CI->getArgOperand(2), 1);
217243789Sdim      return CI->getArgOperand(0);
218243789Sdim    }
219243789Sdim    return 0;
220243789Sdim  }
221243789Sdim};
222243789Sdim
223243789Sdimstruct MemSetChkOpt : public InstFortifiedLibCallOptimization {
224243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
225243789Sdim    this->CI = CI;
226243789Sdim    FunctionType *FT = Callee->getFunctionType();
227243789Sdim    LLVMContext &Context = CI->getParent()->getContext();
228243789Sdim
229243789Sdim    // Check if this has the right signature.
230243789Sdim    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
231243789Sdim        !FT->getParamType(0)->isPointerTy() ||
232243789Sdim        !FT->getParamType(1)->isIntegerTy() ||
233243789Sdim        FT->getParamType(2) != TD->getIntPtrType(Context) ||
234243789Sdim        FT->getParamType(3) != TD->getIntPtrType(Context))
235243789Sdim      return 0;
236243789Sdim
237243789Sdim    if (isFoldable(3, 2, false)) {
238243789Sdim      Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(),
239243789Sdim                                   false);
240243789Sdim      B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1);
241243789Sdim      return CI->getArgOperand(0);
242243789Sdim    }
243243789Sdim    return 0;
244243789Sdim  }
245243789Sdim};
246243789Sdim
247243789Sdimstruct StrCpyChkOpt : public InstFortifiedLibCallOptimization {
248243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
249243789Sdim    this->CI = CI;
250243789Sdim    StringRef Name = Callee->getName();
251243789Sdim    FunctionType *FT = Callee->getFunctionType();
252243789Sdim    LLVMContext &Context = CI->getParent()->getContext();
253243789Sdim
254243789Sdim    // Check if this has the right signature.
255243789Sdim    if (FT->getNumParams() != 3 ||
256243789Sdim        FT->getReturnType() != FT->getParamType(0) ||
257243789Sdim        FT->getParamType(0) != FT->getParamType(1) ||
258243789Sdim        FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
259243789Sdim        FT->getParamType(2) != TD->getIntPtrType(Context))
260243789Sdim      return 0;
261243789Sdim
262243789Sdim    Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1);
263243789Sdim    if (Dst == Src)      // __strcpy_chk(x,x)  -> x
264243789Sdim      return Src;
265243789Sdim
266243789Sdim    // If a) we don't have any length information, or b) we know this will
267243789Sdim    // fit then just lower to a plain strcpy. Otherwise we'll keep our
268243789Sdim    // strcpy_chk call which may fail at runtime if the size is too long.
269243789Sdim    // TODO: It might be nice to get a maximum length out of the possible
270243789Sdim    // string lengths for varying.
271243789Sdim    if (isFoldable(2, 1, true)) {
272243789Sdim      Value *Ret = EmitStrCpy(Dst, Src, B, TD, TLI, Name.substr(2, 6));
273243789Sdim      return Ret;
274243789Sdim    } else {
275243789Sdim      // Maybe we can stil fold __strcpy_chk to __memcpy_chk.
276243789Sdim      uint64_t Len = GetStringLength(Src);
277243789Sdim      if (Len == 0) return 0;
278243789Sdim
279243789Sdim      // This optimization require DataLayout.
280243789Sdim      if (!TD) return 0;
281243789Sdim
282243789Sdim      Value *Ret =
283243789Sdim	EmitMemCpyChk(Dst, Src,
284243789Sdim                      ConstantInt::get(TD->getIntPtrType(Context), Len),
285243789Sdim                      CI->getArgOperand(2), B, TD, TLI);
286243789Sdim      return Ret;
287243789Sdim    }
288243789Sdim    return 0;
289243789Sdim  }
290243789Sdim};
291243789Sdim
292243789Sdimstruct StpCpyChkOpt : public InstFortifiedLibCallOptimization {
293243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
294243789Sdim    this->CI = CI;
295243789Sdim    StringRef Name = Callee->getName();
296243789Sdim    FunctionType *FT = Callee->getFunctionType();
297243789Sdim    LLVMContext &Context = CI->getParent()->getContext();
298243789Sdim
299243789Sdim    // Check if this has the right signature.
300243789Sdim    if (FT->getNumParams() != 3 ||
301243789Sdim        FT->getReturnType() != FT->getParamType(0) ||
302243789Sdim        FT->getParamType(0) != FT->getParamType(1) ||
303243789Sdim        FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
304243789Sdim        FT->getParamType(2) != TD->getIntPtrType(FT->getParamType(0)))
305243789Sdim      return 0;
306243789Sdim
307243789Sdim    Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1);
308243789Sdim    if (Dst == Src) {  // stpcpy(x,x)  -> x+strlen(x)
309243789Sdim      Value *StrLen = EmitStrLen(Src, B, TD, TLI);
310243789Sdim      return StrLen ? B.CreateInBoundsGEP(Dst, StrLen) : 0;
311243789Sdim    }
312243789Sdim
313243789Sdim    // If a) we don't have any length information, or b) we know this will
314243789Sdim    // fit then just lower to a plain stpcpy. Otherwise we'll keep our
315243789Sdim    // stpcpy_chk call which may fail at runtime if the size is too long.
316243789Sdim    // TODO: It might be nice to get a maximum length out of the possible
317243789Sdim    // string lengths for varying.
318243789Sdim    if (isFoldable(2, 1, true)) {
319243789Sdim      Value *Ret = EmitStrCpy(Dst, Src, B, TD, TLI, Name.substr(2, 6));
320243789Sdim      return Ret;
321243789Sdim    } else {
322243789Sdim      // Maybe we can stil fold __stpcpy_chk to __memcpy_chk.
323243789Sdim      uint64_t Len = GetStringLength(Src);
324243789Sdim      if (Len == 0) return 0;
325243789Sdim
326243789Sdim      // This optimization require DataLayout.
327243789Sdim      if (!TD) return 0;
328243789Sdim
329243789Sdim      Type *PT = FT->getParamType(0);
330243789Sdim      Value *LenV = ConstantInt::get(TD->getIntPtrType(PT), Len);
331243789Sdim      Value *DstEnd = B.CreateGEP(Dst,
332243789Sdim                                  ConstantInt::get(TD->getIntPtrType(PT),
333243789Sdim                                                   Len - 1));
334243789Sdim      if (!EmitMemCpyChk(Dst, Src, LenV, CI->getArgOperand(2), B, TD, TLI))
335243789Sdim        return 0;
336243789Sdim      return DstEnd;
337243789Sdim    }
338243789Sdim    return 0;
339243789Sdim  }
340243789Sdim};
341243789Sdim
342243789Sdimstruct StrNCpyChkOpt : public InstFortifiedLibCallOptimization {
343243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
344243789Sdim    this->CI = CI;
345243789Sdim    StringRef Name = Callee->getName();
346243789Sdim    FunctionType *FT = Callee->getFunctionType();
347243789Sdim    LLVMContext &Context = CI->getParent()->getContext();
348243789Sdim
349243789Sdim    // Check if this has the right signature.
350243789Sdim    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
351243789Sdim        FT->getParamType(0) != FT->getParamType(1) ||
352243789Sdim        FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
353243789Sdim        !FT->getParamType(2)->isIntegerTy() ||
354243789Sdim        FT->getParamType(3) != TD->getIntPtrType(Context))
355243789Sdim      return 0;
356243789Sdim
357243789Sdim    if (isFoldable(3, 2, false)) {
358243789Sdim      Value *Ret = EmitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1),
359243789Sdim                               CI->getArgOperand(2), B, TD, TLI,
360243789Sdim                               Name.substr(2, 7));
361243789Sdim      return Ret;
362243789Sdim    }
363243789Sdim    return 0;
364243789Sdim  }
365243789Sdim};
366243789Sdim
367243789Sdim//===----------------------------------------------------------------------===//
368243789Sdim// String and Memory Library Call Optimizations
369243789Sdim//===----------------------------------------------------------------------===//
370243789Sdim
371243789Sdimstruct StrCatOpt : public LibCallOptimization {
372243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
373243789Sdim    // Verify the "strcat" function prototype.
374243789Sdim    FunctionType *FT = Callee->getFunctionType();
375243789Sdim    if (FT->getNumParams() != 2 ||
376243789Sdim        FT->getReturnType() != B.getInt8PtrTy() ||
377243789Sdim        FT->getParamType(0) != FT->getReturnType() ||
378243789Sdim        FT->getParamType(1) != FT->getReturnType())
379243789Sdim      return 0;
380243789Sdim
381243789Sdim    // Extract some information from the instruction
382243789Sdim    Value *Dst = CI->getArgOperand(0);
383243789Sdim    Value *Src = CI->getArgOperand(1);
384243789Sdim
385243789Sdim    // See if we can get the length of the input string.
386243789Sdim    uint64_t Len = GetStringLength(Src);
387243789Sdim    if (Len == 0) return 0;
388243789Sdim    --Len;  // Unbias length.
389243789Sdim
390243789Sdim    // Handle the simple, do-nothing case: strcat(x, "") -> x
391243789Sdim    if (Len == 0)
392243789Sdim      return Dst;
393243789Sdim
394243789Sdim    // These optimizations require DataLayout.
395243789Sdim    if (!TD) return 0;
396243789Sdim
397243789Sdim    return emitStrLenMemCpy(Src, Dst, Len, B);
398243789Sdim  }
399243789Sdim
400243789Sdim  Value *emitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len,
401243789Sdim                          IRBuilder<> &B) {
402243789Sdim    // We need to find the end of the destination string.  That's where the
403243789Sdim    // memory is to be moved to. We just generate a call to strlen.
404243789Sdim    Value *DstLen = EmitStrLen(Dst, B, TD, TLI);
405243789Sdim    if (!DstLen)
406243789Sdim      return 0;
407243789Sdim
408243789Sdim    // Now that we have the destination's length, we must index into the
409243789Sdim    // destination's pointer to get the actual memcpy destination (end of
410243789Sdim    // the string .. we're concatenating).
411243789Sdim    Value *CpyDst = B.CreateGEP(Dst, DstLen, "endptr");
412243789Sdim
413243789Sdim    // We have enough information to now generate the memcpy call to do the
414243789Sdim    // concatenation for us.  Make a memcpy to copy the nul byte with align = 1.
415243789Sdim    B.CreateMemCpy(CpyDst, Src,
416243789Sdim                   ConstantInt::get(TD->getIntPtrType(*Context), Len + 1), 1);
417243789Sdim    return Dst;
418243789Sdim  }
419243789Sdim};
420243789Sdim
421243789Sdimstruct StrNCatOpt : public StrCatOpt {
422243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
423243789Sdim    // Verify the "strncat" function prototype.
424243789Sdim    FunctionType *FT = Callee->getFunctionType();
425243789Sdim    if (FT->getNumParams() != 3 ||
426243789Sdim        FT->getReturnType() != B.getInt8PtrTy() ||
427243789Sdim        FT->getParamType(0) != FT->getReturnType() ||
428243789Sdim        FT->getParamType(1) != FT->getReturnType() ||
429243789Sdim        !FT->getParamType(2)->isIntegerTy())
430243789Sdim      return 0;
431243789Sdim
432243789Sdim    // Extract some information from the instruction
433243789Sdim    Value *Dst = CI->getArgOperand(0);
434243789Sdim    Value *Src = CI->getArgOperand(1);
435243789Sdim    uint64_t Len;
436243789Sdim
437243789Sdim    // We don't do anything if length is not constant
438243789Sdim    if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2)))
439243789Sdim      Len = LengthArg->getZExtValue();
440243789Sdim    else
441243789Sdim      return 0;
442243789Sdim
443243789Sdim    // See if we can get the length of the input string.
444243789Sdim    uint64_t SrcLen = GetStringLength(Src);
445243789Sdim    if (SrcLen == 0) return 0;
446243789Sdim    --SrcLen;  // Unbias length.
447243789Sdim
448243789Sdim    // Handle the simple, do-nothing cases:
449243789Sdim    // strncat(x, "", c) -> x
450243789Sdim    // strncat(x,  c, 0) -> x
451243789Sdim    if (SrcLen == 0 || Len == 0) return Dst;
452243789Sdim
453243789Sdim    // These optimizations require DataLayout.
454243789Sdim    if (!TD) return 0;
455243789Sdim
456243789Sdim    // We don't optimize this case
457243789Sdim    if (Len < SrcLen) return 0;
458243789Sdim
459243789Sdim    // strncat(x, s, c) -> strcat(x, s)
460243789Sdim    // s is constant so the strcat can be optimized further
461243789Sdim    return emitStrLenMemCpy(Src, Dst, SrcLen, B);
462243789Sdim  }
463243789Sdim};
464243789Sdim
465243789Sdimstruct StrChrOpt : public LibCallOptimization {
466243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
467243789Sdim    // Verify the "strchr" function prototype.
468243789Sdim    FunctionType *FT = Callee->getFunctionType();
469243789Sdim    if (FT->getNumParams() != 2 ||
470243789Sdim        FT->getReturnType() != B.getInt8PtrTy() ||
471243789Sdim        FT->getParamType(0) != FT->getReturnType() ||
472243789Sdim        !FT->getParamType(1)->isIntegerTy(32))
473243789Sdim      return 0;
474243789Sdim
475243789Sdim    Value *SrcStr = CI->getArgOperand(0);
476243789Sdim
477243789Sdim    // If the second operand is non-constant, see if we can compute the length
478243789Sdim    // of the input string and turn this into memchr.
479243789Sdim    ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getArgOperand(1));
480243789Sdim    if (CharC == 0) {
481243789Sdim      // These optimizations require DataLayout.
482243789Sdim      if (!TD) return 0;
483243789Sdim
484243789Sdim      uint64_t Len = GetStringLength(SrcStr);
485243789Sdim      if (Len == 0 || !FT->getParamType(1)->isIntegerTy(32))// memchr needs i32.
486243789Sdim        return 0;
487243789Sdim
488243789Sdim      return EmitMemChr(SrcStr, CI->getArgOperand(1), // include nul.
489243789Sdim                        ConstantInt::get(TD->getIntPtrType(*Context), Len),
490243789Sdim                        B, TD, TLI);
491243789Sdim    }
492243789Sdim
493243789Sdim    // Otherwise, the character is a constant, see if the first argument is
494243789Sdim    // a string literal.  If so, we can constant fold.
495243789Sdim    StringRef Str;
496243789Sdim    if (!getConstantStringInfo(SrcStr, Str))
497243789Sdim      return 0;
498243789Sdim
499243789Sdim    // Compute the offset, make sure to handle the case when we're searching for
500243789Sdim    // zero (a weird way to spell strlen).
501263508Sdim    size_t I = (0xFF & CharC->getSExtValue()) == 0 ?
502243789Sdim        Str.size() : Str.find(CharC->getSExtValue());
503243789Sdim    if (I == StringRef::npos) // Didn't find the char.  strchr returns null.
504243789Sdim      return Constant::getNullValue(CI->getType());
505243789Sdim
506243789Sdim    // strchr(s+n,c)  -> gep(s+n+i,c)
507243789Sdim    return B.CreateGEP(SrcStr, B.getInt64(I), "strchr");
508243789Sdim  }
509243789Sdim};
510243789Sdim
511243789Sdimstruct StrRChrOpt : public LibCallOptimization {
512243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
513243789Sdim    // Verify the "strrchr" function prototype.
514243789Sdim    FunctionType *FT = Callee->getFunctionType();
515243789Sdim    if (FT->getNumParams() != 2 ||
516243789Sdim        FT->getReturnType() != B.getInt8PtrTy() ||
517243789Sdim        FT->getParamType(0) != FT->getReturnType() ||
518243789Sdim        !FT->getParamType(1)->isIntegerTy(32))
519243789Sdim      return 0;
520243789Sdim
521243789Sdim    Value *SrcStr = CI->getArgOperand(0);
522243789Sdim    ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getArgOperand(1));
523243789Sdim
524243789Sdim    // Cannot fold anything if we're not looking for a constant.
525243789Sdim    if (!CharC)
526243789Sdim      return 0;
527243789Sdim
528243789Sdim    StringRef Str;
529243789Sdim    if (!getConstantStringInfo(SrcStr, Str)) {
530243789Sdim      // strrchr(s, 0) -> strchr(s, 0)
531243789Sdim      if (TD && CharC->isZero())
532243789Sdim        return EmitStrChr(SrcStr, '\0', B, TD, TLI);
533243789Sdim      return 0;
534243789Sdim    }
535243789Sdim
536243789Sdim    // Compute the offset.
537263508Sdim    size_t I = (0xFF & CharC->getSExtValue()) == 0 ?
538243789Sdim        Str.size() : Str.rfind(CharC->getSExtValue());
539243789Sdim    if (I == StringRef::npos) // Didn't find the char. Return null.
540243789Sdim      return Constant::getNullValue(CI->getType());
541243789Sdim
542243789Sdim    // strrchr(s+n,c) -> gep(s+n+i,c)
543243789Sdim    return B.CreateGEP(SrcStr, B.getInt64(I), "strrchr");
544243789Sdim  }
545243789Sdim};
546243789Sdim
547243789Sdimstruct StrCmpOpt : public LibCallOptimization {
548243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
549243789Sdim    // Verify the "strcmp" function prototype.
550243789Sdim    FunctionType *FT = Callee->getFunctionType();
551243789Sdim    if (FT->getNumParams() != 2 ||
552243789Sdim        !FT->getReturnType()->isIntegerTy(32) ||
553243789Sdim        FT->getParamType(0) != FT->getParamType(1) ||
554243789Sdim        FT->getParamType(0) != B.getInt8PtrTy())
555243789Sdim      return 0;
556243789Sdim
557243789Sdim    Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1);
558243789Sdim    if (Str1P == Str2P)      // strcmp(x,x)  -> 0
559243789Sdim      return ConstantInt::get(CI->getType(), 0);
560243789Sdim
561243789Sdim    StringRef Str1, Str2;
562243789Sdim    bool HasStr1 = getConstantStringInfo(Str1P, Str1);
563243789Sdim    bool HasStr2 = getConstantStringInfo(Str2P, Str2);
564243789Sdim
565243789Sdim    // strcmp(x, y)  -> cnst  (if both x and y are constant strings)
566243789Sdim    if (HasStr1 && HasStr2)
567243789Sdim      return ConstantInt::get(CI->getType(), Str1.compare(Str2));
568243789Sdim
569243789Sdim    if (HasStr1 && Str1.empty()) // strcmp("", x) -> -*x
570243789Sdim      return B.CreateNeg(B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"),
571243789Sdim                                      CI->getType()));
572243789Sdim
573243789Sdim    if (HasStr2 && Str2.empty()) // strcmp(x,"") -> *x
574243789Sdim      return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType());
575243789Sdim
576243789Sdim    // strcmp(P, "x") -> memcmp(P, "x", 2)
577243789Sdim    uint64_t Len1 = GetStringLength(Str1P);
578243789Sdim    uint64_t Len2 = GetStringLength(Str2P);
579243789Sdim    if (Len1 && Len2) {
580243789Sdim      // These optimizations require DataLayout.
581243789Sdim      if (!TD) return 0;
582243789Sdim
583243789Sdim      return EmitMemCmp(Str1P, Str2P,
584243789Sdim                        ConstantInt::get(TD->getIntPtrType(*Context),
585243789Sdim                        std::min(Len1, Len2)), B, TD, TLI);
586243789Sdim    }
587243789Sdim
588243789Sdim    return 0;
589243789Sdim  }
590243789Sdim};
591243789Sdim
592243789Sdimstruct StrNCmpOpt : public LibCallOptimization {
593243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
594243789Sdim    // Verify the "strncmp" function prototype.
595243789Sdim    FunctionType *FT = Callee->getFunctionType();
596243789Sdim    if (FT->getNumParams() != 3 ||
597243789Sdim        !FT->getReturnType()->isIntegerTy(32) ||
598243789Sdim        FT->getParamType(0) != FT->getParamType(1) ||
599243789Sdim        FT->getParamType(0) != B.getInt8PtrTy() ||
600243789Sdim        !FT->getParamType(2)->isIntegerTy())
601243789Sdim      return 0;
602243789Sdim
603243789Sdim    Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1);
604243789Sdim    if (Str1P == Str2P)      // strncmp(x,x,n)  -> 0
605243789Sdim      return ConstantInt::get(CI->getType(), 0);
606243789Sdim
607243789Sdim    // Get the length argument if it is constant.
608243789Sdim    uint64_t Length;
609243789Sdim    if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2)))
610243789Sdim      Length = LengthArg->getZExtValue();
611243789Sdim    else
612243789Sdim      return 0;
613243789Sdim
614243789Sdim    if (Length == 0) // strncmp(x,y,0)   -> 0
615243789Sdim      return ConstantInt::get(CI->getType(), 0);
616243789Sdim
617243789Sdim    if (TD && Length == 1) // strncmp(x,y,1) -> memcmp(x,y,1)
618243789Sdim      return EmitMemCmp(Str1P, Str2P, CI->getArgOperand(2), B, TD, TLI);
619243789Sdim
620243789Sdim    StringRef Str1, Str2;
621243789Sdim    bool HasStr1 = getConstantStringInfo(Str1P, Str1);
622243789Sdim    bool HasStr2 = getConstantStringInfo(Str2P, Str2);
623243789Sdim
624243789Sdim    // strncmp(x, y)  -> cnst  (if both x and y are constant strings)
625243789Sdim    if (HasStr1 && HasStr2) {
626243789Sdim      StringRef SubStr1 = Str1.substr(0, Length);
627243789Sdim      StringRef SubStr2 = Str2.substr(0, Length);
628243789Sdim      return ConstantInt::get(CI->getType(), SubStr1.compare(SubStr2));
629243789Sdim    }
630243789Sdim
631243789Sdim    if (HasStr1 && Str1.empty())  // strncmp("", x, n) -> -*x
632243789Sdim      return B.CreateNeg(B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"),
633243789Sdim                                      CI->getType()));
634243789Sdim
635243789Sdim    if (HasStr2 && Str2.empty())  // strncmp(x, "", n) -> *x
636243789Sdim      return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType());
637243789Sdim
638243789Sdim    return 0;
639243789Sdim  }
640243789Sdim};
641243789Sdim
642243789Sdimstruct StrCpyOpt : public LibCallOptimization {
643243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
644243789Sdim    // Verify the "strcpy" function prototype.
645243789Sdim    FunctionType *FT = Callee->getFunctionType();
646243789Sdim    if (FT->getNumParams() != 2 ||
647243789Sdim        FT->getReturnType() != FT->getParamType(0) ||
648243789Sdim        FT->getParamType(0) != FT->getParamType(1) ||
649243789Sdim        FT->getParamType(0) != B.getInt8PtrTy())
650243789Sdim      return 0;
651243789Sdim
652243789Sdim    Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1);
653243789Sdim    if (Dst == Src)      // strcpy(x,x)  -> x
654243789Sdim      return Src;
655243789Sdim
656243789Sdim    // These optimizations require DataLayout.
657243789Sdim    if (!TD) return 0;
658243789Sdim
659243789Sdim    // See if we can get the length of the input string.
660243789Sdim    uint64_t Len = GetStringLength(Src);
661243789Sdim    if (Len == 0) return 0;
662243789Sdim
663243789Sdim    // We have enough information to now generate the memcpy call to do the
664243789Sdim    // copy for us.  Make a memcpy to copy the nul byte with align = 1.
665243789Sdim    B.CreateMemCpy(Dst, Src,
666243789Sdim		   ConstantInt::get(TD->getIntPtrType(*Context), Len), 1);
667243789Sdim    return Dst;
668243789Sdim  }
669243789Sdim};
670243789Sdim
671243789Sdimstruct StpCpyOpt: public LibCallOptimization {
672243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
673243789Sdim    // Verify the "stpcpy" function prototype.
674243789Sdim    FunctionType *FT = Callee->getFunctionType();
675243789Sdim    if (FT->getNumParams() != 2 ||
676243789Sdim        FT->getReturnType() != FT->getParamType(0) ||
677243789Sdim        FT->getParamType(0) != FT->getParamType(1) ||
678243789Sdim        FT->getParamType(0) != B.getInt8PtrTy())
679243789Sdim      return 0;
680243789Sdim
681243789Sdim    // These optimizations require DataLayout.
682243789Sdim    if (!TD) return 0;
683243789Sdim
684243789Sdim    Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1);
685243789Sdim    if (Dst == Src) {  // stpcpy(x,x)  -> x+strlen(x)
686243789Sdim      Value *StrLen = EmitStrLen(Src, B, TD, TLI);
687243789Sdim      return StrLen ? B.CreateInBoundsGEP(Dst, StrLen) : 0;
688243789Sdim    }
689243789Sdim
690243789Sdim    // See if we can get the length of the input string.
691243789Sdim    uint64_t Len = GetStringLength(Src);
692243789Sdim    if (Len == 0) return 0;
693243789Sdim
694243789Sdim    Type *PT = FT->getParamType(0);
695243789Sdim    Value *LenV = ConstantInt::get(TD->getIntPtrType(PT), Len);
696243789Sdim    Value *DstEnd = B.CreateGEP(Dst,
697243789Sdim                                ConstantInt::get(TD->getIntPtrType(PT),
698243789Sdim                                                 Len - 1));
699243789Sdim
700243789Sdim    // We have enough information to now generate the memcpy call to do the
701243789Sdim    // copy for us.  Make a memcpy to copy the nul byte with align = 1.
702243789Sdim    B.CreateMemCpy(Dst, Src, LenV, 1);
703243789Sdim    return DstEnd;
704243789Sdim  }
705243789Sdim};
706243789Sdim
707243789Sdimstruct StrNCpyOpt : public LibCallOptimization {
708243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
709243789Sdim    FunctionType *FT = Callee->getFunctionType();
710243789Sdim    if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
711243789Sdim        FT->getParamType(0) != FT->getParamType(1) ||
712243789Sdim        FT->getParamType(0) != B.getInt8PtrTy() ||
713243789Sdim        !FT->getParamType(2)->isIntegerTy())
714243789Sdim      return 0;
715243789Sdim
716243789Sdim    Value *Dst = CI->getArgOperand(0);
717243789Sdim    Value *Src = CI->getArgOperand(1);
718243789Sdim    Value *LenOp = CI->getArgOperand(2);
719243789Sdim
720243789Sdim    // See if we can get the length of the input string.
721243789Sdim    uint64_t SrcLen = GetStringLength(Src);
722243789Sdim    if (SrcLen == 0) return 0;
723243789Sdim    --SrcLen;
724243789Sdim
725243789Sdim    if (SrcLen == 0) {
726243789Sdim      // strncpy(x, "", y) -> memset(x, '\0', y, 1)
727243789Sdim      B.CreateMemSet(Dst, B.getInt8('\0'), LenOp, 1);
728243789Sdim      return Dst;
729243789Sdim    }
730243789Sdim
731243789Sdim    uint64_t Len;
732243789Sdim    if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(LenOp))
733243789Sdim      Len = LengthArg->getZExtValue();
734243789Sdim    else
735243789Sdim      return 0;
736243789Sdim
737243789Sdim    if (Len == 0) return Dst; // strncpy(x, y, 0) -> x
738243789Sdim
739243789Sdim    // These optimizations require DataLayout.
740243789Sdim    if (!TD) return 0;
741243789Sdim
742243789Sdim    // Let strncpy handle the zero padding
743243789Sdim    if (Len > SrcLen+1) return 0;
744243789Sdim
745243789Sdim    Type *PT = FT->getParamType(0);
746243789Sdim    // strncpy(x, s, c) -> memcpy(x, s, c, 1) [s and c are constant]
747243789Sdim    B.CreateMemCpy(Dst, Src,
748243789Sdim                   ConstantInt::get(TD->getIntPtrType(PT), Len), 1);
749243789Sdim
750243789Sdim    return Dst;
751243789Sdim  }
752243789Sdim};
753243789Sdim
754243789Sdimstruct StrLenOpt : public LibCallOptimization {
755249423Sdim  virtual bool ignoreCallingConv() { return true; }
756243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
757243789Sdim    FunctionType *FT = Callee->getFunctionType();
758243789Sdim    if (FT->getNumParams() != 1 ||
759243789Sdim        FT->getParamType(0) != B.getInt8PtrTy() ||
760243789Sdim        !FT->getReturnType()->isIntegerTy())
761243789Sdim      return 0;
762243789Sdim
763243789Sdim    Value *Src = CI->getArgOperand(0);
764243789Sdim
765243789Sdim    // Constant folding: strlen("xyz") -> 3
766243789Sdim    if (uint64_t Len = GetStringLength(Src))
767243789Sdim      return ConstantInt::get(CI->getType(), Len-1);
768243789Sdim
769243789Sdim    // strlen(x) != 0 --> *x != 0
770243789Sdim    // strlen(x) == 0 --> *x == 0
771243789Sdim    if (isOnlyUsedInZeroEqualityComparison(CI))
772243789Sdim      return B.CreateZExt(B.CreateLoad(Src, "strlenfirst"), CI->getType());
773243789Sdim    return 0;
774243789Sdim  }
775243789Sdim};
776243789Sdim
777243789Sdimstruct StrPBrkOpt : public LibCallOptimization {
778243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
779243789Sdim    FunctionType *FT = Callee->getFunctionType();
780243789Sdim    if (FT->getNumParams() != 2 ||
781243789Sdim        FT->getParamType(0) != B.getInt8PtrTy() ||
782243789Sdim        FT->getParamType(1) != FT->getParamType(0) ||
783243789Sdim        FT->getReturnType() != FT->getParamType(0))
784243789Sdim      return 0;
785243789Sdim
786243789Sdim    StringRef S1, S2;
787243789Sdim    bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1);
788243789Sdim    bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2);
789243789Sdim
790243789Sdim    // strpbrk(s, "") -> NULL
791243789Sdim    // strpbrk("", s) -> NULL
792243789Sdim    if ((HasS1 && S1.empty()) || (HasS2 && S2.empty()))
793243789Sdim      return Constant::getNullValue(CI->getType());
794243789Sdim
795243789Sdim    // Constant folding.
796243789Sdim    if (HasS1 && HasS2) {
797243789Sdim      size_t I = S1.find_first_of(S2);
798263508Sdim      if (I == StringRef::npos) // No match.
799243789Sdim        return Constant::getNullValue(CI->getType());
800243789Sdim
801243789Sdim      return B.CreateGEP(CI->getArgOperand(0), B.getInt64(I), "strpbrk");
802243789Sdim    }
803243789Sdim
804243789Sdim    // strpbrk(s, "a") -> strchr(s, 'a')
805243789Sdim    if (TD && HasS2 && S2.size() == 1)
806243789Sdim      return EmitStrChr(CI->getArgOperand(0), S2[0], B, TD, TLI);
807243789Sdim
808243789Sdim    return 0;
809243789Sdim  }
810243789Sdim};
811243789Sdim
812243789Sdimstruct StrToOpt : public LibCallOptimization {
813243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
814243789Sdim    FunctionType *FT = Callee->getFunctionType();
815243789Sdim    if ((FT->getNumParams() != 2 && FT->getNumParams() != 3) ||
816243789Sdim        !FT->getParamType(0)->isPointerTy() ||
817243789Sdim        !FT->getParamType(1)->isPointerTy())
818243789Sdim      return 0;
819243789Sdim
820243789Sdim    Value *EndPtr = CI->getArgOperand(1);
821243789Sdim    if (isa<ConstantPointerNull>(EndPtr)) {
822243789Sdim      // With a null EndPtr, this function won't capture the main argument.
823243789Sdim      // It would be readonly too, except that it still may write to errno.
824249423Sdim      CI->addAttribute(1, Attribute::NoCapture);
825243789Sdim    }
826243789Sdim
827243789Sdim    return 0;
828243789Sdim  }
829243789Sdim};
830243789Sdim
831243789Sdimstruct StrSpnOpt : public LibCallOptimization {
832243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
833243789Sdim    FunctionType *FT = Callee->getFunctionType();
834243789Sdim    if (FT->getNumParams() != 2 ||
835243789Sdim        FT->getParamType(0) != B.getInt8PtrTy() ||
836243789Sdim        FT->getParamType(1) != FT->getParamType(0) ||
837243789Sdim        !FT->getReturnType()->isIntegerTy())
838243789Sdim      return 0;
839243789Sdim
840243789Sdim    StringRef S1, S2;
841243789Sdim    bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1);
842243789Sdim    bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2);
843243789Sdim
844243789Sdim    // strspn(s, "") -> 0
845243789Sdim    // strspn("", s) -> 0
846243789Sdim    if ((HasS1 && S1.empty()) || (HasS2 && S2.empty()))
847243789Sdim      return Constant::getNullValue(CI->getType());
848243789Sdim
849243789Sdim    // Constant folding.
850243789Sdim    if (HasS1 && HasS2) {
851243789Sdim      size_t Pos = S1.find_first_not_of(S2);
852243789Sdim      if (Pos == StringRef::npos) Pos = S1.size();
853243789Sdim      return ConstantInt::get(CI->getType(), Pos);
854243789Sdim    }
855243789Sdim
856243789Sdim    return 0;
857243789Sdim  }
858243789Sdim};
859243789Sdim
860243789Sdimstruct StrCSpnOpt : public LibCallOptimization {
861243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
862243789Sdim    FunctionType *FT = Callee->getFunctionType();
863243789Sdim    if (FT->getNumParams() != 2 ||
864243789Sdim        FT->getParamType(0) != B.getInt8PtrTy() ||
865243789Sdim        FT->getParamType(1) != FT->getParamType(0) ||
866243789Sdim        !FT->getReturnType()->isIntegerTy())
867243789Sdim      return 0;
868243789Sdim
869243789Sdim    StringRef S1, S2;
870243789Sdim    bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1);
871243789Sdim    bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2);
872243789Sdim
873243789Sdim    // strcspn("", s) -> 0
874243789Sdim    if (HasS1 && S1.empty())
875243789Sdim      return Constant::getNullValue(CI->getType());
876243789Sdim
877243789Sdim    // Constant folding.
878243789Sdim    if (HasS1 && HasS2) {
879243789Sdim      size_t Pos = S1.find_first_of(S2);
880243789Sdim      if (Pos == StringRef::npos) Pos = S1.size();
881243789Sdim      return ConstantInt::get(CI->getType(), Pos);
882243789Sdim    }
883243789Sdim
884243789Sdim    // strcspn(s, "") -> strlen(s)
885243789Sdim    if (TD && HasS2 && S2.empty())
886243789Sdim      return EmitStrLen(CI->getArgOperand(0), B, TD, TLI);
887243789Sdim
888243789Sdim    return 0;
889243789Sdim  }
890243789Sdim};
891243789Sdim
892243789Sdimstruct StrStrOpt : public LibCallOptimization {
893243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
894243789Sdim    FunctionType *FT = Callee->getFunctionType();
895243789Sdim    if (FT->getNumParams() != 2 ||
896243789Sdim        !FT->getParamType(0)->isPointerTy() ||
897243789Sdim        !FT->getParamType(1)->isPointerTy() ||
898243789Sdim        !FT->getReturnType()->isPointerTy())
899243789Sdim      return 0;
900243789Sdim
901243789Sdim    // fold strstr(x, x) -> x.
902243789Sdim    if (CI->getArgOperand(0) == CI->getArgOperand(1))
903243789Sdim      return B.CreateBitCast(CI->getArgOperand(0), CI->getType());
904243789Sdim
905243789Sdim    // fold strstr(a, b) == a -> strncmp(a, b, strlen(b)) == 0
906243789Sdim    if (TD && isOnlyUsedInEqualityComparison(CI, CI->getArgOperand(0))) {
907243789Sdim      Value *StrLen = EmitStrLen(CI->getArgOperand(1), B, TD, TLI);
908243789Sdim      if (!StrLen)
909243789Sdim        return 0;
910243789Sdim      Value *StrNCmp = EmitStrNCmp(CI->getArgOperand(0), CI->getArgOperand(1),
911243789Sdim                                   StrLen, B, TD, TLI);
912243789Sdim      if (!StrNCmp)
913243789Sdim        return 0;
914243789Sdim      for (Value::use_iterator UI = CI->use_begin(), UE = CI->use_end();
915243789Sdim           UI != UE; ) {
916243789Sdim        ICmpInst *Old = cast<ICmpInst>(*UI++);
917243789Sdim        Value *Cmp = B.CreateICmp(Old->getPredicate(), StrNCmp,
918243789Sdim                                  ConstantInt::getNullValue(StrNCmp->getType()),
919243789Sdim                                  "cmp");
920243789Sdim        LCS->replaceAllUsesWith(Old, Cmp);
921243789Sdim      }
922243789Sdim      return CI;
923243789Sdim    }
924243789Sdim
925243789Sdim    // See if either input string is a constant string.
926243789Sdim    StringRef SearchStr, ToFindStr;
927243789Sdim    bool HasStr1 = getConstantStringInfo(CI->getArgOperand(0), SearchStr);
928243789Sdim    bool HasStr2 = getConstantStringInfo(CI->getArgOperand(1), ToFindStr);
929243789Sdim
930243789Sdim    // fold strstr(x, "") -> x.
931243789Sdim    if (HasStr2 && ToFindStr.empty())
932243789Sdim      return B.CreateBitCast(CI->getArgOperand(0), CI->getType());
933243789Sdim
934243789Sdim    // If both strings are known, constant fold it.
935243789Sdim    if (HasStr1 && HasStr2) {
936263508Sdim      size_t Offset = SearchStr.find(ToFindStr);
937243789Sdim
938243789Sdim      if (Offset == StringRef::npos) // strstr("foo", "bar") -> null
939243789Sdim        return Constant::getNullValue(CI->getType());
940243789Sdim
941243789Sdim      // strstr("abcd", "bc") -> gep((char*)"abcd", 1)
942243789Sdim      Value *Result = CastToCStr(CI->getArgOperand(0), B);
943243789Sdim      Result = B.CreateConstInBoundsGEP1_64(Result, Offset, "strstr");
944243789Sdim      return B.CreateBitCast(Result, CI->getType());
945243789Sdim    }
946243789Sdim
947243789Sdim    // fold strstr(x, "y") -> strchr(x, 'y').
948243789Sdim    if (HasStr2 && ToFindStr.size() == 1) {
949243789Sdim      Value *StrChr= EmitStrChr(CI->getArgOperand(0), ToFindStr[0], B, TD, TLI);
950243789Sdim      return StrChr ? B.CreateBitCast(StrChr, CI->getType()) : 0;
951243789Sdim    }
952243789Sdim    return 0;
953243789Sdim  }
954243789Sdim};
955243789Sdim
956243789Sdimstruct MemCmpOpt : public LibCallOptimization {
957243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
958243789Sdim    FunctionType *FT = Callee->getFunctionType();
959243789Sdim    if (FT->getNumParams() != 3 || !FT->getParamType(0)->isPointerTy() ||
960243789Sdim        !FT->getParamType(1)->isPointerTy() ||
961243789Sdim        !FT->getReturnType()->isIntegerTy(32))
962243789Sdim      return 0;
963243789Sdim
964243789Sdim    Value *LHS = CI->getArgOperand(0), *RHS = CI->getArgOperand(1);
965243789Sdim
966243789Sdim    if (LHS == RHS)  // memcmp(s,s,x) -> 0
967243789Sdim      return Constant::getNullValue(CI->getType());
968243789Sdim
969243789Sdim    // Make sure we have a constant length.
970243789Sdim    ConstantInt *LenC = dyn_cast<ConstantInt>(CI->getArgOperand(2));
971243789Sdim    if (!LenC) return 0;
972243789Sdim    uint64_t Len = LenC->getZExtValue();
973243789Sdim
974243789Sdim    if (Len == 0) // memcmp(s1,s2,0) -> 0
975243789Sdim      return Constant::getNullValue(CI->getType());
976243789Sdim
977243789Sdim    // memcmp(S1,S2,1) -> *(unsigned char*)LHS - *(unsigned char*)RHS
978243789Sdim    if (Len == 1) {
979243789Sdim      Value *LHSV = B.CreateZExt(B.CreateLoad(CastToCStr(LHS, B), "lhsc"),
980243789Sdim                                 CI->getType(), "lhsv");
981243789Sdim      Value *RHSV = B.CreateZExt(B.CreateLoad(CastToCStr(RHS, B), "rhsc"),
982243789Sdim                                 CI->getType(), "rhsv");
983243789Sdim      return B.CreateSub(LHSV, RHSV, "chardiff");
984243789Sdim    }
985243789Sdim
986243789Sdim    // Constant folding: memcmp(x, y, l) -> cnst (all arguments are constant)
987243789Sdim    StringRef LHSStr, RHSStr;
988243789Sdim    if (getConstantStringInfo(LHS, LHSStr) &&
989243789Sdim        getConstantStringInfo(RHS, RHSStr)) {
990243789Sdim      // Make sure we're not reading out-of-bounds memory.
991243789Sdim      if (Len > LHSStr.size() || Len > RHSStr.size())
992243789Sdim        return 0;
993249423Sdim      // Fold the memcmp and normalize the result.  This way we get consistent
994249423Sdim      // results across multiple platforms.
995249423Sdim      uint64_t Ret = 0;
996249423Sdim      int Cmp = memcmp(LHSStr.data(), RHSStr.data(), Len);
997249423Sdim      if (Cmp < 0)
998249423Sdim        Ret = -1;
999249423Sdim      else if (Cmp > 0)
1000249423Sdim        Ret = 1;
1001243789Sdim      return ConstantInt::get(CI->getType(), Ret);
1002243789Sdim    }
1003243789Sdim
1004243789Sdim    return 0;
1005243789Sdim  }
1006243789Sdim};
1007243789Sdim
1008243789Sdimstruct MemCpyOpt : public LibCallOptimization {
1009243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1010243789Sdim    // These optimizations require DataLayout.
1011243789Sdim    if (!TD) return 0;
1012243789Sdim
1013243789Sdim    FunctionType *FT = Callee->getFunctionType();
1014243789Sdim    if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
1015243789Sdim        !FT->getParamType(0)->isPointerTy() ||
1016243789Sdim        !FT->getParamType(1)->isPointerTy() ||
1017243789Sdim        FT->getParamType(2) != TD->getIntPtrType(*Context))
1018243789Sdim      return 0;
1019243789Sdim
1020243789Sdim    // memcpy(x, y, n) -> llvm.memcpy(x, y, n, 1)
1021243789Sdim    B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
1022243789Sdim                   CI->getArgOperand(2), 1);
1023243789Sdim    return CI->getArgOperand(0);
1024243789Sdim  }
1025243789Sdim};
1026243789Sdim
1027243789Sdimstruct MemMoveOpt : public LibCallOptimization {
1028243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1029243789Sdim    // These optimizations require DataLayout.
1030243789Sdim    if (!TD) return 0;
1031243789Sdim
1032243789Sdim    FunctionType *FT = Callee->getFunctionType();
1033243789Sdim    if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
1034243789Sdim        !FT->getParamType(0)->isPointerTy() ||
1035243789Sdim        !FT->getParamType(1)->isPointerTy() ||
1036243789Sdim        FT->getParamType(2) != TD->getIntPtrType(*Context))
1037243789Sdim      return 0;
1038243789Sdim
1039243789Sdim    // memmove(x, y, n) -> llvm.memmove(x, y, n, 1)
1040243789Sdim    B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1),
1041243789Sdim                    CI->getArgOperand(2), 1);
1042243789Sdim    return CI->getArgOperand(0);
1043243789Sdim  }
1044243789Sdim};
1045243789Sdim
1046243789Sdimstruct MemSetOpt : public LibCallOptimization {
1047243789Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1048243789Sdim    // These optimizations require DataLayout.
1049243789Sdim    if (!TD) return 0;
1050243789Sdim
1051243789Sdim    FunctionType *FT = Callee->getFunctionType();
1052243789Sdim    if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
1053243789Sdim        !FT->getParamType(0)->isPointerTy() ||
1054243789Sdim        !FT->getParamType(1)->isIntegerTy() ||
1055263508Sdim        FT->getParamType(2) != TD->getIntPtrType(FT->getParamType(0)))
1056243789Sdim      return 0;
1057243789Sdim
1058243789Sdim    // memset(p, v, n) -> llvm.memset(p, v, n, 1)
1059243789Sdim    Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), false);
1060243789Sdim    B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1);
1061243789Sdim    return CI->getArgOperand(0);
1062243789Sdim  }
1063243789Sdim};
1064243789Sdim
1065249423Sdim//===----------------------------------------------------------------------===//
1066249423Sdim// Math Library Optimizations
1067249423Sdim//===----------------------------------------------------------------------===//
1068249423Sdim
1069249423Sdim//===----------------------------------------------------------------------===//
1070249423Sdim// Double -> Float Shrinking Optimizations for Unary Functions like 'floor'
1071249423Sdim
1072249423Sdimstruct UnaryDoubleFPOpt : public LibCallOptimization {
1073249423Sdim  bool CheckRetType;
1074249423Sdim  UnaryDoubleFPOpt(bool CheckReturnType): CheckRetType(CheckReturnType) {}
1075249423Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1076249423Sdim    FunctionType *FT = Callee->getFunctionType();
1077249423Sdim    if (FT->getNumParams() != 1 || !FT->getReturnType()->isDoubleTy() ||
1078249423Sdim        !FT->getParamType(0)->isDoubleTy())
1079249423Sdim      return 0;
1080249423Sdim
1081249423Sdim    if (CheckRetType) {
1082249423Sdim      // Check if all the uses for function like 'sin' are converted to float.
1083249423Sdim      for (Value::use_iterator UseI = CI->use_begin(); UseI != CI->use_end();
1084249423Sdim          ++UseI) {
1085249423Sdim        FPTruncInst *Cast = dyn_cast<FPTruncInst>(*UseI);
1086249423Sdim        if (Cast == 0 || !Cast->getType()->isFloatTy())
1087249423Sdim          return 0;
1088249423Sdim      }
1089249423Sdim    }
1090249423Sdim
1091249423Sdim    // If this is something like 'floor((double)floatval)', convert to floorf.
1092249423Sdim    FPExtInst *Cast = dyn_cast<FPExtInst>(CI->getArgOperand(0));
1093249423Sdim    if (Cast == 0 || !Cast->getOperand(0)->getType()->isFloatTy())
1094249423Sdim      return 0;
1095249423Sdim
1096249423Sdim    // floor((double)floatval) -> (double)floorf(floatval)
1097249423Sdim    Value *V = Cast->getOperand(0);
1098249423Sdim    V = EmitUnaryFloatFnCall(V, Callee->getName(), B, Callee->getAttributes());
1099249423Sdim    return B.CreateFPExt(V, B.getDoubleTy());
1100249423Sdim  }
1101249423Sdim};
1102249423Sdim
1103249423Sdimstruct UnsafeFPLibCallOptimization : public LibCallOptimization {
1104249423Sdim  bool UnsafeFPShrink;
1105249423Sdim  UnsafeFPLibCallOptimization(bool UnsafeFPShrink) {
1106249423Sdim    this->UnsafeFPShrink = UnsafeFPShrink;
1107249423Sdim  }
1108249423Sdim};
1109249423Sdim
1110249423Sdimstruct CosOpt : public UnsafeFPLibCallOptimization {
1111249423Sdim  CosOpt(bool UnsafeFPShrink) : UnsafeFPLibCallOptimization(UnsafeFPShrink) {}
1112249423Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1113249423Sdim    Value *Ret = NULL;
1114249423Sdim    if (UnsafeFPShrink && Callee->getName() == "cos" &&
1115249423Sdim        TLI->has(LibFunc::cosf)) {
1116249423Sdim      UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true);
1117249423Sdim      Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B);
1118249423Sdim    }
1119249423Sdim
1120249423Sdim    FunctionType *FT = Callee->getFunctionType();
1121249423Sdim    // Just make sure this has 1 argument of FP type, which matches the
1122249423Sdim    // result type.
1123249423Sdim    if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) ||
1124249423Sdim        !FT->getParamType(0)->isFloatingPointTy())
1125249423Sdim      return Ret;
1126249423Sdim
1127249423Sdim    // cos(-x) -> cos(x)
1128249423Sdim    Value *Op1 = CI->getArgOperand(0);
1129249423Sdim    if (BinaryOperator::isFNeg(Op1)) {
1130249423Sdim      BinaryOperator *BinExpr = cast<BinaryOperator>(Op1);
1131249423Sdim      return B.CreateCall(Callee, BinExpr->getOperand(1), "cos");
1132249423Sdim    }
1133249423Sdim    return Ret;
1134249423Sdim  }
1135249423Sdim};
1136249423Sdim
1137249423Sdimstruct PowOpt : public UnsafeFPLibCallOptimization {
1138249423Sdim  PowOpt(bool UnsafeFPShrink) : UnsafeFPLibCallOptimization(UnsafeFPShrink) {}
1139249423Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1140249423Sdim    Value *Ret = NULL;
1141249423Sdim    if (UnsafeFPShrink && Callee->getName() == "pow" &&
1142249423Sdim        TLI->has(LibFunc::powf)) {
1143249423Sdim      UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true);
1144249423Sdim      Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B);
1145249423Sdim    }
1146249423Sdim
1147249423Sdim    FunctionType *FT = Callee->getFunctionType();
1148249423Sdim    // Just make sure this has 2 arguments of the same FP type, which match the
1149249423Sdim    // result type.
1150249423Sdim    if (FT->getNumParams() != 2 || FT->getReturnType() != FT->getParamType(0) ||
1151249423Sdim        FT->getParamType(0) != FT->getParamType(1) ||
1152249423Sdim        !FT->getParamType(0)->isFloatingPointTy())
1153249423Sdim      return Ret;
1154249423Sdim
1155249423Sdim    Value *Op1 = CI->getArgOperand(0), *Op2 = CI->getArgOperand(1);
1156249423Sdim    if (ConstantFP *Op1C = dyn_cast<ConstantFP>(Op1)) {
1157263508Sdim      // pow(1.0, x) -> 1.0
1158263508Sdim      if (Op1C->isExactlyValue(1.0))
1159249423Sdim        return Op1C;
1160263508Sdim      // pow(2.0, x) -> exp2(x)
1161263508Sdim      if (Op1C->isExactlyValue(2.0) &&
1162263508Sdim          hasUnaryFloatFn(TLI, Op1->getType(), LibFunc::exp2, LibFunc::exp2f,
1163263508Sdim                          LibFunc::exp2l))
1164249423Sdim        return EmitUnaryFloatFnCall(Op2, "exp2", B, Callee->getAttributes());
1165249423Sdim    }
1166249423Sdim
1167249423Sdim    ConstantFP *Op2C = dyn_cast<ConstantFP>(Op2);
1168249423Sdim    if (Op2C == 0) return Ret;
1169249423Sdim
1170249423Sdim    if (Op2C->getValueAPF().isZero())  // pow(x, 0.0) -> 1.0
1171249423Sdim      return ConstantFP::get(CI->getType(), 1.0);
1172249423Sdim
1173263508Sdim    if (Op2C->isExactlyValue(0.5) &&
1174263508Sdim        hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::sqrt, LibFunc::sqrtf,
1175263508Sdim                        LibFunc::sqrtl) &&
1176263508Sdim        hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::fabs, LibFunc::fabsf,
1177263508Sdim                        LibFunc::fabsl)) {
1178249423Sdim      // Expand pow(x, 0.5) to (x == -infinity ? +infinity : fabs(sqrt(x))).
1179249423Sdim      // This is faster than calling pow, and still handles negative zero
1180249423Sdim      // and negative infinity correctly.
1181249423Sdim      // TODO: In fast-math mode, this could be just sqrt(x).
1182249423Sdim      // TODO: In finite-only mode, this could be just fabs(sqrt(x)).
1183249423Sdim      Value *Inf = ConstantFP::getInfinity(CI->getType());
1184249423Sdim      Value *NegInf = ConstantFP::getInfinity(CI->getType(), true);
1185249423Sdim      Value *Sqrt = EmitUnaryFloatFnCall(Op1, "sqrt", B,
1186249423Sdim                                         Callee->getAttributes());
1187249423Sdim      Value *FAbs = EmitUnaryFloatFnCall(Sqrt, "fabs", B,
1188249423Sdim                                         Callee->getAttributes());
1189249423Sdim      Value *FCmp = B.CreateFCmpOEQ(Op1, NegInf);
1190249423Sdim      Value *Sel = B.CreateSelect(FCmp, Inf, FAbs);
1191249423Sdim      return Sel;
1192249423Sdim    }
1193249423Sdim
1194249423Sdim    if (Op2C->isExactlyValue(1.0))  // pow(x, 1.0) -> x
1195249423Sdim      return Op1;
1196249423Sdim    if (Op2C->isExactlyValue(2.0))  // pow(x, 2.0) -> x*x
1197249423Sdim      return B.CreateFMul(Op1, Op1, "pow2");
1198249423Sdim    if (Op2C->isExactlyValue(-1.0)) // pow(x, -1.0) -> 1.0/x
1199249423Sdim      return B.CreateFDiv(ConstantFP::get(CI->getType(), 1.0),
1200249423Sdim                          Op1, "powrecip");
1201249423Sdim    return 0;
1202249423Sdim  }
1203249423Sdim};
1204249423Sdim
1205249423Sdimstruct Exp2Opt : public UnsafeFPLibCallOptimization {
1206249423Sdim  Exp2Opt(bool UnsafeFPShrink) : UnsafeFPLibCallOptimization(UnsafeFPShrink) {}
1207249423Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1208249423Sdim    Value *Ret = NULL;
1209249423Sdim    if (UnsafeFPShrink && Callee->getName() == "exp2" &&
1210263508Sdim        TLI->has(LibFunc::exp2f)) {
1211249423Sdim      UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true);
1212249423Sdim      Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B);
1213249423Sdim    }
1214249423Sdim
1215249423Sdim    FunctionType *FT = Callee->getFunctionType();
1216249423Sdim    // Just make sure this has 1 argument of FP type, which matches the
1217249423Sdim    // result type.
1218249423Sdim    if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) ||
1219249423Sdim        !FT->getParamType(0)->isFloatingPointTy())
1220249423Sdim      return Ret;
1221249423Sdim
1222249423Sdim    Value *Op = CI->getArgOperand(0);
1223249423Sdim    // Turn exp2(sitofp(x)) -> ldexp(1.0, sext(x))  if sizeof(x) <= 32
1224249423Sdim    // Turn exp2(uitofp(x)) -> ldexp(1.0, zext(x))  if sizeof(x) < 32
1225249423Sdim    Value *LdExpArg = 0;
1226249423Sdim    if (SIToFPInst *OpC = dyn_cast<SIToFPInst>(Op)) {
1227249423Sdim      if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() <= 32)
1228249423Sdim        LdExpArg = B.CreateSExt(OpC->getOperand(0), B.getInt32Ty());
1229249423Sdim    } else if (UIToFPInst *OpC = dyn_cast<UIToFPInst>(Op)) {
1230249423Sdim      if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() < 32)
1231249423Sdim        LdExpArg = B.CreateZExt(OpC->getOperand(0), B.getInt32Ty());
1232249423Sdim    }
1233249423Sdim
1234249423Sdim    if (LdExpArg) {
1235249423Sdim      const char *Name;
1236249423Sdim      if (Op->getType()->isFloatTy())
1237249423Sdim        Name = "ldexpf";
1238249423Sdim      else if (Op->getType()->isDoubleTy())
1239249423Sdim        Name = "ldexp";
1240249423Sdim      else
1241249423Sdim        Name = "ldexpl";
1242249423Sdim
1243249423Sdim      Constant *One = ConstantFP::get(*Context, APFloat(1.0f));
1244249423Sdim      if (!Op->getType()->isFloatTy())
1245249423Sdim        One = ConstantExpr::getFPExtend(One, Op->getType());
1246249423Sdim
1247249423Sdim      Module *M = Caller->getParent();
1248249423Sdim      Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
1249249423Sdim                                             Op->getType(),
1250249423Sdim                                             B.getInt32Ty(), NULL);
1251249423Sdim      CallInst *CI = B.CreateCall2(Callee, One, LdExpArg);
1252249423Sdim      if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
1253249423Sdim        CI->setCallingConv(F->getCallingConv());
1254249423Sdim
1255249423Sdim      return CI;
1256249423Sdim    }
1257249423Sdim    return Ret;
1258249423Sdim  }
1259249423Sdim};
1260249423Sdim
1261263508Sdimstruct SinCosPiOpt : public LibCallOptimization {
1262263508Sdim  SinCosPiOpt() {}
1263263508Sdim
1264263508Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1265263508Sdim    // Make sure the prototype is as expected, otherwise the rest of the
1266263508Sdim    // function is probably invalid and likely to abort.
1267263508Sdim    if (!isTrigLibCall(CI))
1268263508Sdim      return 0;
1269263508Sdim
1270263508Sdim    Value *Arg = CI->getArgOperand(0);
1271263508Sdim    SmallVector<CallInst *, 1> SinCalls;
1272263508Sdim    SmallVector<CallInst *, 1> CosCalls;
1273263508Sdim    SmallVector<CallInst *, 1> SinCosCalls;
1274263508Sdim
1275263508Sdim    bool IsFloat = Arg->getType()->isFloatTy();
1276263508Sdim
1277263508Sdim    // Look for all compatible sinpi, cospi and sincospi calls with the same
1278263508Sdim    // argument. If there are enough (in some sense) we can make the
1279263508Sdim    // substitution.
1280263508Sdim    for (Value::use_iterator UI = Arg->use_begin(), UE = Arg->use_end();
1281263508Sdim         UI != UE; ++UI)
1282263508Sdim      classifyArgUse(*UI, CI->getParent(), IsFloat, SinCalls, CosCalls,
1283263508Sdim                     SinCosCalls);
1284263508Sdim
1285263508Sdim    // It's only worthwhile if both sinpi and cospi are actually used.
1286263508Sdim    if (SinCosCalls.empty() && (SinCalls.empty() || CosCalls.empty()))
1287263508Sdim      return 0;
1288263508Sdim
1289263508Sdim    Value *Sin, *Cos, *SinCos;
1290263508Sdim    insertSinCosCall(B, CI->getCalledFunction(), Arg, IsFloat, Sin, Cos,
1291263508Sdim                     SinCos);
1292263508Sdim
1293263508Sdim    replaceTrigInsts(SinCalls, Sin);
1294263508Sdim    replaceTrigInsts(CosCalls, Cos);
1295263508Sdim    replaceTrigInsts(SinCosCalls, SinCos);
1296263508Sdim
1297263508Sdim    return 0;
1298263508Sdim  }
1299263508Sdim
1300263508Sdim  bool isTrigLibCall(CallInst *CI) {
1301263508Sdim    Function *Callee = CI->getCalledFunction();
1302263508Sdim    FunctionType *FT = Callee->getFunctionType();
1303263508Sdim
1304263508Sdim    // We can only hope to do anything useful if we can ignore things like errno
1305263508Sdim    // and floating-point exceptions.
1306263508Sdim    bool AttributesSafe = CI->hasFnAttr(Attribute::NoUnwind) &&
1307263508Sdim                          CI->hasFnAttr(Attribute::ReadNone);
1308263508Sdim
1309263508Sdim    // Other than that we need float(float) or double(double)
1310263508Sdim    return AttributesSafe && FT->getNumParams() == 1 &&
1311263508Sdim           FT->getReturnType() == FT->getParamType(0) &&
1312263508Sdim           (FT->getParamType(0)->isFloatTy() ||
1313263508Sdim            FT->getParamType(0)->isDoubleTy());
1314263508Sdim  }
1315263508Sdim
1316263508Sdim  void classifyArgUse(Value *Val, BasicBlock *BB, bool IsFloat,
1317263508Sdim                      SmallVectorImpl<CallInst *> &SinCalls,
1318263508Sdim                      SmallVectorImpl<CallInst *> &CosCalls,
1319263508Sdim                      SmallVectorImpl<CallInst *> &SinCosCalls) {
1320263508Sdim    CallInst *CI = dyn_cast<CallInst>(Val);
1321263508Sdim
1322263508Sdim    if (!CI)
1323263508Sdim      return;
1324263508Sdim
1325263508Sdim    Function *Callee = CI->getCalledFunction();
1326263508Sdim    StringRef FuncName = Callee->getName();
1327263508Sdim    LibFunc::Func Func;
1328263508Sdim    if (!TLI->getLibFunc(FuncName, Func) || !TLI->has(Func) ||
1329263508Sdim        !isTrigLibCall(CI))
1330263508Sdim      return;
1331263508Sdim
1332263508Sdim    if (IsFloat) {
1333263508Sdim      if (Func == LibFunc::sinpif)
1334263508Sdim        SinCalls.push_back(CI);
1335263508Sdim      else if (Func == LibFunc::cospif)
1336263508Sdim        CosCalls.push_back(CI);
1337263508Sdim      else if (Func == LibFunc::sincospi_stretf)
1338263508Sdim        SinCosCalls.push_back(CI);
1339263508Sdim    } else {
1340263508Sdim      if (Func == LibFunc::sinpi)
1341263508Sdim        SinCalls.push_back(CI);
1342263508Sdim      else if (Func == LibFunc::cospi)
1343263508Sdim        CosCalls.push_back(CI);
1344263508Sdim      else if (Func == LibFunc::sincospi_stret)
1345263508Sdim        SinCosCalls.push_back(CI);
1346263508Sdim    }
1347263508Sdim  }
1348263508Sdim
1349263508Sdim  void replaceTrigInsts(SmallVectorImpl<CallInst*> &Calls, Value *Res) {
1350263508Sdim    for (SmallVectorImpl<CallInst*>::iterator I = Calls.begin(),
1351263508Sdim           E = Calls.end();
1352263508Sdim         I != E; ++I) {
1353263508Sdim      LCS->replaceAllUsesWith(*I, Res);
1354263508Sdim    }
1355263508Sdim  }
1356263508Sdim
1357263508Sdim  void insertSinCosCall(IRBuilder<> &B, Function *OrigCallee, Value *Arg,
1358263508Sdim                        bool UseFloat, Value *&Sin, Value *&Cos,
1359263508Sdim                        Value *&SinCos) {
1360263508Sdim    Type *ArgTy = Arg->getType();
1361263508Sdim    Type *ResTy;
1362263508Sdim    StringRef Name;
1363263508Sdim
1364263508Sdim    Triple T(OrigCallee->getParent()->getTargetTriple());
1365263508Sdim    if (UseFloat) {
1366263508Sdim      Name = "__sincospi_stretf";
1367263508Sdim
1368263508Sdim      assert(T.getArch() != Triple::x86 && "x86 messy and unsupported for now");
1369263508Sdim      // x86_64 can't use {float, float} since that would be returned in both
1370263508Sdim      // xmm0 and xmm1, which isn't what a real struct would do.
1371263508Sdim      ResTy = T.getArch() == Triple::x86_64
1372263508Sdim                  ? static_cast<Type *>(VectorType::get(ArgTy, 2))
1373263508Sdim                  : static_cast<Type *>(StructType::get(ArgTy, ArgTy, NULL));
1374263508Sdim    } else {
1375263508Sdim      Name = "__sincospi_stret";
1376263508Sdim      ResTy = StructType::get(ArgTy, ArgTy, NULL);
1377263508Sdim    }
1378263508Sdim
1379263508Sdim    Module *M = OrigCallee->getParent();
1380263508Sdim    Value *Callee = M->getOrInsertFunction(Name, OrigCallee->getAttributes(),
1381263508Sdim                                           ResTy, ArgTy, NULL);
1382263508Sdim
1383263508Sdim    if (Instruction *ArgInst = dyn_cast<Instruction>(Arg)) {
1384263508Sdim      // If the argument is an instruction, it must dominate all uses so put our
1385263508Sdim      // sincos call there.
1386263508Sdim      BasicBlock::iterator Loc = ArgInst;
1387263508Sdim      B.SetInsertPoint(ArgInst->getParent(), ++Loc);
1388263508Sdim    } else {
1389263508Sdim      // Otherwise (e.g. for a constant) the beginning of the function is as
1390263508Sdim      // good a place as any.
1391263508Sdim      BasicBlock &EntryBB = B.GetInsertBlock()->getParent()->getEntryBlock();
1392263508Sdim      B.SetInsertPoint(&EntryBB, EntryBB.begin());
1393263508Sdim    }
1394263508Sdim
1395263508Sdim    SinCos = B.CreateCall(Callee, Arg, "sincospi");
1396263508Sdim
1397263508Sdim    if (SinCos->getType()->isStructTy()) {
1398263508Sdim      Sin = B.CreateExtractValue(SinCos, 0, "sinpi");
1399263508Sdim      Cos = B.CreateExtractValue(SinCos, 1, "cospi");
1400263508Sdim    } else {
1401263508Sdim      Sin = B.CreateExtractElement(SinCos, ConstantInt::get(B.getInt32Ty(), 0),
1402263508Sdim                                   "sinpi");
1403263508Sdim      Cos = B.CreateExtractElement(SinCos, ConstantInt::get(B.getInt32Ty(), 1),
1404263508Sdim                                   "cospi");
1405263508Sdim    }
1406263508Sdim  }
1407263508Sdim
1408263508Sdim};
1409263508Sdim
1410249423Sdim//===----------------------------------------------------------------------===//
1411249423Sdim// Integer Library Call Optimizations
1412249423Sdim//===----------------------------------------------------------------------===//
1413249423Sdim
1414249423Sdimstruct FFSOpt : public LibCallOptimization {
1415249423Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1416249423Sdim    FunctionType *FT = Callee->getFunctionType();
1417249423Sdim    // Just make sure this has 2 arguments of the same FP type, which match the
1418249423Sdim    // result type.
1419249423Sdim    if (FT->getNumParams() != 1 ||
1420249423Sdim        !FT->getReturnType()->isIntegerTy(32) ||
1421249423Sdim        !FT->getParamType(0)->isIntegerTy())
1422249423Sdim      return 0;
1423249423Sdim
1424249423Sdim    Value *Op = CI->getArgOperand(0);
1425249423Sdim
1426249423Sdim    // Constant fold.
1427249423Sdim    if (ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
1428249423Sdim      if (CI->isZero()) // ffs(0) -> 0.
1429249423Sdim        return B.getInt32(0);
1430249423Sdim      // ffs(c) -> cttz(c)+1
1431249423Sdim      return B.getInt32(CI->getValue().countTrailingZeros() + 1);
1432249423Sdim    }
1433249423Sdim
1434249423Sdim    // ffs(x) -> x != 0 ? (i32)llvm.cttz(x)+1 : 0
1435249423Sdim    Type *ArgType = Op->getType();
1436249423Sdim    Value *F = Intrinsic::getDeclaration(Callee->getParent(),
1437249423Sdim                                         Intrinsic::cttz, ArgType);
1438249423Sdim    Value *V = B.CreateCall2(F, Op, B.getFalse(), "cttz");
1439249423Sdim    V = B.CreateAdd(V, ConstantInt::get(V->getType(), 1));
1440249423Sdim    V = B.CreateIntCast(V, B.getInt32Ty(), false);
1441249423Sdim
1442249423Sdim    Value *Cond = B.CreateICmpNE(Op, Constant::getNullValue(ArgType));
1443249423Sdim    return B.CreateSelect(Cond, V, B.getInt32(0));
1444249423Sdim  }
1445249423Sdim};
1446249423Sdim
1447249423Sdimstruct AbsOpt : public LibCallOptimization {
1448249423Sdim  virtual bool ignoreCallingConv() { return true; }
1449249423Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1450249423Sdim    FunctionType *FT = Callee->getFunctionType();
1451249423Sdim    // We require integer(integer) where the types agree.
1452249423Sdim    if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() ||
1453249423Sdim        FT->getParamType(0) != FT->getReturnType())
1454249423Sdim      return 0;
1455249423Sdim
1456249423Sdim    // abs(x) -> x >s -1 ? x : -x
1457249423Sdim    Value *Op = CI->getArgOperand(0);
1458249423Sdim    Value *Pos = B.CreateICmpSGT(Op, Constant::getAllOnesValue(Op->getType()),
1459249423Sdim                                 "ispos");
1460249423Sdim    Value *Neg = B.CreateNeg(Op, "neg");
1461249423Sdim    return B.CreateSelect(Pos, Op, Neg);
1462249423Sdim  }
1463249423Sdim};
1464249423Sdim
1465249423Sdimstruct IsDigitOpt : public LibCallOptimization {
1466249423Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1467249423Sdim    FunctionType *FT = Callee->getFunctionType();
1468249423Sdim    // We require integer(i32)
1469249423Sdim    if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() ||
1470249423Sdim        !FT->getParamType(0)->isIntegerTy(32))
1471249423Sdim      return 0;
1472249423Sdim
1473249423Sdim    // isdigit(c) -> (c-'0') <u 10
1474249423Sdim    Value *Op = CI->getArgOperand(0);
1475249423Sdim    Op = B.CreateSub(Op, B.getInt32('0'), "isdigittmp");
1476249423Sdim    Op = B.CreateICmpULT(Op, B.getInt32(10), "isdigit");
1477249423Sdim    return B.CreateZExt(Op, CI->getType());
1478249423Sdim  }
1479249423Sdim};
1480249423Sdim
1481249423Sdimstruct IsAsciiOpt : public LibCallOptimization {
1482249423Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1483249423Sdim    FunctionType *FT = Callee->getFunctionType();
1484249423Sdim    // We require integer(i32)
1485249423Sdim    if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() ||
1486249423Sdim        !FT->getParamType(0)->isIntegerTy(32))
1487249423Sdim      return 0;
1488249423Sdim
1489249423Sdim    // isascii(c) -> c <u 128
1490249423Sdim    Value *Op = CI->getArgOperand(0);
1491249423Sdim    Op = B.CreateICmpULT(Op, B.getInt32(128), "isascii");
1492249423Sdim    return B.CreateZExt(Op, CI->getType());
1493249423Sdim  }
1494249423Sdim};
1495249423Sdim
1496249423Sdimstruct ToAsciiOpt : public LibCallOptimization {
1497249423Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1498249423Sdim    FunctionType *FT = Callee->getFunctionType();
1499249423Sdim    // We require i32(i32)
1500249423Sdim    if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) ||
1501249423Sdim        !FT->getParamType(0)->isIntegerTy(32))
1502249423Sdim      return 0;
1503249423Sdim
1504249423Sdim    // toascii(c) -> c & 0x7f
1505249423Sdim    return B.CreateAnd(CI->getArgOperand(0),
1506249423Sdim                       ConstantInt::get(CI->getType(),0x7F));
1507249423Sdim  }
1508249423Sdim};
1509249423Sdim
1510249423Sdim//===----------------------------------------------------------------------===//
1511249423Sdim// Formatting and IO Library Call Optimizations
1512249423Sdim//===----------------------------------------------------------------------===//
1513249423Sdim
1514263508Sdimstruct ErrorReportingOpt : public LibCallOptimization {
1515263508Sdim  ErrorReportingOpt(int S = -1) : StreamArg(S) {}
1516263508Sdim
1517263508Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &) {
1518263508Sdim    // Error reporting calls should be cold, mark them as such.
1519263508Sdim    // This applies even to non-builtin calls: it is only a hint and applies to
1520263508Sdim    // functions that the frontend might not understand as builtins.
1521263508Sdim
1522263508Sdim    // This heuristic was suggested in:
1523263508Sdim    // Improving Static Branch Prediction in a Compiler
1524263508Sdim    // Brian L. Deitrich, Ben-Chung Cheng, Wen-mei W. Hwu
1525263508Sdim    // Proceedings of PACT'98, Oct. 1998, IEEE
1526263508Sdim
1527263508Sdim    if (!CI->hasFnAttr(Attribute::Cold) && isReportingError(Callee, CI)) {
1528263508Sdim      CI->addAttribute(AttributeSet::FunctionIndex, Attribute::Cold);
1529263508Sdim    }
1530263508Sdim
1531263508Sdim    return 0;
1532263508Sdim  }
1533263508Sdim
1534263508Sdimprotected:
1535263508Sdim  bool isReportingError(Function *Callee, CallInst *CI) {
1536263508Sdim    if (!ColdErrorCalls)
1537263508Sdim      return false;
1538263508Sdim
1539263508Sdim    if (!Callee || !Callee->isDeclaration())
1540263508Sdim      return false;
1541263508Sdim
1542263508Sdim    if (StreamArg < 0)
1543263508Sdim      return true;
1544263508Sdim
1545263508Sdim    // These functions might be considered cold, but only if their stream
1546263508Sdim    // argument is stderr.
1547263508Sdim
1548263508Sdim    if (StreamArg >= (int) CI->getNumArgOperands())
1549263508Sdim      return false;
1550263508Sdim    LoadInst *LI = dyn_cast<LoadInst>(CI->getArgOperand(StreamArg));
1551263508Sdim    if (!LI)
1552263508Sdim      return false;
1553263508Sdim    GlobalVariable *GV = dyn_cast<GlobalVariable>(LI->getPointerOperand());
1554263508Sdim    if (!GV || !GV->isDeclaration())
1555263508Sdim      return false;
1556263508Sdim    return GV->getName() == "stderr";
1557263508Sdim  }
1558263508Sdim
1559263508Sdim  int StreamArg;
1560263508Sdim};
1561263508Sdim
1562249423Sdimstruct PrintFOpt : public LibCallOptimization {
1563249423Sdim  Value *optimizeFixedFormatString(Function *Callee, CallInst *CI,
1564249423Sdim                                   IRBuilder<> &B) {
1565249423Sdim    // Check for a fixed format string.
1566249423Sdim    StringRef FormatStr;
1567249423Sdim    if (!getConstantStringInfo(CI->getArgOperand(0), FormatStr))
1568249423Sdim      return 0;
1569249423Sdim
1570249423Sdim    // Empty format string -> noop.
1571249423Sdim    if (FormatStr.empty())  // Tolerate printf's declared void.
1572249423Sdim      return CI->use_empty() ? (Value*)CI :
1573249423Sdim                               ConstantInt::get(CI->getType(), 0);
1574249423Sdim
1575249423Sdim    // Do not do any of the following transformations if the printf return value
1576249423Sdim    // is used, in general the printf return value is not compatible with either
1577249423Sdim    // putchar() or puts().
1578249423Sdim    if (!CI->use_empty())
1579249423Sdim      return 0;
1580249423Sdim
1581249423Sdim    // printf("x") -> putchar('x'), even for '%'.
1582249423Sdim    if (FormatStr.size() == 1) {
1583249423Sdim      Value *Res = EmitPutChar(B.getInt32(FormatStr[0]), B, TD, TLI);
1584249423Sdim      if (CI->use_empty() || !Res) return Res;
1585249423Sdim      return B.CreateIntCast(Res, CI->getType(), true);
1586249423Sdim    }
1587249423Sdim
1588249423Sdim    // printf("foo\n") --> puts("foo")
1589249423Sdim    if (FormatStr[FormatStr.size()-1] == '\n' &&
1590263508Sdim        FormatStr.find('%') == StringRef::npos) { // No format characters.
1591249423Sdim      // Create a string literal with no \n on it.  We expect the constant merge
1592249423Sdim      // pass to be run after this pass, to merge duplicate strings.
1593249423Sdim      FormatStr = FormatStr.drop_back();
1594249423Sdim      Value *GV = B.CreateGlobalString(FormatStr, "str");
1595249423Sdim      Value *NewCI = EmitPutS(GV, B, TD, TLI);
1596249423Sdim      return (CI->use_empty() || !NewCI) ?
1597249423Sdim              NewCI :
1598249423Sdim              ConstantInt::get(CI->getType(), FormatStr.size()+1);
1599249423Sdim    }
1600249423Sdim
1601249423Sdim    // Optimize specific format strings.
1602249423Sdim    // printf("%c", chr) --> putchar(chr)
1603249423Sdim    if (FormatStr == "%c" && CI->getNumArgOperands() > 1 &&
1604249423Sdim        CI->getArgOperand(1)->getType()->isIntegerTy()) {
1605249423Sdim      Value *Res = EmitPutChar(CI->getArgOperand(1), B, TD, TLI);
1606249423Sdim
1607249423Sdim      if (CI->use_empty() || !Res) return Res;
1608249423Sdim      return B.CreateIntCast(Res, CI->getType(), true);
1609249423Sdim    }
1610249423Sdim
1611249423Sdim    // printf("%s\n", str) --> puts(str)
1612249423Sdim    if (FormatStr == "%s\n" && CI->getNumArgOperands() > 1 &&
1613249423Sdim        CI->getArgOperand(1)->getType()->isPointerTy()) {
1614249423Sdim      return EmitPutS(CI->getArgOperand(1), B, TD, TLI);
1615249423Sdim    }
1616249423Sdim    return 0;
1617249423Sdim  }
1618249423Sdim
1619249423Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1620249423Sdim    // Require one fixed pointer argument and an integer/void result.
1621249423Sdim    FunctionType *FT = Callee->getFunctionType();
1622249423Sdim    if (FT->getNumParams() < 1 || !FT->getParamType(0)->isPointerTy() ||
1623249423Sdim        !(FT->getReturnType()->isIntegerTy() ||
1624249423Sdim          FT->getReturnType()->isVoidTy()))
1625249423Sdim      return 0;
1626249423Sdim
1627249423Sdim    if (Value *V = optimizeFixedFormatString(Callee, CI, B)) {
1628249423Sdim      return V;
1629249423Sdim    }
1630249423Sdim
1631249423Sdim    // printf(format, ...) -> iprintf(format, ...) if no floating point
1632249423Sdim    // arguments.
1633249423Sdim    if (TLI->has(LibFunc::iprintf) && !callHasFloatingPointArgument(CI)) {
1634249423Sdim      Module *M = B.GetInsertBlock()->getParent()->getParent();
1635249423Sdim      Constant *IPrintFFn =
1636249423Sdim        M->getOrInsertFunction("iprintf", FT, Callee->getAttributes());
1637249423Sdim      CallInst *New = cast<CallInst>(CI->clone());
1638249423Sdim      New->setCalledFunction(IPrintFFn);
1639249423Sdim      B.Insert(New);
1640249423Sdim      return New;
1641249423Sdim    }
1642249423Sdim    return 0;
1643249423Sdim  }
1644249423Sdim};
1645249423Sdim
1646249423Sdimstruct SPrintFOpt : public LibCallOptimization {
1647249423Sdim  Value *OptimizeFixedFormatString(Function *Callee, CallInst *CI,
1648249423Sdim                                   IRBuilder<> &B) {
1649249423Sdim    // Check for a fixed format string.
1650249423Sdim    StringRef FormatStr;
1651249423Sdim    if (!getConstantStringInfo(CI->getArgOperand(1), FormatStr))
1652249423Sdim      return 0;
1653249423Sdim
1654249423Sdim    // If we just have a format string (nothing else crazy) transform it.
1655249423Sdim    if (CI->getNumArgOperands() == 2) {
1656249423Sdim      // Make sure there's no % in the constant array.  We could try to handle
1657249423Sdim      // %% -> % in the future if we cared.
1658249423Sdim      for (unsigned i = 0, e = FormatStr.size(); i != e; ++i)
1659249423Sdim        if (FormatStr[i] == '%')
1660249423Sdim          return 0; // we found a format specifier, bail out.
1661249423Sdim
1662249423Sdim      // These optimizations require DataLayout.
1663249423Sdim      if (!TD) return 0;
1664249423Sdim
1665249423Sdim      // sprintf(str, fmt) -> llvm.memcpy(str, fmt, strlen(fmt)+1, 1)
1666249423Sdim      B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
1667249423Sdim                     ConstantInt::get(TD->getIntPtrType(*Context), // Copy the
1668249423Sdim                                      FormatStr.size() + 1), 1);   // nul byte.
1669249423Sdim      return ConstantInt::get(CI->getType(), FormatStr.size());
1670249423Sdim    }
1671249423Sdim
1672249423Sdim    // The remaining optimizations require the format string to be "%s" or "%c"
1673249423Sdim    // and have an extra operand.
1674249423Sdim    if (FormatStr.size() != 2 || FormatStr[0] != '%' ||
1675249423Sdim        CI->getNumArgOperands() < 3)
1676249423Sdim      return 0;
1677249423Sdim
1678249423Sdim    // Decode the second character of the format string.
1679249423Sdim    if (FormatStr[1] == 'c') {
1680249423Sdim      // sprintf(dst, "%c", chr) --> *(i8*)dst = chr; *((i8*)dst+1) = 0
1681249423Sdim      if (!CI->getArgOperand(2)->getType()->isIntegerTy()) return 0;
1682249423Sdim      Value *V = B.CreateTrunc(CI->getArgOperand(2), B.getInt8Ty(), "char");
1683249423Sdim      Value *Ptr = CastToCStr(CI->getArgOperand(0), B);
1684249423Sdim      B.CreateStore(V, Ptr);
1685249423Sdim      Ptr = B.CreateGEP(Ptr, B.getInt32(1), "nul");
1686249423Sdim      B.CreateStore(B.getInt8(0), Ptr);
1687249423Sdim
1688249423Sdim      return ConstantInt::get(CI->getType(), 1);
1689249423Sdim    }
1690249423Sdim
1691249423Sdim    if (FormatStr[1] == 's') {
1692249423Sdim      // These optimizations require DataLayout.
1693249423Sdim      if (!TD) return 0;
1694249423Sdim
1695249423Sdim      // sprintf(dest, "%s", str) -> llvm.memcpy(dest, str, strlen(str)+1, 1)
1696249423Sdim      if (!CI->getArgOperand(2)->getType()->isPointerTy()) return 0;
1697249423Sdim
1698249423Sdim      Value *Len = EmitStrLen(CI->getArgOperand(2), B, TD, TLI);
1699249423Sdim      if (!Len)
1700249423Sdim        return 0;
1701249423Sdim      Value *IncLen = B.CreateAdd(Len,
1702249423Sdim                                  ConstantInt::get(Len->getType(), 1),
1703249423Sdim                                  "leninc");
1704249423Sdim      B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(2), IncLen, 1);
1705249423Sdim
1706249423Sdim      // The sprintf result is the unincremented number of bytes in the string.
1707249423Sdim      return B.CreateIntCast(Len, CI->getType(), false);
1708249423Sdim    }
1709249423Sdim    return 0;
1710249423Sdim  }
1711249423Sdim
1712249423Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1713249423Sdim    // Require two fixed pointer arguments and an integer result.
1714249423Sdim    FunctionType *FT = Callee->getFunctionType();
1715249423Sdim    if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() ||
1716249423Sdim        !FT->getParamType(1)->isPointerTy() ||
1717249423Sdim        !FT->getReturnType()->isIntegerTy())
1718249423Sdim      return 0;
1719249423Sdim
1720249423Sdim    if (Value *V = OptimizeFixedFormatString(Callee, CI, B)) {
1721249423Sdim      return V;
1722249423Sdim    }
1723249423Sdim
1724249423Sdim    // sprintf(str, format, ...) -> siprintf(str, format, ...) if no floating
1725249423Sdim    // point arguments.
1726249423Sdim    if (TLI->has(LibFunc::siprintf) && !callHasFloatingPointArgument(CI)) {
1727249423Sdim      Module *M = B.GetInsertBlock()->getParent()->getParent();
1728249423Sdim      Constant *SIPrintFFn =
1729249423Sdim        M->getOrInsertFunction("siprintf", FT, Callee->getAttributes());
1730249423Sdim      CallInst *New = cast<CallInst>(CI->clone());
1731249423Sdim      New->setCalledFunction(SIPrintFFn);
1732249423Sdim      B.Insert(New);
1733249423Sdim      return New;
1734249423Sdim    }
1735249423Sdim    return 0;
1736249423Sdim  }
1737249423Sdim};
1738249423Sdim
1739249423Sdimstruct FPrintFOpt : public LibCallOptimization {
1740249423Sdim  Value *optimizeFixedFormatString(Function *Callee, CallInst *CI,
1741249423Sdim                                   IRBuilder<> &B) {
1742263508Sdim    ErrorReportingOpt ER(/* StreamArg = */ 0);
1743263508Sdim    (void) ER.callOptimizer(Callee, CI, B);
1744263508Sdim
1745249423Sdim    // All the optimizations depend on the format string.
1746249423Sdim    StringRef FormatStr;
1747249423Sdim    if (!getConstantStringInfo(CI->getArgOperand(1), FormatStr))
1748249423Sdim      return 0;
1749249423Sdim
1750251662Sdim    // Do not do any of the following transformations if the fprintf return
1751251662Sdim    // value is used, in general the fprintf return value is not compatible
1752251662Sdim    // with fwrite(), fputc() or fputs().
1753251662Sdim    if (!CI->use_empty())
1754251662Sdim      return 0;
1755251662Sdim
1756249423Sdim    // fprintf(F, "foo") --> fwrite("foo", 3, 1, F)
1757249423Sdim    if (CI->getNumArgOperands() == 2) {
1758249423Sdim      for (unsigned i = 0, e = FormatStr.size(); i != e; ++i)
1759249423Sdim        if (FormatStr[i] == '%')  // Could handle %% -> % if we cared.
1760249423Sdim          return 0; // We found a format specifier.
1761249423Sdim
1762249423Sdim      // These optimizations require DataLayout.
1763249423Sdim      if (!TD) return 0;
1764249423Sdim
1765251662Sdim      return EmitFWrite(CI->getArgOperand(1),
1766251662Sdim                        ConstantInt::get(TD->getIntPtrType(*Context),
1767251662Sdim                                         FormatStr.size()),
1768251662Sdim                        CI->getArgOperand(0), B, TD, TLI);
1769249423Sdim    }
1770249423Sdim
1771249423Sdim    // The remaining optimizations require the format string to be "%s" or "%c"
1772249423Sdim    // and have an extra operand.
1773249423Sdim    if (FormatStr.size() != 2 || FormatStr[0] != '%' ||
1774249423Sdim        CI->getNumArgOperands() < 3)
1775249423Sdim      return 0;
1776249423Sdim
1777249423Sdim    // Decode the second character of the format string.
1778249423Sdim    if (FormatStr[1] == 'c') {
1779249423Sdim      // fprintf(F, "%c", chr) --> fputc(chr, F)
1780249423Sdim      if (!CI->getArgOperand(2)->getType()->isIntegerTy()) return 0;
1781251662Sdim      return EmitFPutC(CI->getArgOperand(2), CI->getArgOperand(0), B, TD, TLI);
1782249423Sdim    }
1783249423Sdim
1784249423Sdim    if (FormatStr[1] == 's') {
1785249423Sdim      // fprintf(F, "%s", str) --> fputs(str, F)
1786251662Sdim      if (!CI->getArgOperand(2)->getType()->isPointerTy())
1787249423Sdim        return 0;
1788249423Sdim      return EmitFPutS(CI->getArgOperand(2), CI->getArgOperand(0), B, TD, TLI);
1789249423Sdim    }
1790249423Sdim    return 0;
1791249423Sdim  }
1792249423Sdim
1793249423Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1794249423Sdim    // Require two fixed paramters as pointers and integer result.
1795249423Sdim    FunctionType *FT = Callee->getFunctionType();
1796249423Sdim    if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() ||
1797249423Sdim        !FT->getParamType(1)->isPointerTy() ||
1798249423Sdim        !FT->getReturnType()->isIntegerTy())
1799249423Sdim      return 0;
1800249423Sdim
1801249423Sdim    if (Value *V = optimizeFixedFormatString(Callee, CI, B)) {
1802249423Sdim      return V;
1803249423Sdim    }
1804249423Sdim
1805249423Sdim    // fprintf(stream, format, ...) -> fiprintf(stream, format, ...) if no
1806249423Sdim    // floating point arguments.
1807249423Sdim    if (TLI->has(LibFunc::fiprintf) && !callHasFloatingPointArgument(CI)) {
1808249423Sdim      Module *M = B.GetInsertBlock()->getParent()->getParent();
1809249423Sdim      Constant *FIPrintFFn =
1810249423Sdim        M->getOrInsertFunction("fiprintf", FT, Callee->getAttributes());
1811249423Sdim      CallInst *New = cast<CallInst>(CI->clone());
1812249423Sdim      New->setCalledFunction(FIPrintFFn);
1813249423Sdim      B.Insert(New);
1814249423Sdim      return New;
1815249423Sdim    }
1816249423Sdim    return 0;
1817249423Sdim  }
1818249423Sdim};
1819249423Sdim
1820249423Sdimstruct FWriteOpt : public LibCallOptimization {
1821249423Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1822263508Sdim    ErrorReportingOpt ER(/* StreamArg = */ 3);
1823263508Sdim    (void) ER.callOptimizer(Callee, CI, B);
1824263508Sdim
1825249423Sdim    // Require a pointer, an integer, an integer, a pointer, returning integer.
1826249423Sdim    FunctionType *FT = Callee->getFunctionType();
1827249423Sdim    if (FT->getNumParams() != 4 || !FT->getParamType(0)->isPointerTy() ||
1828249423Sdim        !FT->getParamType(1)->isIntegerTy() ||
1829249423Sdim        !FT->getParamType(2)->isIntegerTy() ||
1830249423Sdim        !FT->getParamType(3)->isPointerTy() ||
1831249423Sdim        !FT->getReturnType()->isIntegerTy())
1832249423Sdim      return 0;
1833249423Sdim
1834249423Sdim    // Get the element size and count.
1835249423Sdim    ConstantInt *SizeC = dyn_cast<ConstantInt>(CI->getArgOperand(1));
1836249423Sdim    ConstantInt *CountC = dyn_cast<ConstantInt>(CI->getArgOperand(2));
1837249423Sdim    if (!SizeC || !CountC) return 0;
1838249423Sdim    uint64_t Bytes = SizeC->getZExtValue()*CountC->getZExtValue();
1839249423Sdim
1840249423Sdim    // If this is writing zero records, remove the call (it's a noop).
1841249423Sdim    if (Bytes == 0)
1842249423Sdim      return ConstantInt::get(CI->getType(), 0);
1843249423Sdim
1844249423Sdim    // If this is writing one byte, turn it into fputc.
1845249423Sdim    // This optimisation is only valid, if the return value is unused.
1846249423Sdim    if (Bytes == 1 && CI->use_empty()) {  // fwrite(S,1,1,F) -> fputc(S[0],F)
1847249423Sdim      Value *Char = B.CreateLoad(CastToCStr(CI->getArgOperand(0), B), "char");
1848249423Sdim      Value *NewCI = EmitFPutC(Char, CI->getArgOperand(3), B, TD, TLI);
1849249423Sdim      return NewCI ? ConstantInt::get(CI->getType(), 1) : 0;
1850249423Sdim    }
1851249423Sdim
1852249423Sdim    return 0;
1853249423Sdim  }
1854249423Sdim};
1855249423Sdim
1856249423Sdimstruct FPutsOpt : public LibCallOptimization {
1857249423Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1858263508Sdim    ErrorReportingOpt ER(/* StreamArg = */ 1);
1859263508Sdim    (void) ER.callOptimizer(Callee, CI, B);
1860263508Sdim
1861249423Sdim    // These optimizations require DataLayout.
1862249423Sdim    if (!TD) return 0;
1863249423Sdim
1864249423Sdim    // Require two pointers.  Also, we can't optimize if return value is used.
1865249423Sdim    FunctionType *FT = Callee->getFunctionType();
1866249423Sdim    if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() ||
1867249423Sdim        !FT->getParamType(1)->isPointerTy() ||
1868249423Sdim        !CI->use_empty())
1869249423Sdim      return 0;
1870249423Sdim
1871249423Sdim    // fputs(s,F) --> fwrite(s,1,strlen(s),F)
1872249423Sdim    uint64_t Len = GetStringLength(CI->getArgOperand(0));
1873249423Sdim    if (!Len) return 0;
1874249423Sdim    // Known to have no uses (see above).
1875249423Sdim    return EmitFWrite(CI->getArgOperand(0),
1876249423Sdim                      ConstantInt::get(TD->getIntPtrType(*Context), Len-1),
1877249423Sdim                      CI->getArgOperand(1), B, TD, TLI);
1878249423Sdim  }
1879249423Sdim};
1880249423Sdim
1881249423Sdimstruct PutsOpt : public LibCallOptimization {
1882249423Sdim  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1883249423Sdim    // Require one fixed pointer argument and an integer/void result.
1884249423Sdim    FunctionType *FT = Callee->getFunctionType();
1885249423Sdim    if (FT->getNumParams() < 1 || !FT->getParamType(0)->isPointerTy() ||
1886249423Sdim        !(FT->getReturnType()->isIntegerTy() ||
1887249423Sdim          FT->getReturnType()->isVoidTy()))
1888249423Sdim      return 0;
1889249423Sdim
1890249423Sdim    // Check for a constant string.
1891249423Sdim    StringRef Str;
1892249423Sdim    if (!getConstantStringInfo(CI->getArgOperand(0), Str))
1893249423Sdim      return 0;
1894249423Sdim
1895249423Sdim    if (Str.empty() && CI->use_empty()) {
1896249423Sdim      // puts("") -> putchar('\n')
1897249423Sdim      Value *Res = EmitPutChar(B.getInt32('\n'), B, TD, TLI);
1898249423Sdim      if (CI->use_empty() || !Res) return Res;
1899249423Sdim      return B.CreateIntCast(Res, CI->getType(), true);
1900249423Sdim    }
1901249423Sdim
1902249423Sdim    return 0;
1903249423Sdim  }
1904249423Sdim};
1905249423Sdim
1906243789Sdim} // End anonymous namespace.
1907243789Sdim
1908243789Sdimnamespace llvm {
1909243789Sdim
1910243789Sdimclass LibCallSimplifierImpl {
1911243789Sdim  const DataLayout *TD;
1912243789Sdim  const TargetLibraryInfo *TLI;
1913243789Sdim  const LibCallSimplifier *LCS;
1914249423Sdim  bool UnsafeFPShrink;
1915243789Sdim
1916249423Sdim  // Math library call optimizations.
1917249423Sdim  CosOpt Cos;
1918249423Sdim  PowOpt Pow;
1919249423Sdim  Exp2Opt Exp2;
1920243789Sdimpublic:
1921243789Sdim  LibCallSimplifierImpl(const DataLayout *TD, const TargetLibraryInfo *TLI,
1922249423Sdim                        const LibCallSimplifier *LCS,
1923249423Sdim                        bool UnsafeFPShrink = false)
1924249423Sdim    : Cos(UnsafeFPShrink), Pow(UnsafeFPShrink), Exp2(UnsafeFPShrink) {
1925243789Sdim    this->TD = TD;
1926243789Sdim    this->TLI = TLI;
1927243789Sdim    this->LCS = LCS;
1928249423Sdim    this->UnsafeFPShrink = UnsafeFPShrink;
1929243789Sdim  }
1930243789Sdim
1931243789Sdim  Value *optimizeCall(CallInst *CI);
1932249423Sdim  LibCallOptimization *lookupOptimization(CallInst *CI);
1933249423Sdim  bool hasFloatVersion(StringRef FuncName);
1934243789Sdim};
1935243789Sdim
1936249423Sdimbool LibCallSimplifierImpl::hasFloatVersion(StringRef FuncName) {
1937249423Sdim  LibFunc::Func Func;
1938249423Sdim  SmallString<20> FloatFuncName = FuncName;
1939249423Sdim  FloatFuncName += 'f';
1940249423Sdim  if (TLI->getLibFunc(FloatFuncName, Func))
1941249423Sdim    return TLI->has(Func);
1942249423Sdim  return false;
1943249423Sdim}
1944243789Sdim
1945249423Sdim// Fortified library call optimizations.
1946249423Sdimstatic MemCpyChkOpt MemCpyChk;
1947249423Sdimstatic MemMoveChkOpt MemMoveChk;
1948249423Sdimstatic MemSetChkOpt MemSetChk;
1949249423Sdimstatic StrCpyChkOpt StrCpyChk;
1950249423Sdimstatic StpCpyChkOpt StpCpyChk;
1951249423Sdimstatic StrNCpyChkOpt StrNCpyChk;
1952243789Sdim
1953249423Sdim// String library call optimizations.
1954249423Sdimstatic StrCatOpt StrCat;
1955249423Sdimstatic StrNCatOpt StrNCat;
1956249423Sdimstatic StrChrOpt StrChr;
1957249423Sdimstatic StrRChrOpt StrRChr;
1958249423Sdimstatic StrCmpOpt StrCmp;
1959249423Sdimstatic StrNCmpOpt StrNCmp;
1960249423Sdimstatic StrCpyOpt StrCpy;
1961249423Sdimstatic StpCpyOpt StpCpy;
1962249423Sdimstatic StrNCpyOpt StrNCpy;
1963249423Sdimstatic StrLenOpt StrLen;
1964249423Sdimstatic StrPBrkOpt StrPBrk;
1965249423Sdimstatic StrToOpt StrTo;
1966249423Sdimstatic StrSpnOpt StrSpn;
1967249423Sdimstatic StrCSpnOpt StrCSpn;
1968249423Sdimstatic StrStrOpt StrStr;
1969249423Sdim
1970249423Sdim// Memory library call optimizations.
1971249423Sdimstatic MemCmpOpt MemCmp;
1972249423Sdimstatic MemCpyOpt MemCpy;
1973249423Sdimstatic MemMoveOpt MemMove;
1974249423Sdimstatic MemSetOpt MemSet;
1975249423Sdim
1976249423Sdim// Math library call optimizations.
1977249423Sdimstatic UnaryDoubleFPOpt UnaryDoubleFP(false);
1978249423Sdimstatic UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true);
1979263508Sdimstatic SinCosPiOpt SinCosPi;
1980249423Sdim
1981249423Sdim  // Integer library call optimizations.
1982249423Sdimstatic FFSOpt FFS;
1983249423Sdimstatic AbsOpt Abs;
1984249423Sdimstatic IsDigitOpt IsDigit;
1985249423Sdimstatic IsAsciiOpt IsAscii;
1986249423Sdimstatic ToAsciiOpt ToAscii;
1987249423Sdim
1988249423Sdim// Formatting and IO library call optimizations.
1989263508Sdimstatic ErrorReportingOpt ErrorReporting;
1990263508Sdimstatic ErrorReportingOpt ErrorReporting0(0);
1991263508Sdimstatic ErrorReportingOpt ErrorReporting1(1);
1992249423Sdimstatic PrintFOpt PrintF;
1993249423Sdimstatic SPrintFOpt SPrintF;
1994249423Sdimstatic FPrintFOpt FPrintF;
1995249423Sdimstatic FWriteOpt FWrite;
1996249423Sdimstatic FPutsOpt FPuts;
1997249423Sdimstatic PutsOpt Puts;
1998249423Sdim
1999249423SdimLibCallOptimization *LibCallSimplifierImpl::lookupOptimization(CallInst *CI) {
2000249423Sdim  LibFunc::Func Func;
2001249423Sdim  Function *Callee = CI->getCalledFunction();
2002249423Sdim  StringRef FuncName = Callee->getName();
2003249423Sdim
2004249423Sdim  // Next check for intrinsics.
2005249423Sdim  if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) {
2006249423Sdim    switch (II->getIntrinsicID()) {
2007249423Sdim    case Intrinsic::pow:
2008249423Sdim       return &Pow;
2009249423Sdim    case Intrinsic::exp2:
2010249423Sdim       return &Exp2;
2011249423Sdim    default:
2012249423Sdim       return 0;
2013249423Sdim    }
2014249423Sdim  }
2015249423Sdim
2016249423Sdim  // Then check for known library functions.
2017249423Sdim  if (TLI->getLibFunc(FuncName, Func) && TLI->has(Func)) {
2018249423Sdim    switch (Func) {
2019249423Sdim      case LibFunc::strcat:
2020249423Sdim        return &StrCat;
2021249423Sdim      case LibFunc::strncat:
2022249423Sdim        return &StrNCat;
2023249423Sdim      case LibFunc::strchr:
2024249423Sdim        return &StrChr;
2025249423Sdim      case LibFunc::strrchr:
2026249423Sdim        return &StrRChr;
2027249423Sdim      case LibFunc::strcmp:
2028249423Sdim        return &StrCmp;
2029249423Sdim      case LibFunc::strncmp:
2030249423Sdim        return &StrNCmp;
2031249423Sdim      case LibFunc::strcpy:
2032249423Sdim        return &StrCpy;
2033249423Sdim      case LibFunc::stpcpy:
2034249423Sdim        return &StpCpy;
2035249423Sdim      case LibFunc::strncpy:
2036249423Sdim        return &StrNCpy;
2037249423Sdim      case LibFunc::strlen:
2038249423Sdim        return &StrLen;
2039249423Sdim      case LibFunc::strpbrk:
2040249423Sdim        return &StrPBrk;
2041249423Sdim      case LibFunc::strtol:
2042249423Sdim      case LibFunc::strtod:
2043249423Sdim      case LibFunc::strtof:
2044249423Sdim      case LibFunc::strtoul:
2045249423Sdim      case LibFunc::strtoll:
2046249423Sdim      case LibFunc::strtold:
2047249423Sdim      case LibFunc::strtoull:
2048249423Sdim        return &StrTo;
2049249423Sdim      case LibFunc::strspn:
2050249423Sdim        return &StrSpn;
2051249423Sdim      case LibFunc::strcspn:
2052249423Sdim        return &StrCSpn;
2053249423Sdim      case LibFunc::strstr:
2054249423Sdim        return &StrStr;
2055249423Sdim      case LibFunc::memcmp:
2056249423Sdim        return &MemCmp;
2057249423Sdim      case LibFunc::memcpy:
2058249423Sdim        return &MemCpy;
2059249423Sdim      case LibFunc::memmove:
2060249423Sdim        return &MemMove;
2061249423Sdim      case LibFunc::memset:
2062249423Sdim        return &MemSet;
2063249423Sdim      case LibFunc::cosf:
2064249423Sdim      case LibFunc::cos:
2065249423Sdim      case LibFunc::cosl:
2066249423Sdim        return &Cos;
2067263508Sdim      case LibFunc::sinpif:
2068263508Sdim      case LibFunc::sinpi:
2069263508Sdim      case LibFunc::cospif:
2070263508Sdim      case LibFunc::cospi:
2071263508Sdim        return &SinCosPi;
2072249423Sdim      case LibFunc::powf:
2073249423Sdim      case LibFunc::pow:
2074249423Sdim      case LibFunc::powl:
2075249423Sdim        return &Pow;
2076249423Sdim      case LibFunc::exp2l:
2077249423Sdim      case LibFunc::exp2:
2078249423Sdim      case LibFunc::exp2f:
2079249423Sdim        return &Exp2;
2080249423Sdim      case LibFunc::ffs:
2081249423Sdim      case LibFunc::ffsl:
2082249423Sdim      case LibFunc::ffsll:
2083249423Sdim        return &FFS;
2084249423Sdim      case LibFunc::abs:
2085249423Sdim      case LibFunc::labs:
2086249423Sdim      case LibFunc::llabs:
2087249423Sdim        return &Abs;
2088249423Sdim      case LibFunc::isdigit:
2089249423Sdim        return &IsDigit;
2090249423Sdim      case LibFunc::isascii:
2091249423Sdim        return &IsAscii;
2092249423Sdim      case LibFunc::toascii:
2093249423Sdim        return &ToAscii;
2094249423Sdim      case LibFunc::printf:
2095249423Sdim        return &PrintF;
2096249423Sdim      case LibFunc::sprintf:
2097249423Sdim        return &SPrintF;
2098249423Sdim      case LibFunc::fprintf:
2099249423Sdim        return &FPrintF;
2100249423Sdim      case LibFunc::fwrite:
2101249423Sdim        return &FWrite;
2102249423Sdim      case LibFunc::fputs:
2103249423Sdim        return &FPuts;
2104249423Sdim      case LibFunc::puts:
2105249423Sdim        return &Puts;
2106263508Sdim      case LibFunc::perror:
2107263508Sdim        return &ErrorReporting;
2108263508Sdim      case LibFunc::vfprintf:
2109263508Sdim      case LibFunc::fiprintf:
2110263508Sdim        return &ErrorReporting0;
2111263508Sdim      case LibFunc::fputc:
2112263508Sdim        return &ErrorReporting1;
2113249423Sdim      case LibFunc::ceil:
2114249423Sdim      case LibFunc::fabs:
2115249423Sdim      case LibFunc::floor:
2116249423Sdim      case LibFunc::rint:
2117249423Sdim      case LibFunc::round:
2118249423Sdim      case LibFunc::nearbyint:
2119249423Sdim      case LibFunc::trunc:
2120249423Sdim        if (hasFloatVersion(FuncName))
2121249423Sdim          return &UnaryDoubleFP;
2122249423Sdim        return 0;
2123249423Sdim      case LibFunc::acos:
2124249423Sdim      case LibFunc::acosh:
2125249423Sdim      case LibFunc::asin:
2126249423Sdim      case LibFunc::asinh:
2127249423Sdim      case LibFunc::atan:
2128249423Sdim      case LibFunc::atanh:
2129249423Sdim      case LibFunc::cbrt:
2130249423Sdim      case LibFunc::cosh:
2131249423Sdim      case LibFunc::exp:
2132249423Sdim      case LibFunc::exp10:
2133249423Sdim      case LibFunc::expm1:
2134249423Sdim      case LibFunc::log:
2135249423Sdim      case LibFunc::log10:
2136249423Sdim      case LibFunc::log1p:
2137249423Sdim      case LibFunc::log2:
2138249423Sdim      case LibFunc::logb:
2139249423Sdim      case LibFunc::sin:
2140249423Sdim      case LibFunc::sinh:
2141249423Sdim      case LibFunc::sqrt:
2142249423Sdim      case LibFunc::tan:
2143249423Sdim      case LibFunc::tanh:
2144249423Sdim        if (UnsafeFPShrink && hasFloatVersion(FuncName))
2145249423Sdim         return &UnsafeUnaryDoubleFP;
2146249423Sdim        return 0;
2147249423Sdim      case LibFunc::memcpy_chk:
2148249423Sdim        return &MemCpyChk;
2149249423Sdim      default:
2150249423Sdim        return 0;
2151249423Sdim      }
2152249423Sdim  }
2153249423Sdim
2154249423Sdim  // Finally check for fortified library calls.
2155249423Sdim  if (FuncName.endswith("_chk")) {
2156249423Sdim    if (FuncName == "__memmove_chk")
2157249423Sdim      return &MemMoveChk;
2158249423Sdim    else if (FuncName == "__memset_chk")
2159249423Sdim      return &MemSetChk;
2160249423Sdim    else if (FuncName == "__strcpy_chk")
2161249423Sdim      return &StrCpyChk;
2162249423Sdim    else if (FuncName == "__stpcpy_chk")
2163249423Sdim      return &StpCpyChk;
2164249423Sdim    else if (FuncName == "__strncpy_chk")
2165249423Sdim      return &StrNCpyChk;
2166249423Sdim    else if (FuncName == "__stpncpy_chk")
2167249423Sdim      return &StrNCpyChk;
2168249423Sdim  }
2169249423Sdim
2170249423Sdim  return 0;
2171249423Sdim
2172243789Sdim}
2173243789Sdim
2174243789SdimValue *LibCallSimplifierImpl::optimizeCall(CallInst *CI) {
2175249423Sdim  LibCallOptimization *LCO = lookupOptimization(CI);
2176243789Sdim  if (LCO) {
2177243789Sdim    IRBuilder<> Builder(CI);
2178243789Sdim    return LCO->optimizeCall(CI, TD, TLI, LCS, Builder);
2179243789Sdim  }
2180243789Sdim  return 0;
2181243789Sdim}
2182243789Sdim
2183243789SdimLibCallSimplifier::LibCallSimplifier(const DataLayout *TD,
2184249423Sdim                                     const TargetLibraryInfo *TLI,
2185249423Sdim                                     bool UnsafeFPShrink) {
2186249423Sdim  Impl = new LibCallSimplifierImpl(TD, TLI, this, UnsafeFPShrink);
2187243789Sdim}
2188243789Sdim
2189243789SdimLibCallSimplifier::~LibCallSimplifier() {
2190243789Sdim  delete Impl;
2191243789Sdim}
2192243789Sdim
2193243789SdimValue *LibCallSimplifier::optimizeCall(CallInst *CI) {
2194263508Sdim  if (CI->isNoBuiltin()) return 0;
2195243789Sdim  return Impl->optimizeCall(CI);
2196243789Sdim}
2197243789Sdim
2198243789Sdimvoid LibCallSimplifier::replaceAllUsesWith(Instruction *I, Value *With) const {
2199243789Sdim  I->replaceAllUsesWith(With);
2200243789Sdim  I->eraseFromParent();
2201243789Sdim}
2202243789Sdim
2203243789Sdim}
2204263508Sdim
2205263508Sdim// TODO:
2206263508Sdim//   Additional cases that we need to add to this file:
2207263508Sdim//
2208263508Sdim// cbrt:
2209263508Sdim//   * cbrt(expN(X))  -> expN(x/3)
2210263508Sdim//   * cbrt(sqrt(x))  -> pow(x,1/6)
2211263508Sdim//   * cbrt(sqrt(x))  -> pow(x,1/9)
2212263508Sdim//
2213263508Sdim// exp, expf, expl:
2214263508Sdim//   * exp(log(x))  -> x
2215263508Sdim//
2216263508Sdim// log, logf, logl:
2217263508Sdim//   * log(exp(x))   -> x
2218263508Sdim//   * log(x**y)     -> y*log(x)
2219263508Sdim//   * log(exp(y))   -> y*log(e)
2220263508Sdim//   * log(exp2(y))  -> y*log(2)
2221263508Sdim//   * log(exp10(y)) -> y*log(10)
2222263508Sdim//   * log(sqrt(x))  -> 0.5*log(x)
2223263508Sdim//   * log(pow(x,y)) -> y*log(x)
2224263508Sdim//
2225263508Sdim// lround, lroundf, lroundl:
2226263508Sdim//   * lround(cnst) -> cnst'
2227263508Sdim//
2228263508Sdim// pow, powf, powl:
2229263508Sdim//   * pow(exp(x),y)  -> exp(x*y)
2230263508Sdim//   * pow(sqrt(x),y) -> pow(x,y*0.5)
2231263508Sdim//   * pow(pow(x,y),z)-> pow(x,y*z)
2232263508Sdim//
2233263508Sdim// round, roundf, roundl:
2234263508Sdim//   * round(cnst) -> cnst'
2235263508Sdim//
2236263508Sdim// signbit:
2237263508Sdim//   * signbit(cnst) -> cnst'
2238263508Sdim//   * signbit(nncst) -> 0 (if pstv is a non-negative constant)
2239263508Sdim//
2240263508Sdim// sqrt, sqrtf, sqrtl:
2241263508Sdim//   * sqrt(expN(x))  -> expN(x*0.5)
2242263508Sdim//   * sqrt(Nroot(x)) -> pow(x,1/(2*N))
2243263508Sdim//   * sqrt(pow(x,y)) -> pow(|x|,y*0.5)
2244263508Sdim//
2245263508Sdim// strchr:
2246263508Sdim//   * strchr(p, 0) -> strlen(p)
2247263508Sdim// tan, tanf, tanl:
2248263508Sdim//   * tan(atan(x)) -> x
2249263508Sdim//
2250263508Sdim// trunc, truncf, truncl:
2251263508Sdim//   * trunc(cnst) -> cnst'
2252263508Sdim//
2253263508Sdim//
2254