15e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge//===------ SimplifyLibCalls.cpp - Library calls simplifier ---------------===//
25e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge//
35e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge//                     The LLVM Compiler Infrastructure
45e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge//
55e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge// This file is distributed under the University of Illinois Open Source
65e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge// License. See LICENSE.TXT for details.
75e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge//
85e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge//===----------------------------------------------------------------------===//
95e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge//
105e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge// This is a utility pass used for testing the InstructionSimplify analysis.
115e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge// The analysis is applied to every instruction, and if it simplifies then the
125e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge// instruction is replaced by the simplification.  If you are looking for a pass
135e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge// that performs serious instruction folding, use the instcombine pass instead.
145e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge//
155e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge//===----------------------------------------------------------------------===//
165e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
175e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge#include "llvm/Transforms/Utils/SimplifyLibCalls.h"
1867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge#include "llvm/ADT/SmallString.h"
195e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge#include "llvm/ADT/StringMap.h"
205e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge#include "llvm/Analysis/ValueTracking.h"
210b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h"
220b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
230b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IRBuilder.h"
2467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge#include "llvm/IR/IntrinsicInst.h"
250b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Intrinsics.h"
260b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h"
270b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h"
28f26b4f05b3fdd8618f75b8784388e8415a6eea0cNadav Rotem#include "llvm/Support/Allocator.h"
295e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge#include "llvm/Target/TargetLibraryInfo.h"
305e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge#include "llvm/Transforms/Utils/BuildLibCalls.h"
315e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
325e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingeusing namespace llvm;
335e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
345e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge/// This class is the abstract base class for the set of optimizations that
355e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge/// corresponds to one library call.
365e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingenamespace {
375e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingeclass LibCallOptimization {
385e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingeprotected:
395e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  Function *Caller;
405e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  const DataLayout *TD;
415e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  const TargetLibraryInfo *TLI;
42b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge  const LibCallSimplifier *LCS;
435e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  LLVMContext* Context;
445e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingepublic:
455e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  LibCallOptimization() { }
465e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  virtual ~LibCallOptimization() {}
475e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
485e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  /// callOptimizer - This pure virtual method is implemented by base classes to
495e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  /// do various optimizations.  If this returns null then no transformation was
505e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  /// performed.  If it returns CI, then it transformed the call and CI is to be
515e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  /// deleted.  If it returns something else, replace CI with the new value and
525e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  /// delete CI.
535e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B)
545e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    =0;
555e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
5633daeab1bb8df65273fd9ecbf1a261f96733732eChad Rosier  /// ignoreCallingConv - Returns false if this transformation could possibly
5733daeab1bb8df65273fd9ecbf1a261f96733732eChad Rosier  /// change the calling convention.
5833daeab1bb8df65273fd9ecbf1a261f96733732eChad Rosier  virtual bool ignoreCallingConv() { return false; }
5933daeab1bb8df65273fd9ecbf1a261f96733732eChad Rosier
605e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  Value *optimizeCall(CallInst *CI, const DataLayout *TD,
61b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge                      const TargetLibraryInfo *TLI,
62b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge                      const LibCallSimplifier *LCS, IRBuilder<> &B) {
635e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    Caller = CI->getParent()->getParent();
645e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    this->TD = TD;
655e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    this->TLI = TLI;
66b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge    this->LCS = LCS;
675e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    if (CI->getCalledFunction())
685e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      Context = &CI->getCalledFunction()->getContext();
695e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
705e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    // We never change the calling convention.
7133daeab1bb8df65273fd9ecbf1a261f96733732eChad Rosier    if (!ignoreCallingConv() && CI->getCallingConv() != llvm::CallingConv::C)
725e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      return NULL;
735e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
745e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    return callOptimizer(CI->getCalledFunction(), CI, B);
755e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  }
765e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge};
775e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
785e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge//===----------------------------------------------------------------------===//
7957cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge// Helper Functions
8057cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge//===----------------------------------------------------------------------===//
8157cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge
8257cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge/// isOnlyUsedInZeroEqualityComparison - Return true if it only matters that the
8357cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge/// value is equal or not-equal to zero.
8457cfd71f881ae381fa43667e003f595ffd70ea18Meador Ingestatic bool isOnlyUsedInZeroEqualityComparison(Value *V) {
8557cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge  for (Value::use_iterator UI = V->use_begin(), E = V->use_end();
8657cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge       UI != E; ++UI) {
8757cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge    if (ICmpInst *IC = dyn_cast<ICmpInst>(*UI))
8857cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge      if (IC->isEquality())
8957cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge        if (Constant *C = dyn_cast<Constant>(IC->getOperand(1)))
9057cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge          if (C->isNullValue())
9157cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge            continue;
9257cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge    // Unknown instruction.
9357cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge    return false;
9457cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge  }
9557cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge  return true;
9657cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge}
9757cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge
986e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge/// isOnlyUsedInEqualityComparison - Return true if it is only used in equality
996e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge/// comparisons with With.
1006e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Ingestatic bool isOnlyUsedInEqualityComparison(Value *V, Value *With) {
1016e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge  for (Value::use_iterator UI = V->use_begin(), E = V->use_end();
1026e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge       UI != E; ++UI) {
1036e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    if (ICmpInst *IC = dyn_cast<ICmpInst>(*UI))
1046e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge      if (IC->isEquality() && IC->getOperand(1) == With)
1056e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge        continue;
1066e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    // Unknown instruction.
1076e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    return false;
1086e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge  }
1096e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge  return true;
1106e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge}
1116e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge
112d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Ingestatic bool callHasFloatingPointArgument(const CallInst *CI) {
113d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge  for (CallInst::const_op_iterator it = CI->op_begin(), e = CI->op_end();
114d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge       it != e; ++it) {
115d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    if ((*it)->getType()->isFloatingPointTy())
116d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      return true;
117d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge  }
118d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge  return false;
119d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge}
120d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge
12157cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge//===----------------------------------------------------------------------===//
1225e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge// Fortified Library Call Optimizations
1235e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge//===----------------------------------------------------------------------===//
1245e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
1255e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingestruct FortifiedLibCallOptimization : public LibCallOptimization {
1265e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingeprotected:
1275e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  virtual bool isFoldable(unsigned SizeCIOp, unsigned SizeArgOp,
1285e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge			  bool isString) const = 0;
1295e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge};
1305e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
1315e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingestruct InstFortifiedLibCallOptimization : public FortifiedLibCallOptimization {
1325e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  CallInst *CI;
1335e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
1345e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  bool isFoldable(unsigned SizeCIOp, unsigned SizeArgOp, bool isString) const {
1355e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    if (CI->getArgOperand(SizeCIOp) == CI->getArgOperand(SizeArgOp))
1365e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      return true;
1375e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    if (ConstantInt *SizeCI =
1385e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge                           dyn_cast<ConstantInt>(CI->getArgOperand(SizeCIOp))) {
1395e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      if (SizeCI->isAllOnesValue())
1405e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge        return true;
1415e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      if (isString) {
1425e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge        uint64_t Len = GetStringLength(CI->getArgOperand(SizeArgOp));
1435e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge        // If the length is 0 we don't know how long it is and so we can't
1445e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge        // remove the check.
1455e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge        if (Len == 0) return false;
1465e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge        return SizeCI->getZExtValue() >= Len;
1475e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      }
1485e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      if (ConstantInt *Arg = dyn_cast<ConstantInt>(
1495e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge                                                  CI->getArgOperand(SizeArgOp)))
1505e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge        return SizeCI->getZExtValue() >= Arg->getZExtValue();
1515e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    }
1525e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    return false;
1535e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  }
1545e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge};
1555e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
1565e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingestruct MemCpyChkOpt : public InstFortifiedLibCallOptimization {
1575e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1585e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    this->CI = CI;
1595e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    FunctionType *FT = Callee->getFunctionType();
160ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth    LLVMContext &Context = CI->getParent()->getContext();
1615e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
1625e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    // Check if this has the right signature.
1635e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
1645e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge        !FT->getParamType(0)->isPointerTy() ||
1655e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge        !FT->getParamType(1)->isPointerTy() ||
166ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth        FT->getParamType(2) != TD->getIntPtrType(Context) ||
167ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth        FT->getParamType(3) != TD->getIntPtrType(Context))
1685e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      return 0;
1695e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
1705e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    if (isFoldable(3, 2, false)) {
1715e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
1725e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge                     CI->getArgOperand(2), 1);
1735e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      return CI->getArgOperand(0);
1745e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    }
1755e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    return 0;
1765e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  }
1775e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge};
1785e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
1795e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingestruct MemMoveChkOpt : public InstFortifiedLibCallOptimization {
1805e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1815e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    this->CI = CI;
1825e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    FunctionType *FT = Callee->getFunctionType();
183ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth    LLVMContext &Context = CI->getParent()->getContext();
1845e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
1855e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    // Check if this has the right signature.
1865e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
1875e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge        !FT->getParamType(0)->isPointerTy() ||
1885e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge        !FT->getParamType(1)->isPointerTy() ||
189ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth        FT->getParamType(2) != TD->getIntPtrType(Context) ||
190ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth        FT->getParamType(3) != TD->getIntPtrType(Context))
1915e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      return 0;
1925e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
1935e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    if (isFoldable(3, 2, false)) {
1945e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1),
1955e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge                      CI->getArgOperand(2), 1);
1965e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      return CI->getArgOperand(0);
1975e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    }
1985e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    return 0;
1995e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  }
2005e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge};
2015e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
2025e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingestruct MemSetChkOpt : public InstFortifiedLibCallOptimization {
2035e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
2045e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    this->CI = CI;
2055e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    FunctionType *FT = Callee->getFunctionType();
206ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth    LLVMContext &Context = CI->getParent()->getContext();
2075e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
2085e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    // Check if this has the right signature.
2095e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
2105e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge        !FT->getParamType(0)->isPointerTy() ||
2115e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge        !FT->getParamType(1)->isIntegerTy() ||
212ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth        FT->getParamType(2) != TD->getIntPtrType(Context) ||
213ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth        FT->getParamType(3) != TD->getIntPtrType(Context))
2145e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      return 0;
2155e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
2165e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    if (isFoldable(3, 2, false)) {
2175e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(),
2185e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge                                   false);
2195e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1);
2205e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      return CI->getArgOperand(0);
2215e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    }
2225e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    return 0;
2235e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  }
2245e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge};
2255e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
2265e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingestruct StrCpyChkOpt : public InstFortifiedLibCallOptimization {
2275e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
2285e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    this->CI = CI;
2295e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    StringRef Name = Callee->getName();
2305e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    FunctionType *FT = Callee->getFunctionType();
2315e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    LLVMContext &Context = CI->getParent()->getContext();
2325e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
2335e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    // Check if this has the right signature.
2345e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    if (FT->getNumParams() != 3 ||
2355e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge        FT->getReturnType() != FT->getParamType(0) ||
2365e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge        FT->getParamType(0) != FT->getParamType(1) ||
2375e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge        FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
238ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth        FT->getParamType(2) != TD->getIntPtrType(Context))
2395e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      return 0;
2405e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
2410c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge    Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1);
2420c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge    if (Dst == Src)      // __strcpy_chk(x,x)  -> x
2430c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge      return Src;
2440c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge
2455e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    // If a) we don't have any length information, or b) we know this will
246fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge    // fit then just lower to a plain strcpy. Otherwise we'll keep our
247fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge    // strcpy_chk call which may fail at runtime if the size is too long.
2485e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    // TODO: It might be nice to get a maximum length out of the possible
2495e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    // string lengths for varying.
2505e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    if (isFoldable(2, 1, true)) {
2510c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge      Value *Ret = EmitStrCpy(Dst, Src, B, TD, TLI, Name.substr(2, 6));
2520c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge      return Ret;
2530c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge    } else {
2540c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge      // Maybe we can stil fold __strcpy_chk to __memcpy_chk.
2550c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge      uint64_t Len = GetStringLength(Src);
2560c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge      if (Len == 0) return 0;
2570c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge
2580c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge      // This optimization require DataLayout.
2590c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge      if (!TD) return 0;
2600c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge
2610c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge      Value *Ret =
2620c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge	EmitMemCpyChk(Dst, Src,
263ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth                      ConstantInt::get(TD->getIntPtrType(Context), Len),
264ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth                      CI->getArgOperand(2), B, TD, TLI);
2655e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      return Ret;
2665e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    }
2675e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    return 0;
2685e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  }
2695e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge};
2705e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
271fa9d1372c99e5b74406a606756ba77d620d575bbMeador Ingestruct StpCpyChkOpt : public InstFortifiedLibCallOptimization {
272fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
273fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge    this->CI = CI;
274fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge    StringRef Name = Callee->getName();
275fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge    FunctionType *FT = Callee->getFunctionType();
276fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge    LLVMContext &Context = CI->getParent()->getContext();
277fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge
278fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge    // Check if this has the right signature.
279fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge    if (FT->getNumParams() != 3 ||
280fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge        FT->getReturnType() != FT->getParamType(0) ||
281fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge        FT->getParamType(0) != FT->getParamType(1) ||
282fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge        FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
283fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge        FT->getParamType(2) != TD->getIntPtrType(FT->getParamType(0)))
284fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge      return 0;
285fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge
286fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge    Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1);
287fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge    if (Dst == Src) {  // stpcpy(x,x)  -> x+strlen(x)
288fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge      Value *StrLen = EmitStrLen(Src, B, TD, TLI);
289fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge      return StrLen ? B.CreateInBoundsGEP(Dst, StrLen) : 0;
290fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge    }
291fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge
292fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge    // If a) we don't have any length information, or b) we know this will
293fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge    // fit then just lower to a plain stpcpy. Otherwise we'll keep our
294fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge    // stpcpy_chk call which may fail at runtime if the size is too long.
295fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge    // TODO: It might be nice to get a maximum length out of the possible
296fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge    // string lengths for varying.
297fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge    if (isFoldable(2, 1, true)) {
298fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge      Value *Ret = EmitStrCpy(Dst, Src, B, TD, TLI, Name.substr(2, 6));
299fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge      return Ret;
300fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge    } else {
301fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge      // Maybe we can stil fold __stpcpy_chk to __memcpy_chk.
302fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge      uint64_t Len = GetStringLength(Src);
303fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge      if (Len == 0) return 0;
304fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge
305fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge      // This optimization require DataLayout.
306fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge      if (!TD) return 0;
307fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge
308fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge      Type *PT = FT->getParamType(0);
309fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge      Value *LenV = ConstantInt::get(TD->getIntPtrType(PT), Len);
310fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge      Value *DstEnd = B.CreateGEP(Dst,
311fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge                                  ConstantInt::get(TD->getIntPtrType(PT),
312fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge                                                   Len - 1));
313fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge      if (!EmitMemCpyChk(Dst, Src, LenV, CI->getArgOperand(2), B, TD, TLI))
314fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge        return 0;
315fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge      return DstEnd;
316fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge    }
317fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge    return 0;
318fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge  }
319fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge};
320fa9d1372c99e5b74406a606756ba77d620d575bbMeador Inge
3215e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingestruct StrNCpyChkOpt : public InstFortifiedLibCallOptimization {
3225e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
3235e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    this->CI = CI;
3245e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    StringRef Name = Callee->getName();
3255e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    FunctionType *FT = Callee->getFunctionType();
3265e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    LLVMContext &Context = CI->getParent()->getContext();
3275e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
3285e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    // Check if this has the right signature.
3295e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
3305e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge        FT->getParamType(0) != FT->getParamType(1) ||
3315e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge        FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
3325e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge        !FT->getParamType(2)->isIntegerTy() ||
333ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth        FT->getParamType(3) != TD->getIntPtrType(Context))
3345e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      return 0;
3355e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
3365e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    if (isFoldable(3, 2, false)) {
3375e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      Value *Ret = EmitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1),
3385e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge                               CI->getArgOperand(2), B, TD, TLI,
3395e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge                               Name.substr(2, 7));
3405e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge      return Ret;
3415e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    }
3425e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    return 0;
3435e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  }
3445e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge};
3455e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
34673d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge//===----------------------------------------------------------------------===//
34773d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge// String and Memory Library Call Optimizations
34873d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge//===----------------------------------------------------------------------===//
34973d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge
35073d8a5864fe8c52be2b710c10ec155019738aad5Meador Ingestruct StrCatOpt : public LibCallOptimization {
35173d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
35273d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // Verify the "strcat" function prototype.
35373d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    FunctionType *FT = Callee->getFunctionType();
35473d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    if (FT->getNumParams() != 2 ||
35573d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge        FT->getReturnType() != B.getInt8PtrTy() ||
35673d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge        FT->getParamType(0) != FT->getReturnType() ||
35773d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge        FT->getParamType(1) != FT->getReturnType())
35873d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge      return 0;
35973d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge
36073d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // Extract some information from the instruction
36173d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    Value *Dst = CI->getArgOperand(0);
36273d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    Value *Src = CI->getArgOperand(1);
36373d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge
36473d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // See if we can get the length of the input string.
36573d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    uint64_t Len = GetStringLength(Src);
36673d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    if (Len == 0) return 0;
36773d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    --Len;  // Unbias length.
36873d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge
36973d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // Handle the simple, do-nothing case: strcat(x, "") -> x
37073d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    if (Len == 0)
37173d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge      return Dst;
37273d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge
37373d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // These optimizations require DataLayout.
37473d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    if (!TD) return 0;
37573d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge
37673d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    return emitStrLenMemCpy(Src, Dst, Len, B);
37773d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge  }
37873d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge
37973d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge  Value *emitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len,
38073d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge                          IRBuilder<> &B) {
38173d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // We need to find the end of the destination string.  That's where the
38273d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // memory is to be moved to. We just generate a call to strlen.
38373d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    Value *DstLen = EmitStrLen(Dst, B, TD, TLI);
38473d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    if (!DstLen)
38573d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge      return 0;
38673d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge
38773d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // Now that we have the destination's length, we must index into the
38873d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // destination's pointer to get the actual memcpy destination (end of
38973d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // the string .. we're concatenating).
39073d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    Value *CpyDst = B.CreateGEP(Dst, DstLen, "endptr");
39173d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge
39273d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // We have enough information to now generate the memcpy call to do the
39373d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // concatenation for us.  Make a memcpy to copy the nul byte with align = 1.
39473d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    B.CreateMemCpy(CpyDst, Src,
395ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth                   ConstantInt::get(TD->getIntPtrType(*Context), Len + 1), 1);
39673d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    return Dst;
39773d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge  }
39873d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge};
39973d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge
40073d8a5864fe8c52be2b710c10ec155019738aad5Meador Ingestruct StrNCatOpt : public StrCatOpt {
40173d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
40273d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // Verify the "strncat" function prototype.
40373d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    FunctionType *FT = Callee->getFunctionType();
40473d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    if (FT->getNumParams() != 3 ||
40573d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge        FT->getReturnType() != B.getInt8PtrTy() ||
40673d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge        FT->getParamType(0) != FT->getReturnType() ||
40773d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge        FT->getParamType(1) != FT->getReturnType() ||
40873d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge        !FT->getParamType(2)->isIntegerTy())
40973d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge      return 0;
41073d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge
41173d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // Extract some information from the instruction
41273d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    Value *Dst = CI->getArgOperand(0);
41373d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    Value *Src = CI->getArgOperand(1);
41473d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    uint64_t Len;
41573d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge
41673d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // We don't do anything if length is not constant
41773d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2)))
41873d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge      Len = LengthArg->getZExtValue();
41973d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    else
42073d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge      return 0;
42173d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge
42273d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // See if we can get the length of the input string.
42373d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    uint64_t SrcLen = GetStringLength(Src);
42473d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    if (SrcLen == 0) return 0;
42573d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    --SrcLen;  // Unbias length.
42673d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge
42773d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // Handle the simple, do-nothing cases:
42873d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // strncat(x, "", c) -> x
42973d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // strncat(x,  c, 0) -> x
43073d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    if (SrcLen == 0 || Len == 0) return Dst;
43173d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge
43273d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // These optimizations require DataLayout.
43373d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    if (!TD) return 0;
43473d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge
43573d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // We don't optimize this case
43673d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    if (Len < SrcLen) return 0;
43773d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge
43873d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // strncat(x, s, c) -> strcat(x, s)
43973d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    // s is constant so the strcat can be optimized further
44073d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge    return emitStrLenMemCpy(Src, Dst, SrcLen, B);
44173d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge  }
44273d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge};
44373d8a5864fe8c52be2b710c10ec155019738aad5Meador Inge
444186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Ingestruct StrChrOpt : public LibCallOptimization {
445186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
446186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    // Verify the "strchr" function prototype.
447186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    FunctionType *FT = Callee->getFunctionType();
448186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    if (FT->getNumParams() != 2 ||
449186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge        FT->getReturnType() != B.getInt8PtrTy() ||
450186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge        FT->getParamType(0) != FT->getReturnType() ||
451186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge        !FT->getParamType(1)->isIntegerTy(32))
452186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge      return 0;
453186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge
454186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    Value *SrcStr = CI->getArgOperand(0);
455186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge
456186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    // If the second operand is non-constant, see if we can compute the length
457186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    // of the input string and turn this into memchr.
458186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getArgOperand(1));
459186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    if (CharC == 0) {
460186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge      // These optimizations require DataLayout.
461186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge      if (!TD) return 0;
462186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge
463186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge      uint64_t Len = GetStringLength(SrcStr);
464186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge      if (Len == 0 || !FT->getParamType(1)->isIntegerTy(32))// memchr needs i32.
465186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge        return 0;
466186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge
467186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge      return EmitMemChr(SrcStr, CI->getArgOperand(1), // include nul.
468ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth                        ConstantInt::get(TD->getIntPtrType(*Context), Len),
469186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge                        B, TD, TLI);
470186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    }
471186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge
472186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    // Otherwise, the character is a constant, see if the first argument is
473186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    // a string literal.  If so, we can constant fold.
474186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    StringRef Str;
475186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    if (!getConstantStringInfo(SrcStr, Str))
476186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge      return 0;
477186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge
478186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    // Compute the offset, make sure to handle the case when we're searching for
479186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    // zero (a weird way to spell strlen).
480186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    size_t I = CharC->getSExtValue() == 0 ?
481186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge        Str.size() : Str.find(CharC->getSExtValue());
482186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    if (I == StringRef::npos) // Didn't find the char.  strchr returns null.
483186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge      return Constant::getNullValue(CI->getType());
484186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge
485186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    // strchr(s+n,c)  -> gep(s+n+i,c)
486186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    return B.CreateGEP(SrcStr, B.getInt64(I), "strchr");
487186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge  }
488186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge};
489186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge
490186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Ingestruct StrRChrOpt : public LibCallOptimization {
491186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
492186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    // Verify the "strrchr" function prototype.
493186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    FunctionType *FT = Callee->getFunctionType();
494186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    if (FT->getNumParams() != 2 ||
495186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge        FT->getReturnType() != B.getInt8PtrTy() ||
496186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge        FT->getParamType(0) != FT->getReturnType() ||
497186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge        !FT->getParamType(1)->isIntegerTy(32))
498186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge      return 0;
499186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge
500186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    Value *SrcStr = CI->getArgOperand(0);
501186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getArgOperand(1));
502186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge
503186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    // Cannot fold anything if we're not looking for a constant.
504186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    if (!CharC)
505186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge      return 0;
506186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge
507186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    StringRef Str;
508186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    if (!getConstantStringInfo(SrcStr, Str)) {
509186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge      // strrchr(s, 0) -> strchr(s, 0)
510186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge      if (TD && CharC->isZero())
511186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge        return EmitStrChr(SrcStr, '\0', B, TD, TLI);
512186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge      return 0;
513186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    }
514186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge
515186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    // Compute the offset.
516186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    size_t I = CharC->getSExtValue() == 0 ?
517186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge        Str.size() : Str.rfind(CharC->getSExtValue());
518186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    if (I == StringRef::npos) // Didn't find the char. Return null.
519186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge      return Constant::getNullValue(CI->getType());
520186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge
521186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    // strrchr(s+n,c) -> gep(s+n+i,c)
522186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge    return B.CreateGEP(SrcStr, B.getInt64(I), "strrchr");
523186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge  }
524186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge};
525186f8d90df976349481ccf8c8e24c37c6ec5ffb4Meador Inge
526a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Ingestruct StrCmpOpt : public LibCallOptimization {
527a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
528a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    // Verify the "strcmp" function prototype.
529a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    FunctionType *FT = Callee->getFunctionType();
530a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    if (FT->getNumParams() != 2 ||
531a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge        !FT->getReturnType()->isIntegerTy(32) ||
532a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge        FT->getParamType(0) != FT->getParamType(1) ||
533a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge        FT->getParamType(0) != B.getInt8PtrTy())
534a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge      return 0;
535a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge
536a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1);
537a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    if (Str1P == Str2P)      // strcmp(x,x)  -> 0
538a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge      return ConstantInt::get(CI->getType(), 0);
539a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge
540a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    StringRef Str1, Str2;
541a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    bool HasStr1 = getConstantStringInfo(Str1P, Str1);
542a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    bool HasStr2 = getConstantStringInfo(Str2P, Str2);
543a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge
544a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    // strcmp(x, y)  -> cnst  (if both x and y are constant strings)
545a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    if (HasStr1 && HasStr2)
546a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge      return ConstantInt::get(CI->getType(), Str1.compare(Str2));
547a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge
548a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    if (HasStr1 && Str1.empty()) // strcmp("", x) -> -*x
549a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge      return B.CreateNeg(B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"),
550a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge                                      CI->getType()));
551a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge
552a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    if (HasStr2 && Str2.empty()) // strcmp(x,"") -> *x
553a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge      return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType());
554a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge
555a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    // strcmp(P, "x") -> memcmp(P, "x", 2)
556a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    uint64_t Len1 = GetStringLength(Str1P);
557a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    uint64_t Len2 = GetStringLength(Str2P);
558a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    if (Len1 && Len2) {
559a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge      // These optimizations require DataLayout.
560a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge      if (!TD) return 0;
561a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge
562a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge      return EmitMemCmp(Str1P, Str2P,
563ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth                        ConstantInt::get(TD->getIntPtrType(*Context),
564a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge                        std::min(Len1, Len2)), B, TD, TLI);
565a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    }
566a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge
567a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    return 0;
568a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge  }
569a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge};
570a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge
571a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Ingestruct StrNCmpOpt : public LibCallOptimization {
572a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
573a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    // Verify the "strncmp" function prototype.
574a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    FunctionType *FT = Callee->getFunctionType();
575a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    if (FT->getNumParams() != 3 ||
576a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge        !FT->getReturnType()->isIntegerTy(32) ||
577a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge        FT->getParamType(0) != FT->getParamType(1) ||
578a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge        FT->getParamType(0) != B.getInt8PtrTy() ||
579a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge        !FT->getParamType(2)->isIntegerTy())
580a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge      return 0;
581a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge
582a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1);
583a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    if (Str1P == Str2P)      // strncmp(x,x,n)  -> 0
584a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge      return ConstantInt::get(CI->getType(), 0);
585a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge
586a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    // Get the length argument if it is constant.
587a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    uint64_t Length;
588a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2)))
589a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge      Length = LengthArg->getZExtValue();
590a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    else
591a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge      return 0;
592a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge
593a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    if (Length == 0) // strncmp(x,y,0)   -> 0
594a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge      return ConstantInt::get(CI->getType(), 0);
595a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge
596a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    if (TD && Length == 1) // strncmp(x,y,1) -> memcmp(x,y,1)
597a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge      return EmitMemCmp(Str1P, Str2P, CI->getArgOperand(2), B, TD, TLI);
598a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge
599a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    StringRef Str1, Str2;
600a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    bool HasStr1 = getConstantStringInfo(Str1P, Str1);
601a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    bool HasStr2 = getConstantStringInfo(Str2P, Str2);
602a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge
603a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    // strncmp(x, y)  -> cnst  (if both x and y are constant strings)
604a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    if (HasStr1 && HasStr2) {
605a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge      StringRef SubStr1 = Str1.substr(0, Length);
606a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge      StringRef SubStr2 = Str2.substr(0, Length);
607a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge      return ConstantInt::get(CI->getType(), SubStr1.compare(SubStr2));
608a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    }
609a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge
610a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    if (HasStr1 && Str1.empty())  // strncmp("", x, n) -> -*x
611a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge      return B.CreateNeg(B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"),
612a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge                                      CI->getType()));
613a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge
614a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    if (HasStr2 && Str2.empty())  // strncmp(x, "", n) -> *x
615a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge      return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType());
616a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge
617a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge    return 0;
618a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge  }
619a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge};
620a239c2e6a7775e890bcfb0867b84e512ceb993deMeador Inge
6210c41d57b09884b92f988cb88553eaa7c77819d4bMeador Ingestruct StrCpyOpt : public LibCallOptimization {
6220c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
6230c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge    // Verify the "strcpy" function prototype.
6240c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge    FunctionType *FT = Callee->getFunctionType();
6250c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge    if (FT->getNumParams() != 2 ||
6260c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge        FT->getReturnType() != FT->getParamType(0) ||
6270c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge        FT->getParamType(0) != FT->getParamType(1) ||
6280c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge        FT->getParamType(0) != B.getInt8PtrTy())
6290c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge      return 0;
6300c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge
6310c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge    Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1);
6320c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge    if (Dst == Src)      // strcpy(x,x)  -> x
6330c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge      return Src;
6340c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge
6350c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge    // These optimizations require DataLayout.
6360c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge    if (!TD) return 0;
6370c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge
6380c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge    // See if we can get the length of the input string.
6390c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge    uint64_t Len = GetStringLength(Src);
6400c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge    if (Len == 0) return 0;
6410c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge
6420c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge    // We have enough information to now generate the memcpy call to do the
6430c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge    // copy for us.  Make a memcpy to copy the nul byte with align = 1.
6440c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge    B.CreateMemCpy(Dst, Src,
645ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth		   ConstantInt::get(TD->getIntPtrType(*Context), Len), 1);
6460c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge    return Dst;
6470c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge  }
6480c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge};
6490c41d57b09884b92f988cb88553eaa7c77819d4bMeador Inge
650e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Ingestruct StpCpyOpt: public LibCallOptimization {
651e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
652e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge    // Verify the "stpcpy" function prototype.
653e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge    FunctionType *FT = Callee->getFunctionType();
654e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge    if (FT->getNumParams() != 2 ||
655e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge        FT->getReturnType() != FT->getParamType(0) ||
656e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge        FT->getParamType(0) != FT->getParamType(1) ||
657e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge        FT->getParamType(0) != B.getInt8PtrTy())
658e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge      return 0;
659e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge
660e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge    // These optimizations require DataLayout.
661e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge    if (!TD) return 0;
662e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge
663e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge    Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1);
664e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge    if (Dst == Src) {  // stpcpy(x,x)  -> x+strlen(x)
665e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge      Value *StrLen = EmitStrLen(Src, B, TD, TLI);
666e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge      return StrLen ? B.CreateInBoundsGEP(Dst, StrLen) : 0;
667e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge    }
668e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge
669e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge    // See if we can get the length of the input string.
670e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge    uint64_t Len = GetStringLength(Src);
671e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge    if (Len == 0) return 0;
672e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge
673e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge    Type *PT = FT->getParamType(0);
674e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge    Value *LenV = ConstantInt::get(TD->getIntPtrType(PT), Len);
675e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge    Value *DstEnd = B.CreateGEP(Dst,
676e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge                                ConstantInt::get(TD->getIntPtrType(PT),
677e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge                                                 Len - 1));
678e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge
679e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge    // We have enough information to now generate the memcpy call to do the
680e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge    // copy for us.  Make a memcpy to copy the nul byte with align = 1.
681e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge    B.CreateMemCpy(Dst, Src, LenV, 1);
682e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge    return DstEnd;
683e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge  }
684e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge};
685e6d781fd3cf9aa30d1c533308d1fdb6738e4f89fMeador Inge
686a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Ingestruct StrNCpyOpt : public LibCallOptimization {
687a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
688a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    FunctionType *FT = Callee->getFunctionType();
689a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
690a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge        FT->getParamType(0) != FT->getParamType(1) ||
691a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge        FT->getParamType(0) != B.getInt8PtrTy() ||
692a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge        !FT->getParamType(2)->isIntegerTy())
693a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge      return 0;
694a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge
695a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    Value *Dst = CI->getArgOperand(0);
696a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    Value *Src = CI->getArgOperand(1);
697a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    Value *LenOp = CI->getArgOperand(2);
698a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge
699a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    // See if we can get the length of the input string.
700a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    uint64_t SrcLen = GetStringLength(Src);
701a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    if (SrcLen == 0) return 0;
702a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    --SrcLen;
703a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge
704a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    if (SrcLen == 0) {
705a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge      // strncpy(x, "", y) -> memset(x, '\0', y, 1)
706a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge      B.CreateMemSet(Dst, B.getInt8('\0'), LenOp, 1);
707a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge      return Dst;
708a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    }
709a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge
710a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    uint64_t Len;
711a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(LenOp))
712a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge      Len = LengthArg->getZExtValue();
713a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    else
714a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge      return 0;
715a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge
716a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    if (Len == 0) return Dst; // strncpy(x, y, 0) -> x
717a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge
718a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    // These optimizations require DataLayout.
719a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    if (!TD) return 0;
720a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge
721a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    // Let strncpy handle the zero padding
722a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    if (Len > SrcLen+1) return 0;
723a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge
724a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    Type *PT = FT->getParamType(0);
725a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    // strncpy(x, s, c) -> memcpy(x, s, c, 1) [s and c are constant]
726a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    B.CreateMemCpy(Dst, Src,
727a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge                   ConstantInt::get(TD->getIntPtrType(PT), Len), 1);
728a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge
729a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge    return Dst;
730a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge  }
731a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge};
732a0885fb8825ed362041b5cf291a007a9f9301ff8Meador Inge
73357cfd71f881ae381fa43667e003f595ffd70ea18Meador Ingestruct StrLenOpt : public LibCallOptimization {
73433daeab1bb8df65273fd9ecbf1a261f96733732eChad Rosier  virtual bool ignoreCallingConv() { return true; }
73557cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
73657cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge    FunctionType *FT = Callee->getFunctionType();
73757cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge    if (FT->getNumParams() != 1 ||
73857cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge        FT->getParamType(0) != B.getInt8PtrTy() ||
73957cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge        !FT->getReturnType()->isIntegerTy())
74057cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge      return 0;
74157cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge
74257cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge    Value *Src = CI->getArgOperand(0);
74357cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge
74457cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge    // Constant folding: strlen("xyz") -> 3
74557cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge    if (uint64_t Len = GetStringLength(Src))
74657cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge      return ConstantInt::get(CI->getType(), Len-1);
74757cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge
74857cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge    // strlen(x) != 0 --> *x != 0
74957cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge    // strlen(x) == 0 --> *x == 0
75057cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge    if (isOnlyUsedInZeroEqualityComparison(CI))
75157cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge      return B.CreateZExt(B.CreateLoad(Src, "strlenfirst"), CI->getType());
75257cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge    return 0;
75357cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge  }
75457cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge};
75557cfd71f881ae381fa43667e003f595ffd70ea18Meador Inge
75608684d1f069711692502d091669a6031c31cdd4aMeador Ingestruct StrPBrkOpt : public LibCallOptimization {
75708684d1f069711692502d091669a6031c31cdd4aMeador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
75808684d1f069711692502d091669a6031c31cdd4aMeador Inge    FunctionType *FT = Callee->getFunctionType();
75908684d1f069711692502d091669a6031c31cdd4aMeador Inge    if (FT->getNumParams() != 2 ||
76008684d1f069711692502d091669a6031c31cdd4aMeador Inge        FT->getParamType(0) != B.getInt8PtrTy() ||
76108684d1f069711692502d091669a6031c31cdd4aMeador Inge        FT->getParamType(1) != FT->getParamType(0) ||
76208684d1f069711692502d091669a6031c31cdd4aMeador Inge        FT->getReturnType() != FT->getParamType(0))
76308684d1f069711692502d091669a6031c31cdd4aMeador Inge      return 0;
76408684d1f069711692502d091669a6031c31cdd4aMeador Inge
76508684d1f069711692502d091669a6031c31cdd4aMeador Inge    StringRef S1, S2;
76608684d1f069711692502d091669a6031c31cdd4aMeador Inge    bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1);
76708684d1f069711692502d091669a6031c31cdd4aMeador Inge    bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2);
76808684d1f069711692502d091669a6031c31cdd4aMeador Inge
76908684d1f069711692502d091669a6031c31cdd4aMeador Inge    // strpbrk(s, "") -> NULL
77008684d1f069711692502d091669a6031c31cdd4aMeador Inge    // strpbrk("", s) -> NULL
77108684d1f069711692502d091669a6031c31cdd4aMeador Inge    if ((HasS1 && S1.empty()) || (HasS2 && S2.empty()))
77208684d1f069711692502d091669a6031c31cdd4aMeador Inge      return Constant::getNullValue(CI->getType());
77308684d1f069711692502d091669a6031c31cdd4aMeador Inge
77408684d1f069711692502d091669a6031c31cdd4aMeador Inge    // Constant folding.
77508684d1f069711692502d091669a6031c31cdd4aMeador Inge    if (HasS1 && HasS2) {
77608684d1f069711692502d091669a6031c31cdd4aMeador Inge      size_t I = S1.find_first_of(S2);
77708684d1f069711692502d091669a6031c31cdd4aMeador Inge      if (I == std::string::npos) // No match.
77808684d1f069711692502d091669a6031c31cdd4aMeador Inge        return Constant::getNullValue(CI->getType());
77908684d1f069711692502d091669a6031c31cdd4aMeador Inge
78008684d1f069711692502d091669a6031c31cdd4aMeador Inge      return B.CreateGEP(CI->getArgOperand(0), B.getInt64(I), "strpbrk");
78108684d1f069711692502d091669a6031c31cdd4aMeador Inge    }
78208684d1f069711692502d091669a6031c31cdd4aMeador Inge
78308684d1f069711692502d091669a6031c31cdd4aMeador Inge    // strpbrk(s, "a") -> strchr(s, 'a')
78408684d1f069711692502d091669a6031c31cdd4aMeador Inge    if (TD && HasS2 && S2.size() == 1)
78508684d1f069711692502d091669a6031c31cdd4aMeador Inge      return EmitStrChr(CI->getArgOperand(0), S2[0], B, TD, TLI);
78608684d1f069711692502d091669a6031c31cdd4aMeador Inge
78708684d1f069711692502d091669a6031c31cdd4aMeador Inge    return 0;
78808684d1f069711692502d091669a6031c31cdd4aMeador Inge  }
78908684d1f069711692502d091669a6031c31cdd4aMeador Inge};
79008684d1f069711692502d091669a6031c31cdd4aMeador Inge
791e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Ingestruct StrToOpt : public LibCallOptimization {
792e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
793e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge    FunctionType *FT = Callee->getFunctionType();
794e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge    if ((FT->getNumParams() != 2 && FT->getNumParams() != 3) ||
795e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge        !FT->getParamType(0)->isPointerTy() ||
796e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge        !FT->getParamType(1)->isPointerTy())
797e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge      return 0;
798e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge
799e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge    Value *EndPtr = CI->getArgOperand(1);
800e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge    if (isa<ConstantPointerNull>(EndPtr)) {
801e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge      // With a null EndPtr, this function won't capture the main argument.
802e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge      // It would be readonly too, except that it still may write to errno.
803328d1b65002e68ae65ffef05eed19122cbf721f5Peter Collingbourne      CI->addAttribute(1, Attribute::NoCapture);
804e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge    }
805e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge
806e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge    return 0;
807e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge  }
808e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge};
809e0f1dca1c8c191db3b353b60142a574c2d1c2a54Meador Inge
8107629de3326318e533ab969abd1b0cbc569b3f3b7Meador Ingestruct StrSpnOpt : public LibCallOptimization {
8117629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
8127629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge    FunctionType *FT = Callee->getFunctionType();
8137629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge    if (FT->getNumParams() != 2 ||
8147629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge        FT->getParamType(0) != B.getInt8PtrTy() ||
8157629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge        FT->getParamType(1) != FT->getParamType(0) ||
8167629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge        !FT->getReturnType()->isIntegerTy())
8177629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge      return 0;
8187629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge
8197629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge    StringRef S1, S2;
8207629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge    bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1);
8217629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge    bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2);
8227629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge
8237629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge    // strspn(s, "") -> 0
8247629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge    // strspn("", s) -> 0
8257629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge    if ((HasS1 && S1.empty()) || (HasS2 && S2.empty()))
8267629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge      return Constant::getNullValue(CI->getType());
8277629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge
8287629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge    // Constant folding.
8297629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge    if (HasS1 && HasS2) {
8307629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge      size_t Pos = S1.find_first_not_of(S2);
8317629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge      if (Pos == StringRef::npos) Pos = S1.size();
8327629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge      return ConstantInt::get(CI->getType(), Pos);
8337629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge    }
8347629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge
8357629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge    return 0;
8367629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge  }
8377629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge};
8387629de3326318e533ab969abd1b0cbc569b3f3b7Meador Inge
8395464ee7eaaf490444589d8716ae529827e29aa9bMeador Ingestruct StrCSpnOpt : public LibCallOptimization {
8405464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
8415464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge    FunctionType *FT = Callee->getFunctionType();
8425464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge    if (FT->getNumParams() != 2 ||
8435464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge        FT->getParamType(0) != B.getInt8PtrTy() ||
8445464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge        FT->getParamType(1) != FT->getParamType(0) ||
8455464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge        !FT->getReturnType()->isIntegerTy())
8465464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge      return 0;
8475464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge
8485464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge    StringRef S1, S2;
8495464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge    bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1);
8505464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge    bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2);
8515464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge
8525464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge    // strcspn("", s) -> 0
8535464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge    if (HasS1 && S1.empty())
8545464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge      return Constant::getNullValue(CI->getType());
8555464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge
8565464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge    // Constant folding.
8575464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge    if (HasS1 && HasS2) {
8585464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge      size_t Pos = S1.find_first_of(S2);
8595464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge      if (Pos == StringRef::npos) Pos = S1.size();
8605464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge      return ConstantInt::get(CI->getType(), Pos);
8615464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge    }
8625464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge
8635464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge    // strcspn(s, "") -> strlen(s)
8645464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge    if (TD && HasS2 && S2.empty())
8655464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge      return EmitStrLen(CI->getArgOperand(0), B, TD, TLI);
8665464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge
8675464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge    return 0;
8685464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge  }
8695464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge};
8705464ee7eaaf490444589d8716ae529827e29aa9bMeador Inge
8716e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Ingestruct StrStrOpt : public LibCallOptimization {
8726e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
8736e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    FunctionType *FT = Callee->getFunctionType();
8746e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    if (FT->getNumParams() != 2 ||
8756e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge        !FT->getParamType(0)->isPointerTy() ||
8766e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge        !FT->getParamType(1)->isPointerTy() ||
8776e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge        !FT->getReturnType()->isPointerTy())
8786e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge      return 0;
8796e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge
8806e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    // fold strstr(x, x) -> x.
8816e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    if (CI->getArgOperand(0) == CI->getArgOperand(1))
8826e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge      return B.CreateBitCast(CI->getArgOperand(0), CI->getType());
8836e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge
8846e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    // fold strstr(a, b) == a -> strncmp(a, b, strlen(b)) == 0
8856e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    if (TD && isOnlyUsedInEqualityComparison(CI, CI->getArgOperand(0))) {
8866e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge      Value *StrLen = EmitStrLen(CI->getArgOperand(1), B, TD, TLI);
8876e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge      if (!StrLen)
8886e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge        return 0;
8896e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge      Value *StrNCmp = EmitStrNCmp(CI->getArgOperand(0), CI->getArgOperand(1),
8906e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge                                   StrLen, B, TD, TLI);
8916e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge      if (!StrNCmp)
8926e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge        return 0;
8936e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge      for (Value::use_iterator UI = CI->use_begin(), UE = CI->use_end();
8946e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge           UI != UE; ) {
8956e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge        ICmpInst *Old = cast<ICmpInst>(*UI++);
8966e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge        Value *Cmp = B.CreateICmp(Old->getPredicate(), StrNCmp,
8976e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge                                  ConstantInt::getNullValue(StrNCmp->getType()),
8986e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge                                  "cmp");
8996e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge        LCS->replaceAllUsesWith(Old, Cmp);
9006e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge      }
9016e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge      return CI;
9026e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    }
9036e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge
9046e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    // See if either input string is a constant string.
9056e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    StringRef SearchStr, ToFindStr;
9066e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    bool HasStr1 = getConstantStringInfo(CI->getArgOperand(0), SearchStr);
9076e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    bool HasStr2 = getConstantStringInfo(CI->getArgOperand(1), ToFindStr);
9086e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge
9096e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    // fold strstr(x, "") -> x.
9106e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    if (HasStr2 && ToFindStr.empty())
9116e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge      return B.CreateBitCast(CI->getArgOperand(0), CI->getType());
9126e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge
9136e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    // If both strings are known, constant fold it.
9146e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    if (HasStr1 && HasStr2) {
9156e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge      std::string::size_type Offset = SearchStr.find(ToFindStr);
9166e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge
9176e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge      if (Offset == StringRef::npos) // strstr("foo", "bar") -> null
9186e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge        return Constant::getNullValue(CI->getType());
9196e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge
9206e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge      // strstr("abcd", "bc") -> gep((char*)"abcd", 1)
9216e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge      Value *Result = CastToCStr(CI->getArgOperand(0), B);
9226e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge      Result = B.CreateConstInBoundsGEP1_64(Result, Offset, "strstr");
9236e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge      return B.CreateBitCast(Result, CI->getType());
9246e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    }
9256e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge
9266e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    // fold strstr(x, "y") -> strchr(x, 'y').
9276e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    if (HasStr2 && ToFindStr.size() == 1) {
9286e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge      Value *StrChr= EmitStrChr(CI->getArgOperand(0), ToFindStr[0], B, TD, TLI);
9296e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge      return StrChr ? B.CreateBitCast(StrChr, CI->getType()) : 0;
9306e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    }
9316e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge    return 0;
9326e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge  }
9336e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge};
9346e1591a5d5fba3bde66e3ffd4dd73edd6b94cecfMeador Inge
935bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Ingestruct MemCmpOpt : public LibCallOptimization {
936bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
937bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge    FunctionType *FT = Callee->getFunctionType();
938bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge    if (FT->getNumParams() != 3 || !FT->getParamType(0)->isPointerTy() ||
939bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge        !FT->getParamType(1)->isPointerTy() ||
940bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge        !FT->getReturnType()->isIntegerTy(32))
941bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge      return 0;
942bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge
943bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge    Value *LHS = CI->getArgOperand(0), *RHS = CI->getArgOperand(1);
944bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge
945bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge    if (LHS == RHS)  // memcmp(s,s,x) -> 0
946bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge      return Constant::getNullValue(CI->getType());
947bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge
948bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge    // Make sure we have a constant length.
949bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge    ConstantInt *LenC = dyn_cast<ConstantInt>(CI->getArgOperand(2));
950bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge    if (!LenC) return 0;
951bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge    uint64_t Len = LenC->getZExtValue();
952bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge
953bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge    if (Len == 0) // memcmp(s1,s2,0) -> 0
954bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge      return Constant::getNullValue(CI->getType());
955bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge
956bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge    // memcmp(S1,S2,1) -> *(unsigned char*)LHS - *(unsigned char*)RHS
957bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge    if (Len == 1) {
958bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge      Value *LHSV = B.CreateZExt(B.CreateLoad(CastToCStr(LHS, B), "lhsc"),
959bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge                                 CI->getType(), "lhsv");
960bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge      Value *RHSV = B.CreateZExt(B.CreateLoad(CastToCStr(RHS, B), "rhsc"),
961bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge                                 CI->getType(), "rhsv");
962bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge      return B.CreateSub(LHSV, RHSV, "chardiff");
963bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge    }
964bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge
965bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge    // Constant folding: memcmp(x, y, l) -> cnst (all arguments are constant)
966bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge    StringRef LHSStr, RHSStr;
967bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge    if (getConstantStringInfo(LHS, LHSStr) &&
968bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge        getConstantStringInfo(RHS, RHSStr)) {
969bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge      // Make sure we're not reading out-of-bounds memory.
970bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge      if (Len > LHSStr.size() || Len > RHSStr.size())
971bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge        return 0;
97230d8f0e9770db76f19273419c57fe112129b145aMeador Inge      // Fold the memcmp and normalize the result.  This way we get consistent
97330d8f0e9770db76f19273419c57fe112129b145aMeador Inge      // results across multiple platforms.
97430d8f0e9770db76f19273419c57fe112129b145aMeador Inge      uint64_t Ret = 0;
97530d8f0e9770db76f19273419c57fe112129b145aMeador Inge      int Cmp = memcmp(LHSStr.data(), RHSStr.data(), Len);
97630d8f0e9770db76f19273419c57fe112129b145aMeador Inge      if (Cmp < 0)
97730d8f0e9770db76f19273419c57fe112129b145aMeador Inge        Ret = -1;
97830d8f0e9770db76f19273419c57fe112129b145aMeador Inge      else if (Cmp > 0)
97930d8f0e9770db76f19273419c57fe112129b145aMeador Inge        Ret = 1;
980bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge      return ConstantInt::get(CI->getType(), Ret);
981bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge    }
982bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge
983bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge    return 0;
984bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge  }
985bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge};
986bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge
98711b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Ingestruct MemCpyOpt : public LibCallOptimization {
98811b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
98911b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge    // These optimizations require DataLayout.
99011b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge    if (!TD) return 0;
99111b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge
99211b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge    FunctionType *FT = Callee->getFunctionType();
99311b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge    if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
99411b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge        !FT->getParamType(0)->isPointerTy() ||
99511b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge        !FT->getParamType(1)->isPointerTy() ||
99611b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge        FT->getParamType(2) != TD->getIntPtrType(*Context))
99711b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge      return 0;
99811b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge
99911b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge    // memcpy(x, y, n) -> llvm.memcpy(x, y, n, 1)
100011b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge    B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
100111b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge                   CI->getArgOperand(2), 1);
100211b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge    return CI->getArgOperand(0);
100311b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge  }
100411b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge};
100511b04b40f285c8dd2c9ae9b349c3877078eeee10Meador Inge
1006d7cb600514a1d85e88ae873633bb42357babbc68Meador Ingestruct MemMoveOpt : public LibCallOptimization {
1007d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1008d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge    // These optimizations require DataLayout.
1009d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge    if (!TD) return 0;
1010d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge
1011d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge    FunctionType *FT = Callee->getFunctionType();
1012d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge    if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
1013d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge        !FT->getParamType(0)->isPointerTy() ||
1014d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge        !FT->getParamType(1)->isPointerTy() ||
1015d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge        FT->getParamType(2) != TD->getIntPtrType(*Context))
1016d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge      return 0;
1017d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge
1018d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge    // memmove(x, y, n) -> llvm.memmove(x, y, n, 1)
1019d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge    B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1),
1020d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge                    CI->getArgOperand(2), 1);
1021d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge    return CI->getArgOperand(0);
1022d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge  }
1023d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge};
1024d7cb600514a1d85e88ae873633bb42357babbc68Meador Inge
102526ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Ingestruct MemSetOpt : public LibCallOptimization {
102626ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
102726ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge    // These optimizations require DataLayout.
102826ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge    if (!TD) return 0;
102926ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge
103026ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge    FunctionType *FT = Callee->getFunctionType();
103126ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge    if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
103226ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge        !FT->getParamType(0)->isPointerTy() ||
103326ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge        !FT->getParamType(1)->isIntegerTy() ||
103426ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge        FT->getParamType(2) != TD->getIntPtrType(*Context))
103526ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge      return 0;
103626ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge
103726ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge    // memset(p, v, n) -> llvm.memset(p, v, n, 1)
103826ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge    Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), false);
103926ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge    B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1);
104026ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge    return CI->getArgOperand(0);
104126ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge  }
104226ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge};
104326ebe398f2bddae5395b4ad8c7ffb5933b2230d1Meador Inge
10442920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge//===----------------------------------------------------------------------===//
10452920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge// Math Library Optimizations
10462920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge//===----------------------------------------------------------------------===//
10472920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
10482920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge//===----------------------------------------------------------------------===//
10492920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge// Double -> Float Shrinking Optimizations for Unary Functions like 'floor'
10502920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
10512920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Ingestruct UnaryDoubleFPOpt : public LibCallOptimization {
10522920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge  bool CheckRetType;
10532920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge  UnaryDoubleFPOpt(bool CheckReturnType): CheckRetType(CheckReturnType) {}
10542920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
10552920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    FunctionType *FT = Callee->getFunctionType();
10562920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    if (FT->getNumParams() != 1 || !FT->getReturnType()->isDoubleTy() ||
10572920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge        !FT->getParamType(0)->isDoubleTy())
10582920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      return 0;
10592920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
10602920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    if (CheckRetType) {
10612920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      // Check if all the uses for function like 'sin' are converted to float.
10622920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      for (Value::use_iterator UseI = CI->use_begin(); UseI != CI->use_end();
10632920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge          ++UseI) {
10642920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge        FPTruncInst *Cast = dyn_cast<FPTruncInst>(*UseI);
10652920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge        if (Cast == 0 || !Cast->getType()->isFloatTy())
10662920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge          return 0;
10672920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      }
10682920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    }
10692920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
10702920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    // If this is something like 'floor((double)floatval)', convert to floorf.
10712920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    FPExtInst *Cast = dyn_cast<FPExtInst>(CI->getArgOperand(0));
10722920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    if (Cast == 0 || !Cast->getOperand(0)->getType()->isFloatTy())
10732920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      return 0;
10742920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
10752920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    // floor((double)floatval) -> (double)floorf(floatval)
10762920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    Value *V = Cast->getOperand(0);
10772920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    V = EmitUnaryFloatFnCall(V, Callee->getName(), B, Callee->getAttributes());
10782920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    return B.CreateFPExt(V, B.getDoubleTy());
10792920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge  }
10802920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge};
10812920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
10822920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Ingestruct UnsafeFPLibCallOptimization : public LibCallOptimization {
10832920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge  bool UnsafeFPShrink;
10842920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge  UnsafeFPLibCallOptimization(bool UnsafeFPShrink) {
10852920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    this->UnsafeFPShrink = UnsafeFPShrink;
10862920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge  }
10872920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge};
10882920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
10892920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Ingestruct CosOpt : public UnsafeFPLibCallOptimization {
10902920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge  CosOpt(bool UnsafeFPShrink) : UnsafeFPLibCallOptimization(UnsafeFPShrink) {}
10912920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
10922920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    Value *Ret = NULL;
10932920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    if (UnsafeFPShrink && Callee->getName() == "cos" &&
10942920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge        TLI->has(LibFunc::cosf)) {
10952920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true);
10962920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B);
10972920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    }
10982920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
10992920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    FunctionType *FT = Callee->getFunctionType();
11002920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    // Just make sure this has 1 argument of FP type, which matches the
11012920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    // result type.
11022920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) ||
11032920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge        !FT->getParamType(0)->isFloatingPointTy())
11042920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      return Ret;
11052920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
11062920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    // cos(-x) -> cos(x)
11072920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    Value *Op1 = CI->getArgOperand(0);
11082920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    if (BinaryOperator::isFNeg(Op1)) {
11092920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      BinaryOperator *BinExpr = cast<BinaryOperator>(Op1);
11102920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      return B.CreateCall(Callee, BinExpr->getOperand(1), "cos");
11112920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    }
11122920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    return Ret;
11132920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge  }
11142920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge};
11152920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
11162920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Ingestruct PowOpt : public UnsafeFPLibCallOptimization {
11172920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge  PowOpt(bool UnsafeFPShrink) : UnsafeFPLibCallOptimization(UnsafeFPShrink) {}
11182920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
11192920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    Value *Ret = NULL;
11202920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    if (UnsafeFPShrink && Callee->getName() == "pow" &&
11212920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge        TLI->has(LibFunc::powf)) {
11222920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true);
11232920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B);
11242920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    }
11252920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
11262920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    FunctionType *FT = Callee->getFunctionType();
11272920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    // Just make sure this has 2 arguments of the same FP type, which match the
11282920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    // result type.
11292920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    if (FT->getNumParams() != 2 || FT->getReturnType() != FT->getParamType(0) ||
11302920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge        FT->getParamType(0) != FT->getParamType(1) ||
11312920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge        !FT->getParamType(0)->isFloatingPointTy())
11322920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      return Ret;
11332920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
11342920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    Value *Op1 = CI->getArgOperand(0), *Op2 = CI->getArgOperand(1);
11352920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    if (ConstantFP *Op1C = dyn_cast<ConstantFP>(Op1)) {
11362920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      if (Op1C->isExactlyValue(1.0))  // pow(1.0, x) -> 1.0
11372920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge        return Op1C;
11382920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      if (Op1C->isExactlyValue(2.0))  // pow(2.0, x) -> exp2(x)
11392920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge        return EmitUnaryFloatFnCall(Op2, "exp2", B, Callee->getAttributes());
11402920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    }
11412920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
11422920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    ConstantFP *Op2C = dyn_cast<ConstantFP>(Op2);
11432920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    if (Op2C == 0) return Ret;
11442920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
11452920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    if (Op2C->getValueAPF().isZero())  // pow(x, 0.0) -> 1.0
11462920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      return ConstantFP::get(CI->getType(), 1.0);
11472920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
11482920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    if (Op2C->isExactlyValue(0.5)) {
11492920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      // Expand pow(x, 0.5) to (x == -infinity ? +infinity : fabs(sqrt(x))).
11502920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      // This is faster than calling pow, and still handles negative zero
11512920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      // and negative infinity correctly.
11522920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      // TODO: In fast-math mode, this could be just sqrt(x).
11532920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      // TODO: In finite-only mode, this could be just fabs(sqrt(x)).
11542920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      Value *Inf = ConstantFP::getInfinity(CI->getType());
11552920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      Value *NegInf = ConstantFP::getInfinity(CI->getType(), true);
11562920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      Value *Sqrt = EmitUnaryFloatFnCall(Op1, "sqrt", B,
11572920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge                                         Callee->getAttributes());
11582920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      Value *FAbs = EmitUnaryFloatFnCall(Sqrt, "fabs", B,
11592920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge                                         Callee->getAttributes());
11602920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      Value *FCmp = B.CreateFCmpOEQ(Op1, NegInf);
11612920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      Value *Sel = B.CreateSelect(FCmp, Inf, FAbs);
11622920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      return Sel;
11632920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    }
11642920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
11652920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    if (Op2C->isExactlyValue(1.0))  // pow(x, 1.0) -> x
11662920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      return Op1;
11672920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    if (Op2C->isExactlyValue(2.0))  // pow(x, 2.0) -> x*x
11682920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      return B.CreateFMul(Op1, Op1, "pow2");
11692920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    if (Op2C->isExactlyValue(-1.0)) // pow(x, -1.0) -> 1.0/x
11702920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      return B.CreateFDiv(ConstantFP::get(CI->getType(), 1.0),
11712920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge                          Op1, "powrecip");
11722920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    return 0;
11732920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge  }
11742920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge};
11752920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
11762920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Ingestruct Exp2Opt : public UnsafeFPLibCallOptimization {
11772920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge  Exp2Opt(bool UnsafeFPShrink) : UnsafeFPLibCallOptimization(UnsafeFPShrink) {}
11782920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
11792920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    Value *Ret = NULL;
11802920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    if (UnsafeFPShrink && Callee->getName() == "exp2" &&
11812920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge        TLI->has(LibFunc::exp2)) {
11822920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true);
11832920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B);
11842920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    }
11852920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
11862920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    FunctionType *FT = Callee->getFunctionType();
11872920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    // Just make sure this has 1 argument of FP type, which matches the
11882920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    // result type.
11892920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) ||
11902920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge        !FT->getParamType(0)->isFloatingPointTy())
11912920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      return Ret;
11922920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
11932920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    Value *Op = CI->getArgOperand(0);
11942920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    // Turn exp2(sitofp(x)) -> ldexp(1.0, sext(x))  if sizeof(x) <= 32
11952920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    // Turn exp2(uitofp(x)) -> ldexp(1.0, zext(x))  if sizeof(x) < 32
11962920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    Value *LdExpArg = 0;
11972920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    if (SIToFPInst *OpC = dyn_cast<SIToFPInst>(Op)) {
11982920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() <= 32)
11992920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge        LdExpArg = B.CreateSExt(OpC->getOperand(0), B.getInt32Ty());
12002920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    } else if (UIToFPInst *OpC = dyn_cast<UIToFPInst>(Op)) {
12012920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() < 32)
12022920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge        LdExpArg = B.CreateZExt(OpC->getOperand(0), B.getInt32Ty());
12032920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    }
12042920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
12052920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    if (LdExpArg) {
12062920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      const char *Name;
12072920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      if (Op->getType()->isFloatTy())
12082920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge        Name = "ldexpf";
12092920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      else if (Op->getType()->isDoubleTy())
12102920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge        Name = "ldexp";
12112920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      else
12122920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge        Name = "ldexpl";
12132920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
12142920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      Constant *One = ConstantFP::get(*Context, APFloat(1.0f));
12152920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      if (!Op->getType()->isFloatTy())
12162920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge        One = ConstantExpr::getFPExtend(One, Op->getType());
12172920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
12182920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      Module *M = Caller->getParent();
12192920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
12202920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge                                             Op->getType(),
12212920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge                                             B.getInt32Ty(), NULL);
12222920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      CallInst *CI = B.CreateCall2(Callee, One, LdExpArg);
12232920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
12242920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge        CI->setCallingConv(F->getCallingConv());
12252920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
12262920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge      return CI;
12272920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    }
12282920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    return Ret;
12292920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge  }
12302920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge};
12312920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
123215d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge//===----------------------------------------------------------------------===//
123315d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge// Integer Library Call Optimizations
123415d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge//===----------------------------------------------------------------------===//
123515d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge
123615d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Ingestruct FFSOpt : public LibCallOptimization {
123715d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
123815d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge    FunctionType *FT = Callee->getFunctionType();
123915d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge    // Just make sure this has 2 arguments of the same FP type, which match the
124015d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge    // result type.
124115d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge    if (FT->getNumParams() != 1 ||
124215d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge        !FT->getReturnType()->isIntegerTy(32) ||
124315d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge        !FT->getParamType(0)->isIntegerTy())
124415d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge      return 0;
124515d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge
124615d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge    Value *Op = CI->getArgOperand(0);
124715d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge
124815d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge    // Constant fold.
124915d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge    if (ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
125015d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge      if (CI->isZero()) // ffs(0) -> 0.
125115d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge        return B.getInt32(0);
125215d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge      // ffs(c) -> cttz(c)+1
125315d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge      return B.getInt32(CI->getValue().countTrailingZeros() + 1);
125415d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge    }
125515d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge
125615d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge    // ffs(x) -> x != 0 ? (i32)llvm.cttz(x)+1 : 0
125715d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge    Type *ArgType = Op->getType();
125815d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge    Value *F = Intrinsic::getDeclaration(Callee->getParent(),
125915d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge                                         Intrinsic::cttz, ArgType);
126015d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge    Value *V = B.CreateCall2(F, Op, B.getFalse(), "cttz");
126115d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge    V = B.CreateAdd(V, ConstantInt::get(V->getType(), 1));
126215d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge    V = B.CreateIntCast(V, B.getInt32Ty(), false);
126315d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge
126415d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge    Value *Cond = B.CreateICmpNE(Op, Constant::getNullValue(ArgType));
126515d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge    return B.CreateSelect(Cond, V, B.getInt32(0));
126615d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge  }
126715d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge};
126815d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge
1269dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Ingestruct AbsOpt : public LibCallOptimization {
127033daeab1bb8df65273fd9ecbf1a261f96733732eChad Rosier  virtual bool ignoreCallingConv() { return true; }
1271dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1272dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge    FunctionType *FT = Callee->getFunctionType();
1273dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge    // We require integer(integer) where the types agree.
1274dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge    if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() ||
1275dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge        FT->getParamType(0) != FT->getReturnType())
1276dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge      return 0;
1277dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge
1278dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge    // abs(x) -> x >s -1 ? x : -x
1279dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge    Value *Op = CI->getArgOperand(0);
1280dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge    Value *Pos = B.CreateICmpSGT(Op, Constant::getAllOnesValue(Op->getType()),
1281dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge                                 "ispos");
1282dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge    Value *Neg = B.CreateNeg(Op, "neg");
1283dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge    return B.CreateSelect(Pos, Op, Neg);
1284dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge  }
1285dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge};
1286dfb3b1a779c62c1ee41f9cddcaad0b89278052aeMeador Inge
1287a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Ingestruct IsDigitOpt : public LibCallOptimization {
1288a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1289a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge    FunctionType *FT = Callee->getFunctionType();
1290a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge    // We require integer(i32)
1291a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge    if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() ||
1292a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge        !FT->getParamType(0)->isIntegerTy(32))
1293a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge      return 0;
1294a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge
1295a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge    // isdigit(c) -> (c-'0') <u 10
1296a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge    Value *Op = CI->getArgOperand(0);
1297a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge    Op = B.CreateSub(Op, B.getInt32('0'), "isdigittmp");
1298a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge    Op = B.CreateICmpULT(Op, B.getInt32(10), "isdigit");
1299a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge    return B.CreateZExt(Op, CI->getType());
1300a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge  }
1301a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge};
1302a0798ec3774de21f3ae3a7eba237e274e4c05ac3Meador Inge
1303017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Ingestruct IsAsciiOpt : public LibCallOptimization {
1304017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1305017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge    FunctionType *FT = Callee->getFunctionType();
1306017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge    // We require integer(i32)
1307017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge    if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() ||
1308017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge        !FT->getParamType(0)->isIntegerTy(32))
1309017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge      return 0;
1310017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge
1311017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge    // isascii(c) -> c <u 128
1312017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge    Value *Op = CI->getArgOperand(0);
1313017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge    Op = B.CreateICmpULT(Op, B.getInt32(128), "isascii");
1314017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge    return B.CreateZExt(Op, CI->getType());
1315017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge  }
1316017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge};
1317017bb750ab99b2ca54771fc86a6b2fed4ad90eecMeador Inge
131838c4441797a9c90dee830d9b90491742ff83d42cMeador Ingestruct ToAsciiOpt : public LibCallOptimization {
131938c4441797a9c90dee830d9b90491742ff83d42cMeador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
132038c4441797a9c90dee830d9b90491742ff83d42cMeador Inge    FunctionType *FT = Callee->getFunctionType();
132138c4441797a9c90dee830d9b90491742ff83d42cMeador Inge    // We require i32(i32)
132238c4441797a9c90dee830d9b90491742ff83d42cMeador Inge    if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) ||
132338c4441797a9c90dee830d9b90491742ff83d42cMeador Inge        !FT->getParamType(0)->isIntegerTy(32))
132438c4441797a9c90dee830d9b90491742ff83d42cMeador Inge      return 0;
132538c4441797a9c90dee830d9b90491742ff83d42cMeador Inge
1326d6d685985047634e1faf5460321e21d77ec6c1bfMeador Inge    // toascii(c) -> c & 0x7f
132738c4441797a9c90dee830d9b90491742ff83d42cMeador Inge    return B.CreateAnd(CI->getArgOperand(0),
132838c4441797a9c90dee830d9b90491742ff83d42cMeador Inge                       ConstantInt::get(CI->getType(),0x7F));
132938c4441797a9c90dee830d9b90491742ff83d42cMeador Inge  }
133038c4441797a9c90dee830d9b90491742ff83d42cMeador Inge};
133138c4441797a9c90dee830d9b90491742ff83d42cMeador Inge
1332d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge//===----------------------------------------------------------------------===//
1333d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge// Formatting and IO Library Call Optimizations
1334d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge//===----------------------------------------------------------------------===//
1335d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge
1336d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Ingestruct PrintFOpt : public LibCallOptimization {
1337d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge  Value *optimizeFixedFormatString(Function *Callee, CallInst *CI,
1338d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge                                   IRBuilder<> &B) {
1339d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    // Check for a fixed format string.
1340d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    StringRef FormatStr;
1341d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    if (!getConstantStringInfo(CI->getArgOperand(0), FormatStr))
1342d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      return 0;
1343d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge
1344d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    // Empty format string -> noop.
1345d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    if (FormatStr.empty())  // Tolerate printf's declared void.
1346d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      return CI->use_empty() ? (Value*)CI :
1347d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge                               ConstantInt::get(CI->getType(), 0);
1348d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge
1349d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    // Do not do any of the following transformations if the printf return value
1350d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    // is used, in general the printf return value is not compatible with either
1351d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    // putchar() or puts().
1352d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    if (!CI->use_empty())
1353d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      return 0;
1354d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge
1355d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    // printf("x") -> putchar('x'), even for '%'.
1356d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    if (FormatStr.size() == 1) {
1357d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      Value *Res = EmitPutChar(B.getInt32(FormatStr[0]), B, TD, TLI);
1358d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      if (CI->use_empty() || !Res) return Res;
1359d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      return B.CreateIntCast(Res, CI->getType(), true);
1360d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    }
1361d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge
1362d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    // printf("foo\n") --> puts("foo")
1363d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    if (FormatStr[FormatStr.size()-1] == '\n' &&
1364d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge        FormatStr.find('%') == std::string::npos) {  // no format characters.
1365d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      // Create a string literal with no \n on it.  We expect the constant merge
1366d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      // pass to be run after this pass, to merge duplicate strings.
1367d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      FormatStr = FormatStr.drop_back();
1368d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      Value *GV = B.CreateGlobalString(FormatStr, "str");
1369d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      Value *NewCI = EmitPutS(GV, B, TD, TLI);
1370d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      return (CI->use_empty() || !NewCI) ?
1371d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge              NewCI :
1372d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge              ConstantInt::get(CI->getType(), FormatStr.size()+1);
1373d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    }
1374d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge
1375d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    // Optimize specific format strings.
1376d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    // printf("%c", chr) --> putchar(chr)
1377d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    if (FormatStr == "%c" && CI->getNumArgOperands() > 1 &&
1378d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge        CI->getArgOperand(1)->getType()->isIntegerTy()) {
1379d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      Value *Res = EmitPutChar(CI->getArgOperand(1), B, TD, TLI);
1380d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge
1381d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      if (CI->use_empty() || !Res) return Res;
1382d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      return B.CreateIntCast(Res, CI->getType(), true);
1383d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    }
1384d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge
1385d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    // printf("%s\n", str) --> puts(str)
1386d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    if (FormatStr == "%s\n" && CI->getNumArgOperands() > 1 &&
1387d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge        CI->getArgOperand(1)->getType()->isPointerTy()) {
1388d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      return EmitPutS(CI->getArgOperand(1), B, TD, TLI);
1389d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    }
1390d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    return 0;
1391d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge  }
1392d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge
1393d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1394d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    // Require one fixed pointer argument and an integer/void result.
1395d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    FunctionType *FT = Callee->getFunctionType();
1396d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    if (FT->getNumParams() < 1 || !FT->getParamType(0)->isPointerTy() ||
1397d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge        !(FT->getReturnType()->isIntegerTy() ||
1398d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge          FT->getReturnType()->isVoidTy()))
1399d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      return 0;
1400d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge
1401d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    if (Value *V = optimizeFixedFormatString(Callee, CI, B)) {
1402d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      return V;
1403d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    }
1404d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge
1405d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    // printf(format, ...) -> iprintf(format, ...) if no floating point
1406d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    // arguments.
1407d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    if (TLI->has(LibFunc::iprintf) && !callHasFloatingPointArgument(CI)) {
1408d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      Module *M = B.GetInsertBlock()->getParent()->getParent();
1409d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      Constant *IPrintFFn =
1410d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge        M->getOrInsertFunction("iprintf", FT, Callee->getAttributes());
1411d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      CallInst *New = cast<CallInst>(CI->clone());
1412d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      New->setCalledFunction(IPrintFFn);
1413d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      B.Insert(New);
1414d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge      return New;
1415d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    }
1416d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge    return 0;
1417d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge  }
1418d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge};
1419d7aa3231f75174810a3443e6c2e1993ddefc1dd2Meador Inge
142069ea027e045f359b48bd436d530fc443a7cbb5c9Meador Ingestruct SPrintFOpt : public LibCallOptimization {
142169ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge  Value *OptimizeFixedFormatString(Function *Callee, CallInst *CI,
142269ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge                                   IRBuilder<> &B) {
142369ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    // Check for a fixed format string.
142469ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    StringRef FormatStr;
142569ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    if (!getConstantStringInfo(CI->getArgOperand(1), FormatStr))
142669ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      return 0;
142769ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge
142869ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    // If we just have a format string (nothing else crazy) transform it.
142969ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    if (CI->getNumArgOperands() == 2) {
143069ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      // Make sure there's no % in the constant array.  We could try to handle
143169ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      // %% -> % in the future if we cared.
143269ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      for (unsigned i = 0, e = FormatStr.size(); i != e; ++i)
143369ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge        if (FormatStr[i] == '%')
143469ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge          return 0; // we found a format specifier, bail out.
143569ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge
143669ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      // These optimizations require DataLayout.
143769ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      if (!TD) return 0;
143869ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge
143969ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      // sprintf(str, fmt) -> llvm.memcpy(str, fmt, strlen(fmt)+1, 1)
144069ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
144169ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge                     ConstantInt::get(TD->getIntPtrType(*Context), // Copy the
144269ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge                                      FormatStr.size() + 1), 1);   // nul byte.
144369ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      return ConstantInt::get(CI->getType(), FormatStr.size());
144469ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    }
144569ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge
144669ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    // The remaining optimizations require the format string to be "%s" or "%c"
144769ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    // and have an extra operand.
144869ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    if (FormatStr.size() != 2 || FormatStr[0] != '%' ||
144969ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge        CI->getNumArgOperands() < 3)
145069ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      return 0;
145169ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge
145269ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    // Decode the second character of the format string.
145369ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    if (FormatStr[1] == 'c') {
145469ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      // sprintf(dst, "%c", chr) --> *(i8*)dst = chr; *((i8*)dst+1) = 0
145569ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      if (!CI->getArgOperand(2)->getType()->isIntegerTy()) return 0;
145669ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      Value *V = B.CreateTrunc(CI->getArgOperand(2), B.getInt8Ty(), "char");
145769ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      Value *Ptr = CastToCStr(CI->getArgOperand(0), B);
145869ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      B.CreateStore(V, Ptr);
145969ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      Ptr = B.CreateGEP(Ptr, B.getInt32(1), "nul");
146069ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      B.CreateStore(B.getInt8(0), Ptr);
146169ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge
146269ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      return ConstantInt::get(CI->getType(), 1);
146369ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    }
146469ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge
146569ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    if (FormatStr[1] == 's') {
146669ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      // These optimizations require DataLayout.
146769ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      if (!TD) return 0;
146869ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge
146969ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      // sprintf(dest, "%s", str) -> llvm.memcpy(dest, str, strlen(str)+1, 1)
147069ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      if (!CI->getArgOperand(2)->getType()->isPointerTy()) return 0;
147169ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge
147269ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      Value *Len = EmitStrLen(CI->getArgOperand(2), B, TD, TLI);
147369ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      if (!Len)
147469ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge        return 0;
147569ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      Value *IncLen = B.CreateAdd(Len,
147669ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge                                  ConstantInt::get(Len->getType(), 1),
147769ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge                                  "leninc");
147869ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(2), IncLen, 1);
147969ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge
148069ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      // The sprintf result is the unincremented number of bytes in the string.
148169ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      return B.CreateIntCast(Len, CI->getType(), false);
148269ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    }
148369ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    return 0;
148469ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge  }
148569ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge
148669ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
148769ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    // Require two fixed pointer arguments and an integer result.
148869ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    FunctionType *FT = Callee->getFunctionType();
148969ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() ||
149069ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge        !FT->getParamType(1)->isPointerTy() ||
149169ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge        !FT->getReturnType()->isIntegerTy())
149269ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      return 0;
149369ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge
149469ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    if (Value *V = OptimizeFixedFormatString(Callee, CI, B)) {
149569ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      return V;
149669ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    }
149769ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge
149869ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    // sprintf(str, format, ...) -> siprintf(str, format, ...) if no floating
149969ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    // point arguments.
150069ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    if (TLI->has(LibFunc::siprintf) && !callHasFloatingPointArgument(CI)) {
150169ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      Module *M = B.GetInsertBlock()->getParent()->getParent();
150269ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      Constant *SIPrintFFn =
150369ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge        M->getOrInsertFunction("siprintf", FT, Callee->getAttributes());
150469ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      CallInst *New = cast<CallInst>(CI->clone());
150569ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      New->setCalledFunction(SIPrintFFn);
150669ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      B.Insert(New);
150769ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge      return New;
150869ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    }
150969ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge    return 0;
151069ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge  }
151169ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge};
151269ea027e045f359b48bd436d530fc443a7cbb5c9Meador Inge
151328d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Ingestruct FPrintFOpt : public LibCallOptimization {
151428d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge  Value *optimizeFixedFormatString(Function *Callee, CallInst *CI,
151528d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge                                   IRBuilder<> &B) {
151628d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    // All the optimizations depend on the format string.
151728d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    StringRef FormatStr;
151828d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    if (!getConstantStringInfo(CI->getArgOperand(1), FormatStr))
151928d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge      return 0;
152028d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge
1521c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne    // Do not do any of the following transformations if the fprintf return
1522c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne    // value is used, in general the fprintf return value is not compatible
1523c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne    // with fwrite(), fputc() or fputs().
1524c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne    if (!CI->use_empty())
1525c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne      return 0;
1526c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne
152728d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    // fprintf(F, "foo") --> fwrite("foo", 3, 1, F)
152828d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    if (CI->getNumArgOperands() == 2) {
152928d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge      for (unsigned i = 0, e = FormatStr.size(); i != e; ++i)
153028d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge        if (FormatStr[i] == '%')  // Could handle %% -> % if we cared.
153128d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge          return 0; // We found a format specifier.
153228d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge
153328d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge      // These optimizations require DataLayout.
153428d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge      if (!TD) return 0;
153528d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge
1536c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne      return EmitFWrite(CI->getArgOperand(1),
1537c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne                        ConstantInt::get(TD->getIntPtrType(*Context),
1538c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne                                         FormatStr.size()),
1539c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne                        CI->getArgOperand(0), B, TD, TLI);
154028d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    }
154128d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge
154228d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    // The remaining optimizations require the format string to be "%s" or "%c"
154328d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    // and have an extra operand.
154428d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    if (FormatStr.size() != 2 || FormatStr[0] != '%' ||
154528d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge        CI->getNumArgOperands() < 3)
154628d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge      return 0;
154728d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge
154828d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    // Decode the second character of the format string.
154928d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    if (FormatStr[1] == 'c') {
155028d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge      // fprintf(F, "%c", chr) --> fputc(chr, F)
155128d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge      if (!CI->getArgOperand(2)->getType()->isIntegerTy()) return 0;
1552c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne      return EmitFPutC(CI->getArgOperand(2), CI->getArgOperand(0), B, TD, TLI);
155328d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    }
155428d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge
155528d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    if (FormatStr[1] == 's') {
155628d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge      // fprintf(F, "%s", str) --> fputs(str, F)
1557c7ab4f99beceef00525f9a7df9ef58e63225cc7fPeter Collingbourne      if (!CI->getArgOperand(2)->getType()->isPointerTy())
155828d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge        return 0;
155928d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge      return EmitFPutS(CI->getArgOperand(2), CI->getArgOperand(0), B, TD, TLI);
156028d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    }
156128d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    return 0;
156228d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge  }
156328d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge
156428d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
156528d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    // Require two fixed paramters as pointers and integer result.
156628d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    FunctionType *FT = Callee->getFunctionType();
156728d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() ||
156828d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge        !FT->getParamType(1)->isPointerTy() ||
156928d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge        !FT->getReturnType()->isIntegerTy())
157028d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge      return 0;
157128d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge
157228d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    if (Value *V = optimizeFixedFormatString(Callee, CI, B)) {
157328d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge      return V;
157428d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    }
157528d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge
157628d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    // fprintf(stream, format, ...) -> fiprintf(stream, format, ...) if no
157728d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    // floating point arguments.
157828d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    if (TLI->has(LibFunc::fiprintf) && !callHasFloatingPointArgument(CI)) {
157928d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge      Module *M = B.GetInsertBlock()->getParent()->getParent();
158028d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge      Constant *FIPrintFFn =
158128d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge        M->getOrInsertFunction("fiprintf", FT, Callee->getAttributes());
158228d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge      CallInst *New = cast<CallInst>(CI->clone());
158328d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge      New->setCalledFunction(FIPrintFFn);
158428d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge      B.Insert(New);
158528d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge      return New;
158628d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    }
158728d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge    return 0;
158828d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge  }
158928d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge};
159028d52913ab0cda3fa21a4b16ad87fea4321b5e7eMeador Inge
1591c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Ingestruct FWriteOpt : public LibCallOptimization {
1592c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1593c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge    // Require a pointer, an integer, an integer, a pointer, returning integer.
1594c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge    FunctionType *FT = Callee->getFunctionType();
1595c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge    if (FT->getNumParams() != 4 || !FT->getParamType(0)->isPointerTy() ||
1596c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge        !FT->getParamType(1)->isIntegerTy() ||
1597c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge        !FT->getParamType(2)->isIntegerTy() ||
1598c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge        !FT->getParamType(3)->isPointerTy() ||
1599c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge        !FT->getReturnType()->isIntegerTy())
1600c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge      return 0;
1601c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge
1602c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge    // Get the element size and count.
1603c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge    ConstantInt *SizeC = dyn_cast<ConstantInt>(CI->getArgOperand(1));
1604c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge    ConstantInt *CountC = dyn_cast<ConstantInt>(CI->getArgOperand(2));
1605c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge    if (!SizeC || !CountC) return 0;
1606c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge    uint64_t Bytes = SizeC->getZExtValue()*CountC->getZExtValue();
1607c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge
1608c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge    // If this is writing zero records, remove the call (it's a noop).
1609c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge    if (Bytes == 0)
1610c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge      return ConstantInt::get(CI->getType(), 0);
1611c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge
1612c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge    // If this is writing one byte, turn it into fputc.
1613c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge    // This optimisation is only valid, if the return value is unused.
1614c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge    if (Bytes == 1 && CI->use_empty()) {  // fwrite(S,1,1,F) -> fputc(S[0],F)
1615c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge      Value *Char = B.CreateLoad(CastToCStr(CI->getArgOperand(0), B), "char");
1616c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge      Value *NewCI = EmitFPutC(Char, CI->getArgOperand(3), B, TD, TLI);
1617c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge      return NewCI ? ConstantInt::get(CI->getType(), 1) : 0;
1618c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge    }
1619c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge
1620c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge    return 0;
1621c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge  }
1622c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge};
1623c2e331275bac0e5e16f24bdb3ae4bc39a3caba5bMeador Inge
16245c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Ingestruct FPutsOpt : public LibCallOptimization {
16255c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
16265c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge    // These optimizations require DataLayout.
16275c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge    if (!TD) return 0;
16285c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge
16295c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge    // Require two pointers.  Also, we can't optimize if return value is used.
16305c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge    FunctionType *FT = Callee->getFunctionType();
16315c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge    if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() ||
16325c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge        !FT->getParamType(1)->isPointerTy() ||
16335c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge        !CI->use_empty())
16345c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge      return 0;
16355c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge
16365c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge    // fputs(s,F) --> fwrite(s,1,strlen(s),F)
16375c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge    uint64_t Len = GetStringLength(CI->getArgOperand(0));
16385c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge    if (!Len) return 0;
16395c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge    // Known to have no uses (see above).
16405c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge    return EmitFWrite(CI->getArgOperand(0),
16415c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge                      ConstantInt::get(TD->getIntPtrType(*Context), Len-1),
16425c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge                      CI->getArgOperand(1), B, TD, TLI);
16435c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge  }
16445c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge};
16455c5e230ac7ab03937f685baaf78525fd2b8154f1Meador Inge
1646aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Ingestruct PutsOpt : public LibCallOptimization {
1647aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge  virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1648aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge    // Require one fixed pointer argument and an integer/void result.
1649aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge    FunctionType *FT = Callee->getFunctionType();
1650aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge    if (FT->getNumParams() < 1 || !FT->getParamType(0)->isPointerTy() ||
1651aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge        !(FT->getReturnType()->isIntegerTy() ||
1652aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge          FT->getReturnType()->isVoidTy()))
1653aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge      return 0;
1654aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge
1655aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge    // Check for a constant string.
1656aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge    StringRef Str;
1657aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge    if (!getConstantStringInfo(CI->getArgOperand(0), Str))
1658aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge      return 0;
1659aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge
1660aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge    if (Str.empty() && CI->use_empty()) {
1661aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge      // puts("") -> putchar('\n')
1662aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge      Value *Res = EmitPutChar(B.getInt32('\n'), B, TD, TLI);
1663aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge      if (CI->use_empty() || !Res) return Res;
1664aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge      return B.CreateIntCast(Res, CI->getType(), true);
1665aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge    }
1666aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge
1667aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge    return 0;
1668aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge  }
1669aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge};
1670aa8cccf1292503f4a5d3fc55610f9a24f6dbee74Meador Inge
16715e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge} // End anonymous namespace.
16725e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
16735e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingenamespace llvm {
16745e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
16755e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingeclass LibCallSimplifierImpl {
16765e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  const DataLayout *TD;
16775e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  const TargetLibraryInfo *TLI;
1678b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge  const LibCallSimplifier *LCS;
16792920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge  bool UnsafeFPShrink;
1680bb51ec8b62c2819882b82a2510bf4df6f459bd51Meador Inge
16812920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge  // Math library call optimizations.
168267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  CosOpt Cos;
168367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  PowOpt Pow;
168467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  Exp2Opt Exp2;
16855e8904576a5260cfd5b14596e338a4bb25b9817eMeador Ingepublic:
1686b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge  LibCallSimplifierImpl(const DataLayout *TD, const TargetLibraryInfo *TLI,
16872920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge                        const LibCallSimplifier *LCS,
16882920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge                        bool UnsafeFPShrink = false)
168967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge    : Cos(UnsafeFPShrink), Pow(UnsafeFPShrink), Exp2(UnsafeFPShrink) {
16905e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    this->TD = TD;
16915e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    this->TLI = TLI;
1692b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge    this->LCS = LCS;
16932920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge    this->UnsafeFPShrink = UnsafeFPShrink;
16945e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  }
16955e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
16965e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  Value *optimizeCall(CallInst *CI);
169767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  LibCallOptimization *lookupOptimization(CallInst *CI);
169867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  bool hasFloatVersion(StringRef FuncName);
16995e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge};
17005e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
170167cb638629c69ab8c896175f58b4f472de5988d9Meador Ingebool LibCallSimplifierImpl::hasFloatVersion(StringRef FuncName) {
170267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  LibFunc::Func Func;
170367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  SmallString<20> FloatFuncName = FuncName;
170467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  FloatFuncName += 'f';
170567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  if (TLI->getLibFunc(FloatFuncName, Func))
170667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge    return TLI->has(Func);
170767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  return false;
170867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge}
17092920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
171067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge// Fortified library call optimizations.
171167cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic MemCpyChkOpt MemCpyChk;
171267cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic MemMoveChkOpt MemMoveChk;
171367cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic MemSetChkOpt MemSetChk;
171467cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrCpyChkOpt StrCpyChk;
171567cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StpCpyChkOpt StpCpyChk;
171667cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrNCpyChkOpt StrNCpyChk;
171767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge
171867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge// String library call optimizations.
171967cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrCatOpt StrCat;
172067cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrNCatOpt StrNCat;
172167cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrChrOpt StrChr;
172267cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrRChrOpt StrRChr;
172367cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrCmpOpt StrCmp;
172467cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrNCmpOpt StrNCmp;
172567cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrCpyOpt StrCpy;
172667cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StpCpyOpt StpCpy;
172767cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrNCpyOpt StrNCpy;
172867cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrLenOpt StrLen;
172967cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrPBrkOpt StrPBrk;
173067cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrToOpt StrTo;
173167cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrSpnOpt StrSpn;
173267cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrCSpnOpt StrCSpn;
173367cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic StrStrOpt StrStr;
173467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge
173567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge// Memory library call optimizations.
173667cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic MemCmpOpt MemCmp;
173767cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic MemCpyOpt MemCpy;
173867cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic MemMoveOpt MemMove;
173967cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic MemSetOpt MemSet;
174067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge
174167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge// Math library call optimizations.
174267cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic UnaryDoubleFPOpt UnaryDoubleFP(false);
174367cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true);
174467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge
174567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  // Integer library call optimizations.
174667cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic FFSOpt FFS;
174767cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic AbsOpt Abs;
174867cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic IsDigitOpt IsDigit;
174967cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic IsAsciiOpt IsAscii;
175067cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic ToAsciiOpt ToAscii;
175167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge
175267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge// Formatting and IO library call optimizations.
175367cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic PrintFOpt PrintF;
175467cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic SPrintFOpt SPrintF;
175567cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic FPrintFOpt FPrintF;
175667cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic FWriteOpt FWrite;
175767cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic FPutsOpt FPuts;
175867cb638629c69ab8c896175f58b4f472de5988d9Meador Ingestatic PutsOpt Puts;
175967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge
176067cb638629c69ab8c896175f58b4f472de5988d9Meador IngeLibCallOptimization *LibCallSimplifierImpl::lookupOptimization(CallInst *CI) {
176167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  LibFunc::Func Func;
176267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  Function *Callee = CI->getCalledFunction();
176367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  StringRef FuncName = Callee->getName();
176467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge
176567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  // Next check for intrinsics.
176667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) {
176767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge    switch (II->getIntrinsicID()) {
176867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge    case Intrinsic::pow:
176967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge       return &Pow;
177067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge    case Intrinsic::exp2:
177167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge       return &Exp2;
177267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge    default:
177367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge       return 0;
177467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge    }
17752920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge  }
17762920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge
177767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  // Then check for known library functions.
177867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  if (TLI->getLibFunc(FuncName, Func) && TLI->has(Func)) {
177967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge    switch (Func) {
178067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::strcat:
178167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &StrCat;
178267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::strncat:
178367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &StrNCat;
178467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::strchr:
178567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &StrChr;
178667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::strrchr:
178767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &StrRChr;
178867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::strcmp:
178967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &StrCmp;
179067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::strncmp:
179167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &StrNCmp;
179267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::strcpy:
179367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &StrCpy;
179467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::stpcpy:
179567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &StpCpy;
179667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::strncpy:
179767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &StrNCpy;
179867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::strlen:
179967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &StrLen;
180067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::strpbrk:
180167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &StrPBrk;
180267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::strtol:
180367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::strtod:
180467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::strtof:
180567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::strtoul:
180667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::strtoll:
180767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::strtold:
180867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::strtoull:
180967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &StrTo;
181067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::strspn:
181167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &StrSpn;
181267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::strcspn:
181367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &StrCSpn;
181467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::strstr:
181567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &StrStr;
181667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::memcmp:
181767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &MemCmp;
181867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::memcpy:
181967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &MemCpy;
182067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::memmove:
182167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &MemMove;
182267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::memset:
182367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &MemSet;
182467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::cosf:
182567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::cos:
182667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::cosl:
182767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &Cos;
182867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::powf:
182967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::pow:
183067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::powl:
183167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &Pow;
183267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::exp2l:
183367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::exp2:
183467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::exp2f:
183567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &Exp2;
183667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::ffs:
183767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::ffsl:
183867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::ffsll:
183967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &FFS;
184067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::abs:
184167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::labs:
184267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::llabs:
184367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &Abs;
184467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::isdigit:
184567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &IsDigit;
184667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::isascii:
184767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &IsAscii;
184867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::toascii:
184967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &ToAscii;
185067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::printf:
185167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &PrintF;
185267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::sprintf:
185367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &SPrintF;
185467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::fprintf:
185567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &FPrintF;
185667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::fwrite:
185767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &FWrite;
185867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::fputs:
185967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &FPuts;
186067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::puts:
186167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &Puts;
186267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::ceil:
186367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::fabs:
186467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::floor:
186567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::rint:
186667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::round:
186767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::nearbyint:
186867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::trunc:
186967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        if (hasFloatVersion(FuncName))
187067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge          return &UnaryDoubleFP;
187167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return 0;
187267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::acos:
187367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::acosh:
187467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::asin:
187567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::asinh:
187667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::atan:
187767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::atanh:
187867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::cbrt:
187967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::cosh:
188067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::exp:
188167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::exp10:
188267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::expm1:
188367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::log:
188467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::log10:
188567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::log1p:
188667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::log2:
188767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::logb:
188867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::sin:
188967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::sinh:
189067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::sqrt:
189167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::tan:
189267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::tanh:
189367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        if (UnsafeFPShrink && hasFloatVersion(FuncName))
189467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge         return &UnsafeUnaryDoubleFP;
189567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return 0;
189667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      case LibFunc::memcpy_chk:
189767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return &MemCpyChk;
189867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      default:
189967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge        return 0;
190067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      }
190167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  }
190267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge
190367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  // Finally check for fortified library calls.
190467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  if (FuncName.endswith("_chk")) {
190567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge    if (FuncName == "__memmove_chk")
190667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      return &MemMoveChk;
190767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge    else if (FuncName == "__memset_chk")
190867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      return &MemSetChk;
190967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge    else if (FuncName == "__strcpy_chk")
191067cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      return &StrCpyChk;
191167cb638629c69ab8c896175f58b4f472de5988d9Meador Inge    else if (FuncName == "__stpcpy_chk")
191267cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      return &StpCpyChk;
191367cb638629c69ab8c896175f58b4f472de5988d9Meador Inge    else if (FuncName == "__strncpy_chk")
191467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      return &StrNCpyChk;
191567cb638629c69ab8c896175f58b4f472de5988d9Meador Inge    else if (FuncName == "__stpncpy_chk")
191667cb638629c69ab8c896175f58b4f472de5988d9Meador Inge      return &StrNCpyChk;
191767cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  }
191867cb638629c69ab8c896175f58b4f472de5988d9Meador Inge
191967cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  return 0;
192015d099a790f3fd6f8f643c4e7c50a1659f4fc92bMeador Inge
19215e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge}
19225e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
19235e8904576a5260cfd5b14596e338a4bb25b9817eMeador IngeValue *LibCallSimplifierImpl::optimizeCall(CallInst *CI) {
192467cb638629c69ab8c896175f58b4f472de5988d9Meador Inge  LibCallOptimization *LCO = lookupOptimization(CI);
19255e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  if (LCO) {
19265e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge    IRBuilder<> Builder(CI);
1927b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge    return LCO->optimizeCall(CI, TD, TLI, LCS, Builder);
19285e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  }
19295e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  return 0;
19305e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge}
19315e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
19325e8904576a5260cfd5b14596e338a4bb25b9817eMeador IngeLibCallSimplifier::LibCallSimplifier(const DataLayout *TD,
19332920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge                                     const TargetLibraryInfo *TLI,
19342920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge                                     bool UnsafeFPShrink) {
19352920a71663b96f2c33b1fee09ca5ca9f5dc1cf12Meador Inge  Impl = new LibCallSimplifierImpl(TD, TLI, this, UnsafeFPShrink);
19365e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge}
19375e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
19385e8904576a5260cfd5b14596e338a4bb25b9817eMeador IngeLibCallSimplifier::~LibCallSimplifier() {
19395e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  delete Impl;
19405e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge}
19415e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
19425e8904576a5260cfd5b14596e338a4bb25b9817eMeador IngeValue *LibCallSimplifier::optimizeCall(CallInst *CI) {
19432253a2f52f3c46ae75cd05f5885acb987bd1d6b6Michael Gottesman  if (CI->isNoBuiltin()) return 0;
19445e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge  return Impl->optimizeCall(CI);
19455e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge}
19465e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge
1947b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Ingevoid LibCallSimplifier::replaceAllUsesWith(Instruction *I, Value *With) const {
1948b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge  I->replaceAllUsesWith(With);
1949b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge  I->eraseFromParent();
1950b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge}
1951b69bf6be1b042a5f06a623fc546107fc6d9f46c4Meador Inge
19525e8904576a5260cfd5b14596e338a4bb25b9817eMeador Inge}
1953be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge
1954be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// TODO:
1955be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   Additional cases that we need to add to this file:
1956be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//
1957be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// cbrt:
1958be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * cbrt(expN(X))  -> expN(x/3)
1959be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * cbrt(sqrt(x))  -> pow(x,1/6)
1960be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * cbrt(sqrt(x))  -> pow(x,1/9)
1961be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//
1962be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// exp, expf, expl:
1963be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * exp(log(x))  -> x
1964be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//
1965be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// log, logf, logl:
1966be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * log(exp(x))   -> x
1967be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * log(x**y)     -> y*log(x)
1968be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * log(exp(y))   -> y*log(e)
1969be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * log(exp2(y))  -> y*log(2)
1970be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * log(exp10(y)) -> y*log(10)
1971be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * log(sqrt(x))  -> 0.5*log(x)
1972be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * log(pow(x,y)) -> y*log(x)
1973be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//
1974be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// lround, lroundf, lroundl:
1975be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * lround(cnst) -> cnst'
1976be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//
1977be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// pow, powf, powl:
1978be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * pow(exp(x),y)  -> exp(x*y)
1979be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * pow(sqrt(x),y) -> pow(x,y*0.5)
1980be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * pow(pow(x,y),z)-> pow(x,y*z)
1981be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//
1982be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// round, roundf, roundl:
1983be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * round(cnst) -> cnst'
1984be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//
1985be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// signbit:
1986be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * signbit(cnst) -> cnst'
1987be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * signbit(nncst) -> 0 (if pstv is a non-negative constant)
1988be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//
1989be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// sqrt, sqrtf, sqrtl:
1990be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * sqrt(expN(x))  -> expN(x*0.5)
1991be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * sqrt(Nroot(x)) -> pow(x,1/(2*N))
1992be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * sqrt(pow(x,y)) -> pow(|x|,y*0.5)
1993be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//
1994be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// strchr:
1995be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * strchr(p, 0) -> strlen(p)
1996be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// tan, tanf, tanl:
1997be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * tan(atan(x)) -> x
1998be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//
1999be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge// trunc, truncf, truncl:
2000be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//   * trunc(cnst) -> cnst'
2001be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//
2002be87bce32bc9af9bc5918a6e08806b61e3088165Meador Inge//
2003