SimplifyLibCalls.cpp revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
1424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)//===------ SimplifyLibCalls.cpp - Library calls simplifier ---------------===// 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The LLVM Compiler Infrastructure 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 5424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// License. See LICENSE.TXT for details. 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This is a utility pass used for testing the InstructionSimplify analysis. 119ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch// The analysis is applied to every instruction, and if it simplifies then the 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// instruction is replaced by the simplification. If you are looking for a pass 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// that performs serious instruction folding, use the instcombine pass instead. 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch//===----------------------------------------------------------------------===// 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/Transforms/Utils/SimplifyLibCalls.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "llvm/ADT/SmallString.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/ADT/StringMap.h" 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "llvm/ADT/Triple.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/Analysis/ValueTracking.h" 2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "llvm/IR/DataLayout.h" 2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "llvm/IR/DiagnosticInfo.h" 2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "llvm/IR/Function.h" 2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "llvm/IR/IRBuilder.h" 2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "llvm/IR/IntrinsicInst.h" 2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "llvm/IR/Intrinsics.h" 2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "llvm/IR/LLVMContext.h" 2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "llvm/IR/Module.h" 3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "llvm/Support/Allocator.h" 3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "llvm/Support/CommandLine.h" 3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "llvm/Target/TargetLibraryInfo.h" 3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "llvm/Transforms/Utils/BuildLibCalls.h" 3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)using namespace llvm; 3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)static cl::opt<bool> 3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)ColdErrorCalls("error-reporting-is-cold", cl::init(true), 3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) cl::Hidden, cl::desc("Treat error-reporting calls as cold")); 4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)/// This class is the abstract base class for the set of optimizations that 4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// corresponds to one library call. 4368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace { 4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class LibCallOptimization { 4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)protected: 4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Function *Caller; 4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const DataLayout *DL; 4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const TargetLibraryInfo *TLI; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LibCallSimplifier *LCS; 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LLVMContext* Context; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public: 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LibCallOptimization() { } 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual ~LibCallOptimization() {} 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// callOptimizer - This pure virtual method is implemented by base classes to 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// do various optimizations. If this returns null then no transformation was 57424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) /// performed. If it returns CI, then it transformed the call and CI is to be 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// deleted. If it returns something else, replace CI with the new value and 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// delete CI. 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) =0; 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /// ignoreCallingConv - Returns false if this transformation could possibly 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /// change the calling convention. 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool ignoreCallingConv() { return false; } 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Value *optimizeCall(CallInst *CI, const DataLayout *DL, 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const TargetLibraryInfo *TLI, 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LibCallSimplifier *LCS, IRBuilder<> &B) { 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Caller = CI->getParent()->getParent(); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this->DL = DL; 72424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) this->TLI = TLI; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this->LCS = LCS; 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (CI->getCalledFunction()) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Context = &CI->getCalledFunction()->getContext(); 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We never change the calling convention. 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!ignoreCallingConv() && CI->getCallingConv() != llvm::CallingConv::C) 7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return nullptr; 8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return callOptimizer(CI->getCalledFunction(), CI, B); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Helper Functions 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// isOnlyUsedInZeroEqualityComparison - Return true if it only matters that the 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// value is equal or not-equal to zero. 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static bool isOnlyUsedInZeroEqualityComparison(Value *V) { 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (User *U : V->users()) { 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ICmpInst *IC = dyn_cast<ICmpInst>(U)) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (IC->isEquality()) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Constant *C = dyn_cast<Constant>(IC->getOperand(1))) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (C->isNullValue()) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Unknown instruction. 9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// isOnlyUsedInEqualityComparison - Return true if it is only used in equality 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// comparisons with With. 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static bool isOnlyUsedInEqualityComparison(Value *V, Value *With) { 10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (User *U : V->users()) { 10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (ICmpInst *IC = dyn_cast<ICmpInst>(U)) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (IC->isEquality() && IC->getOperand(1) == With) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Unknown instruction. 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)static bool callHasFloatingPointArgument(const CallInst *CI) { 11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (CallInst::const_op_iterator it = CI->op_begin(), e = CI->op_end(); 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != e; ++it) { 12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if ((*it)->getType()->isFloatingPointTy()) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// \brief Check whether the overloaded unary floating point function 12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// corresponing to \a Ty is available. 12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)static bool hasUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty, 12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) LibFunc::Func DoubleFn, LibFunc::Func FloatFn, 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LibFunc::Func LongDoubleFn) { 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (Ty->getTypeID()) { 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case Type::FloatTyID: 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return TLI->has(FloatFn); 134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) case Type::DoubleTyID: 135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return TLI->has(DoubleFn); 13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) default: 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TLI->has(LongDoubleFn); 13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Fortified Library Call Optimizations 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct FortifiedLibCallOptimization : public LibCallOptimization { 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)protected: 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool isFoldable(unsigned SizeCIOp, unsigned SizeArgOp, 14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool isString) const = 0; 14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}; 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct InstFortifiedLibCallOptimization : public FortifiedLibCallOptimization { 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CallInst *CI; 15368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool isFoldable(unsigned SizeCIOp, unsigned SizeArgOp, 15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool isString) const override { 15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (CI->getArgOperand(SizeCIOp) == CI->getArgOperand(SizeArgOp)) 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ConstantInt *SizeCI = 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dyn_cast<ConstantInt>(CI->getArgOperand(SizeCIOp))) { 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (SizeCI->isAllOnesValue()) 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (isString) { 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64_t Len = GetStringLength(CI->getArgOperand(SizeArgOp)); 164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // If the length is 0 we don't know how long it is and so we can't 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // remove the check. 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (Len == 0) return false; 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SizeCI->getZExtValue() >= Len; 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (ConstantInt *Arg = dyn_cast<ConstantInt>( 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CI->getArgOperand(SizeArgOp))) 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SizeCI->getZExtValue() >= Arg->getZExtValue(); 17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct MemCpyChkOpt : public InstFortifiedLibCallOptimization { 17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Value *callOptimizer(Function *Callee, CallInst *CI, 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IRBuilder<> &B) override { 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this->CI = CI; 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FunctionType *FT = Callee->getFunctionType(); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LLVMContext &Context = CI->getParent()->getContext(); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check if this has the right signature. 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !FT->getParamType(0)->isPointerTy() || 18758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) !FT->getParamType(1)->isPointerTy() || 188a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FT->getParamType(2) != DL->getIntPtrType(Context) || 18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FT->getParamType(3) != DL->getIntPtrType(Context)) 19058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return nullptr; 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (isFoldable(3, 2, false)) { 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CI->getArgOperand(2), 1); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return CI->getArgOperand(0); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return nullptr; 19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)struct MemMoveChkOpt : public InstFortifiedLibCallOptimization { 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Value *callOptimizer(Function *Callee, CallInst *CI, 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IRBuilder<> &B) override { 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this->CI = CI; 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FunctionType *FT = Callee->getFunctionType(); 206a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) LLVMContext &Context = CI->getParent()->getContext(); 20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 208a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Check if this has the right signature. 20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) !FT->getParamType(0)->isPointerTy() || 211a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) !FT->getParamType(1)->isPointerTy() || 212a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FT->getParamType(2) != DL->getIntPtrType(Context) || 213a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FT->getParamType(3) != DL->getIntPtrType(Context)) 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return nullptr; 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (isFoldable(3, 2, false)) { 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1), 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CI->getArgOperand(2), 1); 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return CI->getArgOperand(0); 22068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return nullptr; 22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}; 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct MemSetChkOpt : public InstFortifiedLibCallOptimization { 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Value *callOptimizer(Function *Callee, CallInst *CI, 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IRBuilder<> &B) override { 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this->CI = CI; 22968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FunctionType *FT = Callee->getFunctionType(); 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LLVMContext &Context = CI->getParent()->getContext(); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check if this has the right signature. 233a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 23458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) !FT->getParamType(0)->isPointerTy() || 23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) !FT->getParamType(1)->isIntegerTy() || 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FT->getParamType(2) != DL->getIntPtrType(Context) || 237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FT->getParamType(3) != DL->getIntPtrType(Context)) 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return nullptr; 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (isFoldable(3, 2, false)) { 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) false); 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1); 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return CI->getArgOperand(0); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return nullptr; 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)struct StrCpyChkOpt : public InstFortifiedLibCallOptimization { 25158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Value *callOptimizer(Function *Callee, CallInst *CI, 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IRBuilder<> &B) override { 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this->CI = CI; 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StringRef Name = Callee->getName(); 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FunctionType *FT = Callee->getFunctionType(); 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LLVMContext &Context = CI->getParent()->getContext(); 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check if this has the right signature. 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (FT->getNumParams() != 3 || 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FT->getReturnType() != FT->getParamType(0) || 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FT->getParamType(0) != FT->getParamType(1) || 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FT->getParamType(0) != Type::getInt8PtrTy(Context) || 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FT->getParamType(2) != DL->getIntPtrType(Context)) 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return nullptr; 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1); 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (Dst == Src) // __strcpy_chk(x,x) -> x 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Src; 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If a) we don't have any length information, or b) we know this will 27158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // fit then just lower to a plain strcpy. Otherwise we'll keep our 27268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // strcpy_chk call which may fail at runtime if the size is too long. 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO: It might be nice to get a maximum length out of the possible 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // string lengths for varying. 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (isFoldable(2, 1, true)) { 276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Value *Ret = EmitStrCpy(Dst, Src, B, DL, TLI, Name.substr(2, 6)); 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Ret; 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Maybe we can stil fold __strcpy_chk to __memcpy_chk. 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64_t Len = GetStringLength(Src); 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Len == 0) return nullptr; 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // This optimization require DataLayout. 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!DL) return nullptr; 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Value *Ret = 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EmitMemCpyChk(Dst, Src, 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConstantInt::get(DL->getIntPtrType(Context), Len), 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CI->getArgOperand(2), B, DL, TLI); 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Ret; 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return nullptr; 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstruct StpCpyChkOpt : public InstFortifiedLibCallOptimization { 297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Value *callOptimizer(Function *Callee, CallInst *CI, 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IRBuilder<> &B) override { 299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch this->CI = CI; 300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StringRef Name = Callee->getName(); 301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FunctionType *FT = Callee->getFunctionType(); 302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LLVMContext &Context = CI->getParent()->getContext(); 303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Check if this has the right signature. 305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (FT->getNumParams() != 3 || 306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FT->getReturnType() != FT->getParamType(0) || 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FT->getParamType(0) != FT->getParamType(1) || 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FT->getParamType(0) != Type::getInt8PtrTy(Context) || 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FT->getParamType(2) != DL->getIntPtrType(FT->getParamType(0))) 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return nullptr; 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1); 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Dst == Src) { // stpcpy(x,x) -> x+strlen(x) 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Value *StrLen = EmitStrLen(Src, B, DL, TLI); 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return StrLen ? B.CreateInBoundsGEP(Dst, StrLen) : nullptr; 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If a) we don't have any length information, or b) we know this will 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // fit then just lower to a plain stpcpy. Otherwise we'll keep our 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // stpcpy_chk call which may fail at runtime if the size is too long. 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO: It might be nice to get a maximum length out of the possible 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // string lengths for varying. 323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (isFoldable(2, 1, true)) { 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Value *Ret = EmitStrCpy(Dst, Src, B, DL, TLI, Name.substr(2, 6)); 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Ret; 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Maybe we can stil fold __stpcpy_chk to __memcpy_chk. 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64_t Len = GetStringLength(Src); 329eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (Len == 0) return nullptr; 330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // This optimization require DataLayout. 332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!DL) return nullptr; 333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Type *PT = FT->getParamType(0); 335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Value *LenV = ConstantInt::get(DL->getIntPtrType(PT), Len); 336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Value *DstEnd = B.CreateGEP(Dst, 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConstantInt::get(DL->getIntPtrType(PT), 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Len - 1)); 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!EmitMemCpyChk(Dst, Src, LenV, CI->getArgOperand(2), B, DL, TLI)) 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return nullptr; 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return DstEnd; 34258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 34358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return nullptr; 34458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 34558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}; 346a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 347a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)struct StrNCpyChkOpt : public InstFortifiedLibCallOptimization { 348a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Value *callOptimizer(Function *Callee, CallInst *CI, 349a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) IRBuilder<> &B) override { 350a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) this->CI = CI; 351a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) StringRef Name = Callee->getName(); 352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FunctionType *FT = Callee->getFunctionType(); 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LLVMContext &Context = CI->getParent()->getContext(); 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check if this has the right signature. 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FT->getParamType(0) != FT->getParamType(1) || 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FT->getParamType(0) != Type::getInt8PtrTy(Context) || 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !FT->getParamType(2)->isIntegerTy() || 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FT->getParamType(3) != DL->getIntPtrType(Context)) 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return nullptr; 36258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 36358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (isFoldable(3, 2, false)) { 36458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Value *Ret = EmitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1), 36558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CI->getArgOperand(2), B, DL, TLI, 36668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Name.substr(2, 7)); 36768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return Ret; 36868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 36968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return nullptr; 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// String and Memory Library Call Optimizations 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct StrCatOpt : public LibCallOptimization { 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Value *callOptimizer(Function *Callee, CallInst *CI, 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IRBuilder<> &B) override { 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Verify the "strcat" function prototype. 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FunctionType *FT = Callee->getFunctionType(); 382ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (FT->getNumParams() != 2 || 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FT->getReturnType() != B.getInt8PtrTy() || 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FT->getParamType(0) != FT->getReturnType() || 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FT->getParamType(1) != FT->getReturnType()) 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return nullptr; 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Extract some information from the instruction 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Value *Dst = CI->getArgOperand(0); 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Value *Src = CI->getArgOperand(1); 3917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // See if we can get the length of the input string. 3937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch uint64_t Len = GetStringLength(Src); 3947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (Len == 0) return nullptr; 3957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch --Len; // Unbias length. 3967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Handle the simple, do-nothing case: strcat(x, "") -> x 3987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (Len == 0) 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return Dst; 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // These optimizations require DataLayout. 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!DL) return nullptr; 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return emitStrLenMemCpy(Src, Dst, Len, B); 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Value *emitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len, 40868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) IRBuilder<> &B) { 40968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // We need to find the end of the destination string. That's where the 41068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // memory is to be moved to. We just generate a call to strlen. 41168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Value *DstLen = EmitStrLen(Dst, B, DL, TLI); 41268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!DstLen) 41368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return nullptr; 41468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 41568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Now that we have the destination's length, we must index into the 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // destination's pointer to get the actual memcpy destination (end of 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the string .. we're concatenating). 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Value *CpyDst = B.CreateGEP(Dst, DstLen, "endptr"); 41968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We have enough information to now generate the memcpy call to do the 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // concatenation for us. Make a memcpy to copy the nul byte with align = 1. 422a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) B.CreateMemCpy(CpyDst, Src, 42368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ConstantInt::get(DL->getIntPtrType(*Context), Len + 1), 1); 424a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return Dst; 425a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 426a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}; 427a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 428a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)struct StrNCatOpt : public StrCatOpt { 429a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Value *callOptimizer(Function *Callee, CallInst *CI, 430a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) IRBuilder<> &B) override { 431a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Verify the "strncat" function prototype. 432a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FunctionType *FT = Callee->getFunctionType(); 43368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (FT->getNumParams() != 3 || 434a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FT->getReturnType() != B.getInt8PtrTy() || 435a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FT->getParamType(0) != FT->getReturnType() || 436a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FT->getParamType(1) != FT->getReturnType() || 437a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) !FT->getParamType(2)->isIntegerTy()) 438a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return nullptr; 43968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 440a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Extract some information from the instruction 441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Value *Dst = CI->getArgOperand(0); 442a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Value *Src = CI->getArgOperand(1); 443a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) uint64_t Len; 444a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 44558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch // We don't do anything if length is not constant 44658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2))) 44758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch Len = LengthArg->getZExtValue(); 44858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch else 44968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return nullptr; 45058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch 45158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch // See if we can get the length of the input string. 45258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch uint64_t SrcLen = GetStringLength(Src); 453a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (SrcLen == 0) return nullptr; 45468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) --SrcLen; // Unbias length. 455a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 456a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Handle the simple, do-nothing cases: 457a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // strncat(x, "", c) -> x 458a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // strncat(x, c, 0) -> x 459a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (SrcLen == 0 || Len == 0) return Dst; 460a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 461a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // These optimizations require DataLayout. 462a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!DL) return nullptr; 463a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 46468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // We don't optimize this case 465a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (Len < SrcLen) return nullptr; 466a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 467a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // strncat(x, s, c) -> strcat(x, s) 468a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // s is constant so the strcat can be optimized further 469a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return emitStrLenMemCpy(Src, Dst, SrcLen, B); 470424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct StrChrOpt : public LibCallOptimization { 4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Value *callOptimizer(Function *Callee, CallInst *CI, 4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IRBuilder<> &B) override { 4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Verify the "strchr" function prototype. 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FunctionType *FT = Callee->getFunctionType(); 47868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (FT->getNumParams() != 2 || 4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FT->getReturnType() != B.getInt8PtrTy() || 4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FT->getParamType(0) != FT->getReturnType() || 4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !FT->getParamType(1)->isIntegerTy(32)) 4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return nullptr; 4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Value *SrcStr = CI->getArgOperand(0); 4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 48690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If the second operand is non-constant, see if we can compute the length 487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // of the input string and turn this into memchr. 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getArgOperand(1)); 4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!CharC) { 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // These optimizations require DataLayout. 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!DL) return nullptr; 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64_t Len = GetStringLength(SrcStr); 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Len == 0 || !FT->getParamType(1)->isIntegerTy(32))// memchr needs i32. 49568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return nullptr; 49668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 49768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return EmitMemChr(SrcStr, CI->getArgOperand(1), // include nul. 49868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ConstantInt::get(DL->getIntPtrType(*Context), Len), 49968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) B, DL, TLI); 5003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 50268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Otherwise, the character is a constant, see if the first argument is 5033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // a string literal. If so, we can constant fold. 5043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StringRef Str; 5053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!getConstantStringInfo(SrcStr, Str)) { 5063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (DL && CharC->isZero()) // strchr(p, 0) -> p + strlen(p) 5073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return B.CreateGEP(SrcStr, EmitStrLen(SrcStr, B, DL, TLI), "strchr"); 5083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return nullptr; 5093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 51168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Compute the offset, make sure to handle the case when we're searching for 512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // zero (a weird way to spell strlen). 51368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) size_t I = (0xFF & CharC->getSExtValue()) == 0 ? 514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Str.size() : Str.find(CharC->getSExtValue()); 51568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (I == StringRef::npos) // Didn't find the char. strchr returns null. 51668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return Constant::getNullValue(CI->getType()); 5173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 51868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // strchr(s+n,c) -> gep(s+n+i,c) 5193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return B.CreateGEP(SrcStr, B.getInt64(I), "strchr"); 5203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 5223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 52368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)struct StrRChrOpt : public LibCallOptimization { 524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Value *callOptimizer(Function *Callee, CallInst *CI, 52568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) IRBuilder<> &B) override { 526eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Verify the "strrchr" function prototype. 527eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FunctionType *FT = Callee->getFunctionType(); 52868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (FT->getNumParams() != 2 || 52968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FT->getReturnType() != B.getInt8PtrTy() || 53068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FT->getParamType(0) != FT->getReturnType() || 53168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) !FT->getParamType(1)->isIntegerTy(32)) 53268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return nullptr; 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Value *SrcStr = CI->getArgOperand(0); 5353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getArgOperand(1)); 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 537eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Cannot fold anything if we're not looking for a constant. 53868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!CharC) 539a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return nullptr; 54068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 541a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) StringRef Str; 542a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!getConstantStringInfo(SrcStr, Str)) { 543a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // strrchr(s, 0) -> strchr(s, 0) 544a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (DL && CharC->isZero()) 545a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return EmitStrChr(SrcStr, '\0', B, DL, TLI); 546868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return nullptr; 547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Compute the offset. 5503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) size_t I = (0xFF & CharC->getSExtValue()) == 0 ? 55168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Str.size() : Str.rfind(CharC->getSExtValue()); 5523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (I == StringRef::npos) // Didn't find the char. Return null. 55368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return Constant::getNullValue(CI->getType()); 55468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // strrchr(s+n,c) -> gep(s+n+i,c) 5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return B.CreateGEP(SrcStr, B.getInt64(I), "strrchr"); 5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 5595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct StrCmpOpt : public LibCallOptimization { 5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Value *callOptimizer(Function *Callee, CallInst *CI, 56290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) IRBuilder<> &B) override { 563868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Verify the "strcmp" function prototype. 564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FunctionType *FT = Callee->getFunctionType(); 565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (FT->getNumParams() != 2 || 566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !FT->getReturnType()->isIntegerTy(32) || 567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FT->getParamType(0) != FT->getParamType(1) || 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FT->getParamType(0) != B.getInt8PtrTy()) 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return nullptr; 57068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 57168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1); 57268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (Str1P == Str2P) // strcmp(x,x) -> 0 57368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return ConstantInt::get(CI->getType(), 0); 57468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 57568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) StringRef Str1, Str2; 57668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool HasStr1 = getConstantStringInfo(Str1P, Str1); 57768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool HasStr2 = getConstantStringInfo(Str2P, Str2); 57868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 57968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // strcmp(x, y) -> cnst (if both x and y are constant strings) 58068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (HasStr1 && HasStr2) 58168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return ConstantInt::get(CI->getType(), Str1.compare(Str2)); 58268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 58368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (HasStr1 && Str1.empty()) // strcmp("", x) -> -*x 58468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return B.CreateNeg(B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"), 58568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CI->getType())); 58668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 58768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (HasStr2 && Str2.empty()) // strcmp(x,"") -> *x 58868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType()); 58968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 59068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // strcmp(P, "x") -> memcmp(P, "x", 2) 59168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) uint64_t Len1 = GetStringLength(Str1P); 592424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) uint64_t Len2 = GetStringLength(Str2P); 59358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (Len1 && Len2) { 59468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // These optimizations require DataLayout. 59568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!DL) return nullptr; 59668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 59768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return EmitMemCmp(Str1P, Str2P, 598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ConstantInt::get(DL->getIntPtrType(*Context), 599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::min(Len1, Len2)), B, DL, TLI); 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 601424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return nullptr; 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 60568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct StrNCmpOpt : public LibCallOptimization { 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Value *callOptimizer(Function *Callee, CallInst *CI, 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IRBuilder<> &B) override { 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Verify the "strncmp" function prototype. 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FunctionType *FT = Callee->getFunctionType(); 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (FT->getNumParams() != 3 || 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !FT->getReturnType()->isIntegerTy(32) || 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FT->getParamType(0) != FT->getParamType(1) || 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FT->getParamType(0) != B.getInt8PtrTy() || 615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !FT->getParamType(2)->isIntegerTy()) 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return nullptr; 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1); 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Str1P == Str2P) // strncmp(x,x,n) -> 0 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ConstantInt::get(CI->getType(), 0); 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Get the length argument if it is constant. 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64_t Length; 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2))) 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Length = LengthArg->getZExtValue(); 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return nullptr; 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Length == 0) // strncmp(x,y,0) -> 0 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ConstantInt::get(CI->getType(), 0); 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (DL && Length == 1) // strncmp(x,y,1) -> memcmp(x,y,1) 6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return EmitMemCmp(Str1P, Str2P, CI->getArgOperand(2), B, DL, TLI); 6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StringRef Str1, Str2; 6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool HasStr1 = getConstantStringInfo(Str1P, Str1); 6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool HasStr2 = getConstantStringInfo(Str2P, Str2); 6385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // strncmp(x, y) -> cnst (if both x and y are constant strings) 6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (HasStr1 && HasStr2) { 6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StringRef SubStr1 = Str1.substr(0, Length); 6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StringRef SubStr2 = Str2.substr(0, Length); 6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return ConstantInt::get(CI->getType(), SubStr1.compare(SubStr2)); 6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (HasStr1 && Str1.empty()) // strncmp("", x, n) -> -*x 6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return B.CreateNeg(B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"), 6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CI->getType())); 6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (HasStr2 && Str2.empty()) // strncmp(x, "", n) -> *x 65168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType()); 6525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return nullptr; 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct StrCpyOpt : public LibCallOptimization { 658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Value *callOptimizer(Function *Callee, CallInst *CI, 65968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) IRBuilder<> &B) override { 66068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Verify the "strcpy" function prototype. 661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FunctionType *FT = Callee->getFunctionType(); 662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (FT->getNumParams() != 2 || 663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FT->getReturnType() != FT->getParamType(0) || 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FT->getParamType(0) != FT->getParamType(1) || 66568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FT->getParamType(0) != B.getInt8PtrTy()) 666424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return nullptr; 66768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1); 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Dst == Src) // strcpy(x,x) -> x 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Src; 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // These optimizations require DataLayout. 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!DL) return nullptr; 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // See if we can get the length of the input string. 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64_t Len = GetStringLength(Src); 677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (Len == 0) return nullptr; 67868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We have enough information to now generate the memcpy call to do the 680424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // copy for us. Make a memcpy to copy the nul byte with align = 1. 68168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) B.CreateMemCpy(Dst, Src, 682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ConstantInt::get(DL->getIntPtrType(*Context), Len), 1); 683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Dst; 6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 6865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)struct StpCpyOpt: public LibCallOptimization { 688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Value *callOptimizer(Function *Callee, CallInst *CI, 689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IRBuilder<> &B) override { 690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Verify the "stpcpy" function prototype. 691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FunctionType *FT = Callee->getFunctionType(); 692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (FT->getNumParams() != 2 || 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FT->getReturnType() != FT->getParamType(0) || 69458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FT->getParamType(0) != FT->getParamType(1) || 69568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FT->getParamType(0) != B.getInt8PtrTy()) 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return nullptr; 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // These optimizations require DataLayout. 699424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!DL) return nullptr; 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 70168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1); 70268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (Dst == Src) { // stpcpy(x,x) -> x+strlen(x) 70368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Value *StrLen = EmitStrLen(Src, B, DL, TLI); 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return StrLen ? B.CreateInBoundsGEP(Dst, StrLen) : nullptr; 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // See if we can get the length of the input string. 70868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) uint64_t Len = GetStringLength(Src); 70968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (Len == 0) return nullptr; 71068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Type *PT = FT->getParamType(0); 712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Value *LenV = ConstantInt::get(DL->getIntPtrType(PT), Len); 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Value *DstEnd = B.CreateGEP(Dst, 714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ConstantInt::get(DL->getIntPtrType(PT), 715424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Len - 1)); 7165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We have enough information to now generate the memcpy call to do the 7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // copy for us. Make a memcpy to copy the nul byte with align = 1. 7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) B.CreateMemCpy(Dst, Src, LenV, 1); 7205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return DstEnd; 7215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 7225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct StrNCpyOpt : public LibCallOptimization { 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Value *callOptimizer(Function *Callee, CallInst *CI, 72668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) IRBuilder<> &B) override { 72768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FunctionType *FT = Callee->getFunctionType(); 72868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || 72968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FT->getParamType(0) != FT->getParamType(1) || 73068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FT->getParamType(0) != B.getInt8PtrTy() || 73168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) !FT->getParamType(2)->isIntegerTy()) 7325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return nullptr; 7335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 73468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Value *Dst = CI->getArgOperand(0); 73568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Value *Src = CI->getArgOperand(1); 73668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Value *LenOp = CI->getArgOperand(2); 73768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 73868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // See if we can get the length of the input string. 73968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) uint64_t SrcLen = GetStringLength(Src); 74068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (SrcLen == 0) return nullptr; 741a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) --SrcLen; 742a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 74368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (SrcLen == 0) { 744a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // strncpy(x, "", y) -> memset(x, '\0', y, 1) 745a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) B.CreateMemSet(Dst, B.getInt8('\0'), LenOp, 1); 746a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return Dst; 747a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 748a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 749a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) uint64_t Len; 750a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(LenOp)) 751a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Len = LengthArg->getZExtValue(); 75268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) else 75368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return nullptr; 754a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 75568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (Len == 0) return Dst; // strncpy(x, y, 0) -> x 756a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 757a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // These optimizations require DataLayout. 758a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!DL) return nullptr; 75968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 760a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Let strncpy handle the zero padding 761a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (Len > SrcLen+1) return nullptr; 762a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 763a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Type *PT = FT->getParamType(0); 764a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // strncpy(x, s, c) -> memcpy(x, s, c, 1) [s and c are constant] 765a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) B.CreateMemCpy(Dst, Src, 766a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ConstantInt::get(DL->getIntPtrType(PT), Len), 1); 767a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 768a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return Dst; 769a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 770a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}; 771a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 772a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)struct StrLenOpt : public LibCallOptimization { 773a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool ignoreCallingConv() override { return true; } 774a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Value *callOptimizer(Function *Callee, CallInst *CI, 7757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IRBuilder<> &B) override { 7767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FunctionType *FT = Callee->getFunctionType(); 7777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (FT->getNumParams() != 1 || 7787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FT->getParamType(0) != B.getInt8PtrTy() || 7797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch !FT->getReturnType()->isIntegerTy()) 7807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return nullptr; 7817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Value *Src = CI->getArgOperand(0); 7837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Constant folding: strlen("xyz") -> 3 7857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (uint64_t Len = GetStringLength(Src)) 7867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return ConstantInt::get(CI->getType(), Len-1); 7877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // strlen(x?"foo":"bars") --> x ? 3 : 4 7897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (SelectInst *SI = dyn_cast<SelectInst>(Src)) { 7907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch uint64_t LenTrue = GetStringLength(SI->getTrueValue()); 791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint64_t LenFalse = GetStringLength(SI->getFalseValue()); 792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (LenTrue && LenFalse) { 7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) emitOptimizationRemark(*Context, "simplify-libcalls", *Caller, 794eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SI->getDebugLoc(), 795eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "folded strlen(select) to select of constants"); 796eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return B.CreateSelect(SI->getCondition(), 797424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ConstantInt::get(CI->getType(), LenTrue-1), 798eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ConstantInt::get(CI->getType(), LenFalse-1)); 799eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 80058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 80158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 80258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // strlen(x) != 0 --> *x != 0 80368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // strlen(x) == 0 --> *x == 0 80458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (isOnlyUsedInZeroEqualityComparison(CI)) 80558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return B.CreateZExt(B.CreateLoad(Src, "strlenfirst"), CI->getType()); 80668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 80758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return nullptr; 80868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 80958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}; 81058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 81158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)struct StrPBrkOpt : public LibCallOptimization { 81258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Value *callOptimizer(Function *Callee, CallInst *CI, 813 IRBuilder<> &B) override { 814 FunctionType *FT = Callee->getFunctionType(); 815 if (FT->getNumParams() != 2 || 816 FT->getParamType(0) != B.getInt8PtrTy() || 817 FT->getParamType(1) != FT->getParamType(0) || 818 FT->getReturnType() != FT->getParamType(0)) 819 return nullptr; 820 821 StringRef S1, S2; 822 bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1); 823 bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2); 824 825 // strpbrk(s, "") -> NULL 826 // strpbrk("", s) -> NULL 827 if ((HasS1 && S1.empty()) || (HasS2 && S2.empty())) 828 return Constant::getNullValue(CI->getType()); 829 830 // Constant folding. 831 if (HasS1 && HasS2) { 832 size_t I = S1.find_first_of(S2); 833 if (I == StringRef::npos) // No match. 834 return Constant::getNullValue(CI->getType()); 835 836 return B.CreateGEP(CI->getArgOperand(0), B.getInt64(I), "strpbrk"); 837 } 838 839 // strpbrk(s, "a") -> strchr(s, 'a') 840 if (DL && HasS2 && S2.size() == 1) 841 return EmitStrChr(CI->getArgOperand(0), S2[0], B, DL, TLI); 842 843 return nullptr; 844 } 845}; 846 847struct StrToOpt : public LibCallOptimization { 848 Value *callOptimizer(Function *Callee, CallInst *CI, 849 IRBuilder<> &B) override { 850 FunctionType *FT = Callee->getFunctionType(); 851 if ((FT->getNumParams() != 2 && FT->getNumParams() != 3) || 852 !FT->getParamType(0)->isPointerTy() || 853 !FT->getParamType(1)->isPointerTy()) 854 return nullptr; 855 856 Value *EndPtr = CI->getArgOperand(1); 857 if (isa<ConstantPointerNull>(EndPtr)) { 858 // With a null EndPtr, this function won't capture the main argument. 859 // It would be readonly too, except that it still may write to errno. 860 CI->addAttribute(1, Attribute::NoCapture); 861 } 862 863 return nullptr; 864 } 865}; 866 867struct StrSpnOpt : public LibCallOptimization { 868 Value *callOptimizer(Function *Callee, CallInst *CI, 869 IRBuilder<> &B) override { 870 FunctionType *FT = Callee->getFunctionType(); 871 if (FT->getNumParams() != 2 || 872 FT->getParamType(0) != B.getInt8PtrTy() || 873 FT->getParamType(1) != FT->getParamType(0) || 874 !FT->getReturnType()->isIntegerTy()) 875 return nullptr; 876 877 StringRef S1, S2; 878 bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1); 879 bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2); 880 881 // strspn(s, "") -> 0 882 // strspn("", s) -> 0 883 if ((HasS1 && S1.empty()) || (HasS2 && S2.empty())) 884 return Constant::getNullValue(CI->getType()); 885 886 // Constant folding. 887 if (HasS1 && HasS2) { 888 size_t Pos = S1.find_first_not_of(S2); 889 if (Pos == StringRef::npos) Pos = S1.size(); 890 return ConstantInt::get(CI->getType(), Pos); 891 } 892 893 return nullptr; 894 } 895}; 896 897struct StrCSpnOpt : public LibCallOptimization { 898 Value *callOptimizer(Function *Callee, CallInst *CI, 899 IRBuilder<> &B) override { 900 FunctionType *FT = Callee->getFunctionType(); 901 if (FT->getNumParams() != 2 || 902 FT->getParamType(0) != B.getInt8PtrTy() || 903 FT->getParamType(1) != FT->getParamType(0) || 904 !FT->getReturnType()->isIntegerTy()) 905 return nullptr; 906 907 StringRef S1, S2; 908 bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1); 909 bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2); 910 911 // strcspn("", s) -> 0 912 if (HasS1 && S1.empty()) 913 return Constant::getNullValue(CI->getType()); 914 915 // Constant folding. 916 if (HasS1 && HasS2) { 917 size_t Pos = S1.find_first_of(S2); 918 if (Pos == StringRef::npos) Pos = S1.size(); 919 return ConstantInt::get(CI->getType(), Pos); 920 } 921 922 // strcspn(s, "") -> strlen(s) 923 if (DL && HasS2 && S2.empty()) 924 return EmitStrLen(CI->getArgOperand(0), B, DL, TLI); 925 926 return nullptr; 927 } 928}; 929 930struct StrStrOpt : public LibCallOptimization { 931 Value *callOptimizer(Function *Callee, CallInst *CI, 932 IRBuilder<> &B) override { 933 FunctionType *FT = Callee->getFunctionType(); 934 if (FT->getNumParams() != 2 || 935 !FT->getParamType(0)->isPointerTy() || 936 !FT->getParamType(1)->isPointerTy() || 937 !FT->getReturnType()->isPointerTy()) 938 return nullptr; 939 940 // fold strstr(x, x) -> x. 941 if (CI->getArgOperand(0) == CI->getArgOperand(1)) 942 return B.CreateBitCast(CI->getArgOperand(0), CI->getType()); 943 944 // fold strstr(a, b) == a -> strncmp(a, b, strlen(b)) == 0 945 if (DL && isOnlyUsedInEqualityComparison(CI, CI->getArgOperand(0))) { 946 Value *StrLen = EmitStrLen(CI->getArgOperand(1), B, DL, TLI); 947 if (!StrLen) 948 return nullptr; 949 Value *StrNCmp = EmitStrNCmp(CI->getArgOperand(0), CI->getArgOperand(1), 950 StrLen, B, DL, TLI); 951 if (!StrNCmp) 952 return nullptr; 953 for (auto UI = CI->user_begin(), UE = CI->user_end(); UI != UE;) { 954 ICmpInst *Old = cast<ICmpInst>(*UI++); 955 Value *Cmp = B.CreateICmp(Old->getPredicate(), StrNCmp, 956 ConstantInt::getNullValue(StrNCmp->getType()), 957 "cmp"); 958 LCS->replaceAllUsesWith(Old, Cmp); 959 } 960 return CI; 961 } 962 963 // See if either input string is a constant string. 964 StringRef SearchStr, ToFindStr; 965 bool HasStr1 = getConstantStringInfo(CI->getArgOperand(0), SearchStr); 966 bool HasStr2 = getConstantStringInfo(CI->getArgOperand(1), ToFindStr); 967 968 // fold strstr(x, "") -> x. 969 if (HasStr2 && ToFindStr.empty()) 970 return B.CreateBitCast(CI->getArgOperand(0), CI->getType()); 971 972 // If both strings are known, constant fold it. 973 if (HasStr1 && HasStr2) { 974 size_t Offset = SearchStr.find(ToFindStr); 975 976 if (Offset == StringRef::npos) // strstr("foo", "bar") -> null 977 return Constant::getNullValue(CI->getType()); 978 979 // strstr("abcd", "bc") -> gep((char*)"abcd", 1) 980 Value *Result = CastToCStr(CI->getArgOperand(0), B); 981 Result = B.CreateConstInBoundsGEP1_64(Result, Offset, "strstr"); 982 return B.CreateBitCast(Result, CI->getType()); 983 } 984 985 // fold strstr(x, "y") -> strchr(x, 'y'). 986 if (HasStr2 && ToFindStr.size() == 1) { 987 Value *StrChr= EmitStrChr(CI->getArgOperand(0), ToFindStr[0], B, DL, TLI); 988 return StrChr ? B.CreateBitCast(StrChr, CI->getType()) : nullptr; 989 } 990 return nullptr; 991 } 992}; 993 994struct MemCmpOpt : public LibCallOptimization { 995 Value *callOptimizer(Function *Callee, CallInst *CI, 996 IRBuilder<> &B) override { 997 FunctionType *FT = Callee->getFunctionType(); 998 if (FT->getNumParams() != 3 || !FT->getParamType(0)->isPointerTy() || 999 !FT->getParamType(1)->isPointerTy() || 1000 !FT->getReturnType()->isIntegerTy(32)) 1001 return nullptr; 1002 1003 Value *LHS = CI->getArgOperand(0), *RHS = CI->getArgOperand(1); 1004 1005 if (LHS == RHS) // memcmp(s,s,x) -> 0 1006 return Constant::getNullValue(CI->getType()); 1007 1008 // Make sure we have a constant length. 1009 ConstantInt *LenC = dyn_cast<ConstantInt>(CI->getArgOperand(2)); 1010 if (!LenC) return nullptr; 1011 uint64_t Len = LenC->getZExtValue(); 1012 1013 if (Len == 0) // memcmp(s1,s2,0) -> 0 1014 return Constant::getNullValue(CI->getType()); 1015 1016 // memcmp(S1,S2,1) -> *(unsigned char*)LHS - *(unsigned char*)RHS 1017 if (Len == 1) { 1018 Value *LHSV = B.CreateZExt(B.CreateLoad(CastToCStr(LHS, B), "lhsc"), 1019 CI->getType(), "lhsv"); 1020 Value *RHSV = B.CreateZExt(B.CreateLoad(CastToCStr(RHS, B), "rhsc"), 1021 CI->getType(), "rhsv"); 1022 return B.CreateSub(LHSV, RHSV, "chardiff"); 1023 } 1024 1025 // Constant folding: memcmp(x, y, l) -> cnst (all arguments are constant) 1026 StringRef LHSStr, RHSStr; 1027 if (getConstantStringInfo(LHS, LHSStr) && 1028 getConstantStringInfo(RHS, RHSStr)) { 1029 // Make sure we're not reading out-of-bounds memory. 1030 if (Len > LHSStr.size() || Len > RHSStr.size()) 1031 return nullptr; 1032 // Fold the memcmp and normalize the result. This way we get consistent 1033 // results across multiple platforms. 1034 uint64_t Ret = 0; 1035 int Cmp = memcmp(LHSStr.data(), RHSStr.data(), Len); 1036 if (Cmp < 0) 1037 Ret = -1; 1038 else if (Cmp > 0) 1039 Ret = 1; 1040 return ConstantInt::get(CI->getType(), Ret); 1041 } 1042 1043 return nullptr; 1044 } 1045}; 1046 1047struct MemCpyOpt : public LibCallOptimization { 1048 Value *callOptimizer(Function *Callee, CallInst *CI, 1049 IRBuilder<> &B) override { 1050 // These optimizations require DataLayout. 1051 if (!DL) return nullptr; 1052 1053 FunctionType *FT = Callee->getFunctionType(); 1054 if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || 1055 !FT->getParamType(0)->isPointerTy() || 1056 !FT->getParamType(1)->isPointerTy() || 1057 FT->getParamType(2) != DL->getIntPtrType(*Context)) 1058 return nullptr; 1059 1060 // memcpy(x, y, n) -> llvm.memcpy(x, y, n, 1) 1061 B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), 1062 CI->getArgOperand(2), 1); 1063 return CI->getArgOperand(0); 1064 } 1065}; 1066 1067struct MemMoveOpt : public LibCallOptimization { 1068 Value *callOptimizer(Function *Callee, CallInst *CI, 1069 IRBuilder<> &B) override { 1070 // These optimizations require DataLayout. 1071 if (!DL) return nullptr; 1072 1073 FunctionType *FT = Callee->getFunctionType(); 1074 if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || 1075 !FT->getParamType(0)->isPointerTy() || 1076 !FT->getParamType(1)->isPointerTy() || 1077 FT->getParamType(2) != DL->getIntPtrType(*Context)) 1078 return nullptr; 1079 1080 // memmove(x, y, n) -> llvm.memmove(x, y, n, 1) 1081 B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1), 1082 CI->getArgOperand(2), 1); 1083 return CI->getArgOperand(0); 1084 } 1085}; 1086 1087struct MemSetOpt : public LibCallOptimization { 1088 Value *callOptimizer(Function *Callee, CallInst *CI, 1089 IRBuilder<> &B) override { 1090 // These optimizations require DataLayout. 1091 if (!DL) return nullptr; 1092 1093 FunctionType *FT = Callee->getFunctionType(); 1094 if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || 1095 !FT->getParamType(0)->isPointerTy() || 1096 !FT->getParamType(1)->isIntegerTy() || 1097 FT->getParamType(2) != DL->getIntPtrType(FT->getParamType(0))) 1098 return nullptr; 1099 1100 // memset(p, v, n) -> llvm.memset(p, v, n, 1) 1101 Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), false); 1102 B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1); 1103 return CI->getArgOperand(0); 1104 } 1105}; 1106 1107//===----------------------------------------------------------------------===// 1108// Math Library Optimizations 1109//===----------------------------------------------------------------------===// 1110 1111//===----------------------------------------------------------------------===// 1112// Double -> Float Shrinking Optimizations for Unary Functions like 'floor' 1113 1114struct UnaryDoubleFPOpt : public LibCallOptimization { 1115 bool CheckRetType; 1116 UnaryDoubleFPOpt(bool CheckReturnType): CheckRetType(CheckReturnType) {} 1117 Value *callOptimizer(Function *Callee, CallInst *CI, 1118 IRBuilder<> &B) override { 1119 FunctionType *FT = Callee->getFunctionType(); 1120 if (FT->getNumParams() != 1 || !FT->getReturnType()->isDoubleTy() || 1121 !FT->getParamType(0)->isDoubleTy()) 1122 return nullptr; 1123 1124 if (CheckRetType) { 1125 // Check if all the uses for function like 'sin' are converted to float. 1126 for (User *U : CI->users()) { 1127 FPTruncInst *Cast = dyn_cast<FPTruncInst>(U); 1128 if (!Cast || !Cast->getType()->isFloatTy()) 1129 return nullptr; 1130 } 1131 } 1132 1133 // If this is something like 'floor((double)floatval)', convert to floorf. 1134 FPExtInst *Cast = dyn_cast<FPExtInst>(CI->getArgOperand(0)); 1135 if (!Cast || !Cast->getOperand(0)->getType()->isFloatTy()) 1136 return nullptr; 1137 1138 // floor((double)floatval) -> (double)floorf(floatval) 1139 Value *V = Cast->getOperand(0); 1140 V = EmitUnaryFloatFnCall(V, Callee->getName(), B, Callee->getAttributes()); 1141 return B.CreateFPExt(V, B.getDoubleTy()); 1142 } 1143}; 1144 1145// Double -> Float Shrinking Optimizations for Binary Functions like 'fmin/fmax' 1146struct BinaryDoubleFPOpt : public LibCallOptimization { 1147 bool CheckRetType; 1148 BinaryDoubleFPOpt(bool CheckReturnType): CheckRetType(CheckReturnType) {} 1149 Value *callOptimizer(Function *Callee, CallInst *CI, 1150 IRBuilder<> &B) override { 1151 FunctionType *FT = Callee->getFunctionType(); 1152 // Just make sure this has 2 arguments of the same FP type, which match the 1153 // result type. 1154 if (FT->getNumParams() != 2 || FT->getReturnType() != FT->getParamType(0) || 1155 FT->getParamType(0) != FT->getParamType(1) || 1156 !FT->getParamType(0)->isFloatingPointTy()) 1157 return nullptr; 1158 1159 if (CheckRetType) { 1160 // Check if all the uses for function like 'fmin/fmax' are converted to 1161 // float. 1162 for (User *U : CI->users()) { 1163 FPTruncInst *Cast = dyn_cast<FPTruncInst>(U); 1164 if (!Cast || !Cast->getType()->isFloatTy()) 1165 return nullptr; 1166 } 1167 } 1168 1169 // If this is something like 'fmin((double)floatval1, (double)floatval2)', 1170 // we convert it to fminf. 1171 FPExtInst *Cast1 = dyn_cast<FPExtInst>(CI->getArgOperand(0)); 1172 FPExtInst *Cast2 = dyn_cast<FPExtInst>(CI->getArgOperand(1)); 1173 if (!Cast1 || !Cast1->getOperand(0)->getType()->isFloatTy() || 1174 !Cast2 || !Cast2->getOperand(0)->getType()->isFloatTy()) 1175 return nullptr; 1176 1177 // fmin((double)floatval1, (double)floatval2) 1178 // -> (double)fmin(floatval1, floatval2) 1179 Value *V = nullptr; 1180 Value *V1 = Cast1->getOperand(0); 1181 Value *V2 = Cast2->getOperand(0); 1182 V = EmitBinaryFloatFnCall(V1, V2, Callee->getName(), B, 1183 Callee->getAttributes()); 1184 return B.CreateFPExt(V, B.getDoubleTy()); 1185 } 1186}; 1187 1188struct UnsafeFPLibCallOptimization : public LibCallOptimization { 1189 bool UnsafeFPShrink; 1190 UnsafeFPLibCallOptimization(bool UnsafeFPShrink) { 1191 this->UnsafeFPShrink = UnsafeFPShrink; 1192 } 1193}; 1194 1195struct CosOpt : public UnsafeFPLibCallOptimization { 1196 CosOpt(bool UnsafeFPShrink) : UnsafeFPLibCallOptimization(UnsafeFPShrink) {} 1197 Value *callOptimizer(Function *Callee, CallInst *CI, 1198 IRBuilder<> &B) override { 1199 Value *Ret = nullptr; 1200 if (UnsafeFPShrink && Callee->getName() == "cos" && 1201 TLI->has(LibFunc::cosf)) { 1202 UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true); 1203 Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B); 1204 } 1205 1206 FunctionType *FT = Callee->getFunctionType(); 1207 // Just make sure this has 1 argument of FP type, which matches the 1208 // result type. 1209 if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) || 1210 !FT->getParamType(0)->isFloatingPointTy()) 1211 return Ret; 1212 1213 // cos(-x) -> cos(x) 1214 Value *Op1 = CI->getArgOperand(0); 1215 if (BinaryOperator::isFNeg(Op1)) { 1216 BinaryOperator *BinExpr = cast<BinaryOperator>(Op1); 1217 return B.CreateCall(Callee, BinExpr->getOperand(1), "cos"); 1218 } 1219 return Ret; 1220 } 1221}; 1222 1223struct PowOpt : public UnsafeFPLibCallOptimization { 1224 PowOpt(bool UnsafeFPShrink) : UnsafeFPLibCallOptimization(UnsafeFPShrink) {} 1225 Value *callOptimizer(Function *Callee, CallInst *CI, 1226 IRBuilder<> &B) override { 1227 Value *Ret = nullptr; 1228 if (UnsafeFPShrink && Callee->getName() == "pow" && 1229 TLI->has(LibFunc::powf)) { 1230 UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true); 1231 Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B); 1232 } 1233 1234 FunctionType *FT = Callee->getFunctionType(); 1235 // Just make sure this has 2 arguments of the same FP type, which match the 1236 // result type. 1237 if (FT->getNumParams() != 2 || FT->getReturnType() != FT->getParamType(0) || 1238 FT->getParamType(0) != FT->getParamType(1) || 1239 !FT->getParamType(0)->isFloatingPointTy()) 1240 return Ret; 1241 1242 Value *Op1 = CI->getArgOperand(0), *Op2 = CI->getArgOperand(1); 1243 if (ConstantFP *Op1C = dyn_cast<ConstantFP>(Op1)) { 1244 // pow(1.0, x) -> 1.0 1245 if (Op1C->isExactlyValue(1.0)) 1246 return Op1C; 1247 // pow(2.0, x) -> exp2(x) 1248 if (Op1C->isExactlyValue(2.0) && 1249 hasUnaryFloatFn(TLI, Op1->getType(), LibFunc::exp2, LibFunc::exp2f, 1250 LibFunc::exp2l)) 1251 return EmitUnaryFloatFnCall(Op2, "exp2", B, Callee->getAttributes()); 1252 // pow(10.0, x) -> exp10(x) 1253 if (Op1C->isExactlyValue(10.0) && 1254 hasUnaryFloatFn(TLI, Op1->getType(), LibFunc::exp10, LibFunc::exp10f, 1255 LibFunc::exp10l)) 1256 return EmitUnaryFloatFnCall(Op2, TLI->getName(LibFunc::exp10), B, 1257 Callee->getAttributes()); 1258 } 1259 1260 ConstantFP *Op2C = dyn_cast<ConstantFP>(Op2); 1261 if (!Op2C) return Ret; 1262 1263 if (Op2C->getValueAPF().isZero()) // pow(x, 0.0) -> 1.0 1264 return ConstantFP::get(CI->getType(), 1.0); 1265 1266 if (Op2C->isExactlyValue(0.5) && 1267 hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::sqrt, LibFunc::sqrtf, 1268 LibFunc::sqrtl) && 1269 hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::fabs, LibFunc::fabsf, 1270 LibFunc::fabsl)) { 1271 // Expand pow(x, 0.5) to (x == -infinity ? +infinity : fabs(sqrt(x))). 1272 // This is faster than calling pow, and still handles negative zero 1273 // and negative infinity correctly. 1274 // TODO: In fast-math mode, this could be just sqrt(x). 1275 // TODO: In finite-only mode, this could be just fabs(sqrt(x)). 1276 Value *Inf = ConstantFP::getInfinity(CI->getType()); 1277 Value *NegInf = ConstantFP::getInfinity(CI->getType(), true); 1278 Value *Sqrt = EmitUnaryFloatFnCall(Op1, "sqrt", B, 1279 Callee->getAttributes()); 1280 Value *FAbs = EmitUnaryFloatFnCall(Sqrt, "fabs", B, 1281 Callee->getAttributes()); 1282 Value *FCmp = B.CreateFCmpOEQ(Op1, NegInf); 1283 Value *Sel = B.CreateSelect(FCmp, Inf, FAbs); 1284 return Sel; 1285 } 1286 1287 if (Op2C->isExactlyValue(1.0)) // pow(x, 1.0) -> x 1288 return Op1; 1289 if (Op2C->isExactlyValue(2.0)) // pow(x, 2.0) -> x*x 1290 return B.CreateFMul(Op1, Op1, "pow2"); 1291 if (Op2C->isExactlyValue(-1.0)) // pow(x, -1.0) -> 1.0/x 1292 return B.CreateFDiv(ConstantFP::get(CI->getType(), 1.0), 1293 Op1, "powrecip"); 1294 return nullptr; 1295 } 1296}; 1297 1298struct Exp2Opt : public UnsafeFPLibCallOptimization { 1299 Exp2Opt(bool UnsafeFPShrink) : UnsafeFPLibCallOptimization(UnsafeFPShrink) {} 1300 Value *callOptimizer(Function *Callee, CallInst *CI, 1301 IRBuilder<> &B) override { 1302 Value *Ret = nullptr; 1303 if (UnsafeFPShrink && Callee->getName() == "exp2" && 1304 TLI->has(LibFunc::exp2f)) { 1305 UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true); 1306 Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B); 1307 } 1308 1309 FunctionType *FT = Callee->getFunctionType(); 1310 // Just make sure this has 1 argument of FP type, which matches the 1311 // result type. 1312 if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) || 1313 !FT->getParamType(0)->isFloatingPointTy()) 1314 return Ret; 1315 1316 Value *Op = CI->getArgOperand(0); 1317 // Turn exp2(sitofp(x)) -> ldexp(1.0, sext(x)) if sizeof(x) <= 32 1318 // Turn exp2(uitofp(x)) -> ldexp(1.0, zext(x)) if sizeof(x) < 32 1319 LibFunc::Func LdExp = LibFunc::ldexpl; 1320 if (Op->getType()->isFloatTy()) 1321 LdExp = LibFunc::ldexpf; 1322 else if (Op->getType()->isDoubleTy()) 1323 LdExp = LibFunc::ldexp; 1324 1325 if (TLI->has(LdExp)) { 1326 Value *LdExpArg = nullptr; 1327 if (SIToFPInst *OpC = dyn_cast<SIToFPInst>(Op)) { 1328 if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() <= 32) 1329 LdExpArg = B.CreateSExt(OpC->getOperand(0), B.getInt32Ty()); 1330 } else if (UIToFPInst *OpC = dyn_cast<UIToFPInst>(Op)) { 1331 if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() < 32) 1332 LdExpArg = B.CreateZExt(OpC->getOperand(0), B.getInt32Ty()); 1333 } 1334 1335 if (LdExpArg) { 1336 Constant *One = ConstantFP::get(*Context, APFloat(1.0f)); 1337 if (!Op->getType()->isFloatTy()) 1338 One = ConstantExpr::getFPExtend(One, Op->getType()); 1339 1340 Module *M = Caller->getParent(); 1341 Value *Callee = 1342 M->getOrInsertFunction(TLI->getName(LdExp), Op->getType(), 1343 Op->getType(), B.getInt32Ty(), NULL); 1344 CallInst *CI = B.CreateCall2(Callee, One, LdExpArg); 1345 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts())) 1346 CI->setCallingConv(F->getCallingConv()); 1347 1348 return CI; 1349 } 1350 } 1351 return Ret; 1352 } 1353}; 1354 1355struct SinCosPiOpt : public LibCallOptimization { 1356 SinCosPiOpt() {} 1357 1358 Value *callOptimizer(Function *Callee, CallInst *CI, 1359 IRBuilder<> &B) override { 1360 // Make sure the prototype is as expected, otherwise the rest of the 1361 // function is probably invalid and likely to abort. 1362 if (!isTrigLibCall(CI)) 1363 return nullptr; 1364 1365 Value *Arg = CI->getArgOperand(0); 1366 SmallVector<CallInst *, 1> SinCalls; 1367 SmallVector<CallInst *, 1> CosCalls; 1368 SmallVector<CallInst *, 1> SinCosCalls; 1369 1370 bool IsFloat = Arg->getType()->isFloatTy(); 1371 1372 // Look for all compatible sinpi, cospi and sincospi calls with the same 1373 // argument. If there are enough (in some sense) we can make the 1374 // substitution. 1375 for (User *U : Arg->users()) 1376 classifyArgUse(U, CI->getParent(), IsFloat, SinCalls, CosCalls, 1377 SinCosCalls); 1378 1379 // It's only worthwhile if both sinpi and cospi are actually used. 1380 if (SinCosCalls.empty() && (SinCalls.empty() || CosCalls.empty())) 1381 return nullptr; 1382 1383 Value *Sin, *Cos, *SinCos; 1384 insertSinCosCall(B, CI->getCalledFunction(), Arg, IsFloat, Sin, Cos, 1385 SinCos); 1386 1387 replaceTrigInsts(SinCalls, Sin); 1388 replaceTrigInsts(CosCalls, Cos); 1389 replaceTrigInsts(SinCosCalls, SinCos); 1390 1391 return nullptr; 1392 } 1393 1394 bool isTrigLibCall(CallInst *CI) { 1395 Function *Callee = CI->getCalledFunction(); 1396 FunctionType *FT = Callee->getFunctionType(); 1397 1398 // We can only hope to do anything useful if we can ignore things like errno 1399 // and floating-point exceptions. 1400 bool AttributesSafe = CI->hasFnAttr(Attribute::NoUnwind) && 1401 CI->hasFnAttr(Attribute::ReadNone); 1402 1403 // Other than that we need float(float) or double(double) 1404 return AttributesSafe && FT->getNumParams() == 1 && 1405 FT->getReturnType() == FT->getParamType(0) && 1406 (FT->getParamType(0)->isFloatTy() || 1407 FT->getParamType(0)->isDoubleTy()); 1408 } 1409 1410 void classifyArgUse(Value *Val, BasicBlock *BB, bool IsFloat, 1411 SmallVectorImpl<CallInst *> &SinCalls, 1412 SmallVectorImpl<CallInst *> &CosCalls, 1413 SmallVectorImpl<CallInst *> &SinCosCalls) { 1414 CallInst *CI = dyn_cast<CallInst>(Val); 1415 1416 if (!CI) 1417 return; 1418 1419 Function *Callee = CI->getCalledFunction(); 1420 StringRef FuncName = Callee->getName(); 1421 LibFunc::Func Func; 1422 if (!TLI->getLibFunc(FuncName, Func) || !TLI->has(Func) || 1423 !isTrigLibCall(CI)) 1424 return; 1425 1426 if (IsFloat) { 1427 if (Func == LibFunc::sinpif) 1428 SinCalls.push_back(CI); 1429 else if (Func == LibFunc::cospif) 1430 CosCalls.push_back(CI); 1431 else if (Func == LibFunc::sincospif_stret) 1432 SinCosCalls.push_back(CI); 1433 } else { 1434 if (Func == LibFunc::sinpi) 1435 SinCalls.push_back(CI); 1436 else if (Func == LibFunc::cospi) 1437 CosCalls.push_back(CI); 1438 else if (Func == LibFunc::sincospi_stret) 1439 SinCosCalls.push_back(CI); 1440 } 1441 } 1442 1443 void replaceTrigInsts(SmallVectorImpl<CallInst*> &Calls, Value *Res) { 1444 for (SmallVectorImpl<CallInst*>::iterator I = Calls.begin(), 1445 E = Calls.end(); 1446 I != E; ++I) { 1447 LCS->replaceAllUsesWith(*I, Res); 1448 } 1449 } 1450 1451 void insertSinCosCall(IRBuilder<> &B, Function *OrigCallee, Value *Arg, 1452 bool UseFloat, Value *&Sin, Value *&Cos, 1453 Value *&SinCos) { 1454 Type *ArgTy = Arg->getType(); 1455 Type *ResTy; 1456 StringRef Name; 1457 1458 Triple T(OrigCallee->getParent()->getTargetTriple()); 1459 if (UseFloat) { 1460 Name = "__sincospif_stret"; 1461 1462 assert(T.getArch() != Triple::x86 && "x86 messy and unsupported for now"); 1463 // x86_64 can't use {float, float} since that would be returned in both 1464 // xmm0 and xmm1, which isn't what a real struct would do. 1465 ResTy = T.getArch() == Triple::x86_64 1466 ? static_cast<Type *>(VectorType::get(ArgTy, 2)) 1467 : static_cast<Type *>(StructType::get(ArgTy, ArgTy, NULL)); 1468 } else { 1469 Name = "__sincospi_stret"; 1470 ResTy = StructType::get(ArgTy, ArgTy, NULL); 1471 } 1472 1473 Module *M = OrigCallee->getParent(); 1474 Value *Callee = M->getOrInsertFunction(Name, OrigCallee->getAttributes(), 1475 ResTy, ArgTy, NULL); 1476 1477 if (Instruction *ArgInst = dyn_cast<Instruction>(Arg)) { 1478 // If the argument is an instruction, it must dominate all uses so put our 1479 // sincos call there. 1480 BasicBlock::iterator Loc = ArgInst; 1481 B.SetInsertPoint(ArgInst->getParent(), ++Loc); 1482 } else { 1483 // Otherwise (e.g. for a constant) the beginning of the function is as 1484 // good a place as any. 1485 BasicBlock &EntryBB = B.GetInsertBlock()->getParent()->getEntryBlock(); 1486 B.SetInsertPoint(&EntryBB, EntryBB.begin()); 1487 } 1488 1489 SinCos = B.CreateCall(Callee, Arg, "sincospi"); 1490 1491 if (SinCos->getType()->isStructTy()) { 1492 Sin = B.CreateExtractValue(SinCos, 0, "sinpi"); 1493 Cos = B.CreateExtractValue(SinCos, 1, "cospi"); 1494 } else { 1495 Sin = B.CreateExtractElement(SinCos, ConstantInt::get(B.getInt32Ty(), 0), 1496 "sinpi"); 1497 Cos = B.CreateExtractElement(SinCos, ConstantInt::get(B.getInt32Ty(), 1), 1498 "cospi"); 1499 } 1500 } 1501 1502}; 1503 1504//===----------------------------------------------------------------------===// 1505// Integer Library Call Optimizations 1506//===----------------------------------------------------------------------===// 1507 1508struct FFSOpt : public LibCallOptimization { 1509 Value *callOptimizer(Function *Callee, CallInst *CI, 1510 IRBuilder<> &B) override { 1511 FunctionType *FT = Callee->getFunctionType(); 1512 // Just make sure this has 2 arguments of the same FP type, which match the 1513 // result type. 1514 if (FT->getNumParams() != 1 || 1515 !FT->getReturnType()->isIntegerTy(32) || 1516 !FT->getParamType(0)->isIntegerTy()) 1517 return nullptr; 1518 1519 Value *Op = CI->getArgOperand(0); 1520 1521 // Constant fold. 1522 if (ConstantInt *CI = dyn_cast<ConstantInt>(Op)) { 1523 if (CI->isZero()) // ffs(0) -> 0. 1524 return B.getInt32(0); 1525 // ffs(c) -> cttz(c)+1 1526 return B.getInt32(CI->getValue().countTrailingZeros() + 1); 1527 } 1528 1529 // ffs(x) -> x != 0 ? (i32)llvm.cttz(x)+1 : 0 1530 Type *ArgType = Op->getType(); 1531 Value *F = Intrinsic::getDeclaration(Callee->getParent(), 1532 Intrinsic::cttz, ArgType); 1533 Value *V = B.CreateCall2(F, Op, B.getFalse(), "cttz"); 1534 V = B.CreateAdd(V, ConstantInt::get(V->getType(), 1)); 1535 V = B.CreateIntCast(V, B.getInt32Ty(), false); 1536 1537 Value *Cond = B.CreateICmpNE(Op, Constant::getNullValue(ArgType)); 1538 return B.CreateSelect(Cond, V, B.getInt32(0)); 1539 } 1540}; 1541 1542struct AbsOpt : public LibCallOptimization { 1543 bool ignoreCallingConv() override { return true; } 1544 Value *callOptimizer(Function *Callee, CallInst *CI, 1545 IRBuilder<> &B) override { 1546 FunctionType *FT = Callee->getFunctionType(); 1547 // We require integer(integer) where the types agree. 1548 if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() || 1549 FT->getParamType(0) != FT->getReturnType()) 1550 return nullptr; 1551 1552 // abs(x) -> x >s -1 ? x : -x 1553 Value *Op = CI->getArgOperand(0); 1554 Value *Pos = B.CreateICmpSGT(Op, Constant::getAllOnesValue(Op->getType()), 1555 "ispos"); 1556 Value *Neg = B.CreateNeg(Op, "neg"); 1557 return B.CreateSelect(Pos, Op, Neg); 1558 } 1559}; 1560 1561struct IsDigitOpt : public LibCallOptimization { 1562 Value *callOptimizer(Function *Callee, CallInst *CI, 1563 IRBuilder<> &B) override { 1564 FunctionType *FT = Callee->getFunctionType(); 1565 // We require integer(i32) 1566 if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() || 1567 !FT->getParamType(0)->isIntegerTy(32)) 1568 return nullptr; 1569 1570 // isdigit(c) -> (c-'0') <u 10 1571 Value *Op = CI->getArgOperand(0); 1572 Op = B.CreateSub(Op, B.getInt32('0'), "isdigittmp"); 1573 Op = B.CreateICmpULT(Op, B.getInt32(10), "isdigit"); 1574 return B.CreateZExt(Op, CI->getType()); 1575 } 1576}; 1577 1578struct IsAsciiOpt : public LibCallOptimization { 1579 Value *callOptimizer(Function *Callee, CallInst *CI, 1580 IRBuilder<> &B) override { 1581 FunctionType *FT = Callee->getFunctionType(); 1582 // We require integer(i32) 1583 if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() || 1584 !FT->getParamType(0)->isIntegerTy(32)) 1585 return nullptr; 1586 1587 // isascii(c) -> c <u 128 1588 Value *Op = CI->getArgOperand(0); 1589 Op = B.CreateICmpULT(Op, B.getInt32(128), "isascii"); 1590 return B.CreateZExt(Op, CI->getType()); 1591 } 1592}; 1593 1594struct ToAsciiOpt : public LibCallOptimization { 1595 Value *callOptimizer(Function *Callee, CallInst *CI, 1596 IRBuilder<> &B) override { 1597 FunctionType *FT = Callee->getFunctionType(); 1598 // We require i32(i32) 1599 if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) || 1600 !FT->getParamType(0)->isIntegerTy(32)) 1601 return nullptr; 1602 1603 // toascii(c) -> c & 0x7f 1604 return B.CreateAnd(CI->getArgOperand(0), 1605 ConstantInt::get(CI->getType(),0x7F)); 1606 } 1607}; 1608 1609//===----------------------------------------------------------------------===// 1610// Formatting and IO Library Call Optimizations 1611//===----------------------------------------------------------------------===// 1612 1613struct ErrorReportingOpt : public LibCallOptimization { 1614 ErrorReportingOpt(int S = -1) : StreamArg(S) {} 1615 1616 Value *callOptimizer(Function *Callee, CallInst *CI, 1617 IRBuilder<> &) override { 1618 // Error reporting calls should be cold, mark them as such. 1619 // This applies even to non-builtin calls: it is only a hint and applies to 1620 // functions that the frontend might not understand as builtins. 1621 1622 // This heuristic was suggested in: 1623 // Improving Static Branch Prediction in a Compiler 1624 // Brian L. Deitrich, Ben-Chung Cheng, Wen-mei W. Hwu 1625 // Proceedings of PACT'98, Oct. 1998, IEEE 1626 1627 if (!CI->hasFnAttr(Attribute::Cold) && isReportingError(Callee, CI)) { 1628 CI->addAttribute(AttributeSet::FunctionIndex, Attribute::Cold); 1629 } 1630 1631 return nullptr; 1632 } 1633 1634protected: 1635 bool isReportingError(Function *Callee, CallInst *CI) { 1636 if (!ColdErrorCalls) 1637 return false; 1638 1639 if (!Callee || !Callee->isDeclaration()) 1640 return false; 1641 1642 if (StreamArg < 0) 1643 return true; 1644 1645 // These functions might be considered cold, but only if their stream 1646 // argument is stderr. 1647 1648 if (StreamArg >= (int) CI->getNumArgOperands()) 1649 return false; 1650 LoadInst *LI = dyn_cast<LoadInst>(CI->getArgOperand(StreamArg)); 1651 if (!LI) 1652 return false; 1653 GlobalVariable *GV = dyn_cast<GlobalVariable>(LI->getPointerOperand()); 1654 if (!GV || !GV->isDeclaration()) 1655 return false; 1656 return GV->getName() == "stderr"; 1657 } 1658 1659 int StreamArg; 1660}; 1661 1662struct PrintFOpt : public LibCallOptimization { 1663 Value *optimizeFixedFormatString(Function *Callee, CallInst *CI, 1664 IRBuilder<> &B) { 1665 // Check for a fixed format string. 1666 StringRef FormatStr; 1667 if (!getConstantStringInfo(CI->getArgOperand(0), FormatStr)) 1668 return nullptr; 1669 1670 // Empty format string -> noop. 1671 if (FormatStr.empty()) // Tolerate printf's declared void. 1672 return CI->use_empty() ? (Value*)CI : 1673 ConstantInt::get(CI->getType(), 0); 1674 1675 // Do not do any of the following transformations if the printf return value 1676 // is used, in general the printf return value is not compatible with either 1677 // putchar() or puts(). 1678 if (!CI->use_empty()) 1679 return nullptr; 1680 1681 // printf("x") -> putchar('x'), even for '%'. 1682 if (FormatStr.size() == 1) { 1683 Value *Res = EmitPutChar(B.getInt32(FormatStr[0]), B, DL, TLI); 1684 if (CI->use_empty() || !Res) return Res; 1685 return B.CreateIntCast(Res, CI->getType(), true); 1686 } 1687 1688 // printf("foo\n") --> puts("foo") 1689 if (FormatStr[FormatStr.size()-1] == '\n' && 1690 FormatStr.find('%') == StringRef::npos) { // No format characters. 1691 // Create a string literal with no \n on it. We expect the constant merge 1692 // pass to be run after this pass, to merge duplicate strings. 1693 FormatStr = FormatStr.drop_back(); 1694 Value *GV = B.CreateGlobalString(FormatStr, "str"); 1695 Value *NewCI = EmitPutS(GV, B, DL, TLI); 1696 return (CI->use_empty() || !NewCI) ? 1697 NewCI : 1698 ConstantInt::get(CI->getType(), FormatStr.size()+1); 1699 } 1700 1701 // Optimize specific format strings. 1702 // printf("%c", chr) --> putchar(chr) 1703 if (FormatStr == "%c" && CI->getNumArgOperands() > 1 && 1704 CI->getArgOperand(1)->getType()->isIntegerTy()) { 1705 Value *Res = EmitPutChar(CI->getArgOperand(1), B, DL, TLI); 1706 1707 if (CI->use_empty() || !Res) return Res; 1708 return B.CreateIntCast(Res, CI->getType(), true); 1709 } 1710 1711 // printf("%s\n", str) --> puts(str) 1712 if (FormatStr == "%s\n" && CI->getNumArgOperands() > 1 && 1713 CI->getArgOperand(1)->getType()->isPointerTy()) { 1714 return EmitPutS(CI->getArgOperand(1), B, DL, TLI); 1715 } 1716 return nullptr; 1717 } 1718 1719 Value *callOptimizer(Function *Callee, CallInst *CI, 1720 IRBuilder<> &B) override { 1721 // Require one fixed pointer argument and an integer/void result. 1722 FunctionType *FT = Callee->getFunctionType(); 1723 if (FT->getNumParams() < 1 || !FT->getParamType(0)->isPointerTy() || 1724 !(FT->getReturnType()->isIntegerTy() || 1725 FT->getReturnType()->isVoidTy())) 1726 return nullptr; 1727 1728 if (Value *V = optimizeFixedFormatString(Callee, CI, B)) { 1729 return V; 1730 } 1731 1732 // printf(format, ...) -> iprintf(format, ...) if no floating point 1733 // arguments. 1734 if (TLI->has(LibFunc::iprintf) && !callHasFloatingPointArgument(CI)) { 1735 Module *M = B.GetInsertBlock()->getParent()->getParent(); 1736 Constant *IPrintFFn = 1737 M->getOrInsertFunction("iprintf", FT, Callee->getAttributes()); 1738 CallInst *New = cast<CallInst>(CI->clone()); 1739 New->setCalledFunction(IPrintFFn); 1740 B.Insert(New); 1741 return New; 1742 } 1743 return nullptr; 1744 } 1745}; 1746 1747struct SPrintFOpt : public LibCallOptimization { 1748 Value *OptimizeFixedFormatString(Function *Callee, CallInst *CI, 1749 IRBuilder<> &B) { 1750 // Check for a fixed format string. 1751 StringRef FormatStr; 1752 if (!getConstantStringInfo(CI->getArgOperand(1), FormatStr)) 1753 return nullptr; 1754 1755 // If we just have a format string (nothing else crazy) transform it. 1756 if (CI->getNumArgOperands() == 2) { 1757 // Make sure there's no % in the constant array. We could try to handle 1758 // %% -> % in the future if we cared. 1759 for (unsigned i = 0, e = FormatStr.size(); i != e; ++i) 1760 if (FormatStr[i] == '%') 1761 return nullptr; // we found a format specifier, bail out. 1762 1763 // These optimizations require DataLayout. 1764 if (!DL) return nullptr; 1765 1766 // sprintf(str, fmt) -> llvm.memcpy(str, fmt, strlen(fmt)+1, 1) 1767 B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), 1768 ConstantInt::get(DL->getIntPtrType(*Context), // Copy the 1769 FormatStr.size() + 1), 1); // nul byte. 1770 return ConstantInt::get(CI->getType(), FormatStr.size()); 1771 } 1772 1773 // The remaining optimizations require the format string to be "%s" or "%c" 1774 // and have an extra operand. 1775 if (FormatStr.size() != 2 || FormatStr[0] != '%' || 1776 CI->getNumArgOperands() < 3) 1777 return nullptr; 1778 1779 // Decode the second character of the format string. 1780 if (FormatStr[1] == 'c') { 1781 // sprintf(dst, "%c", chr) --> *(i8*)dst = chr; *((i8*)dst+1) = 0 1782 if (!CI->getArgOperand(2)->getType()->isIntegerTy()) return nullptr; 1783 Value *V = B.CreateTrunc(CI->getArgOperand(2), B.getInt8Ty(), "char"); 1784 Value *Ptr = CastToCStr(CI->getArgOperand(0), B); 1785 B.CreateStore(V, Ptr); 1786 Ptr = B.CreateGEP(Ptr, B.getInt32(1), "nul"); 1787 B.CreateStore(B.getInt8(0), Ptr); 1788 1789 return ConstantInt::get(CI->getType(), 1); 1790 } 1791 1792 if (FormatStr[1] == 's') { 1793 // These optimizations require DataLayout. 1794 if (!DL) return nullptr; 1795 1796 // sprintf(dest, "%s", str) -> llvm.memcpy(dest, str, strlen(str)+1, 1) 1797 if (!CI->getArgOperand(2)->getType()->isPointerTy()) return nullptr; 1798 1799 Value *Len = EmitStrLen(CI->getArgOperand(2), B, DL, TLI); 1800 if (!Len) 1801 return nullptr; 1802 Value *IncLen = B.CreateAdd(Len, 1803 ConstantInt::get(Len->getType(), 1), 1804 "leninc"); 1805 B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(2), IncLen, 1); 1806 1807 // The sprintf result is the unincremented number of bytes in the string. 1808 return B.CreateIntCast(Len, CI->getType(), false); 1809 } 1810 return nullptr; 1811 } 1812 1813 Value *callOptimizer(Function *Callee, CallInst *CI, 1814 IRBuilder<> &B) override { 1815 // Require two fixed pointer arguments and an integer result. 1816 FunctionType *FT = Callee->getFunctionType(); 1817 if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() || 1818 !FT->getParamType(1)->isPointerTy() || 1819 !FT->getReturnType()->isIntegerTy()) 1820 return nullptr; 1821 1822 if (Value *V = OptimizeFixedFormatString(Callee, CI, B)) { 1823 return V; 1824 } 1825 1826 // sprintf(str, format, ...) -> siprintf(str, format, ...) if no floating 1827 // point arguments. 1828 if (TLI->has(LibFunc::siprintf) && !callHasFloatingPointArgument(CI)) { 1829 Module *M = B.GetInsertBlock()->getParent()->getParent(); 1830 Constant *SIPrintFFn = 1831 M->getOrInsertFunction("siprintf", FT, Callee->getAttributes()); 1832 CallInst *New = cast<CallInst>(CI->clone()); 1833 New->setCalledFunction(SIPrintFFn); 1834 B.Insert(New); 1835 return New; 1836 } 1837 return nullptr; 1838 } 1839}; 1840 1841struct FPrintFOpt : public LibCallOptimization { 1842 Value *optimizeFixedFormatString(Function *Callee, CallInst *CI, 1843 IRBuilder<> &B) { 1844 ErrorReportingOpt ER(/* StreamArg = */ 0); 1845 (void) ER.callOptimizer(Callee, CI, B); 1846 1847 // All the optimizations depend on the format string. 1848 StringRef FormatStr; 1849 if (!getConstantStringInfo(CI->getArgOperand(1), FormatStr)) 1850 return nullptr; 1851 1852 // Do not do any of the following transformations if the fprintf return 1853 // value is used, in general the fprintf return value is not compatible 1854 // with fwrite(), fputc() or fputs(). 1855 if (!CI->use_empty()) 1856 return nullptr; 1857 1858 // fprintf(F, "foo") --> fwrite("foo", 3, 1, F) 1859 if (CI->getNumArgOperands() == 2) { 1860 for (unsigned i = 0, e = FormatStr.size(); i != e; ++i) 1861 if (FormatStr[i] == '%') // Could handle %% -> % if we cared. 1862 return nullptr; // We found a format specifier. 1863 1864 // These optimizations require DataLayout. 1865 if (!DL) return nullptr; 1866 1867 return EmitFWrite(CI->getArgOperand(1), 1868 ConstantInt::get(DL->getIntPtrType(*Context), 1869 FormatStr.size()), 1870 CI->getArgOperand(0), B, DL, TLI); 1871 } 1872 1873 // The remaining optimizations require the format string to be "%s" or "%c" 1874 // and have an extra operand. 1875 if (FormatStr.size() != 2 || FormatStr[0] != '%' || 1876 CI->getNumArgOperands() < 3) 1877 return nullptr; 1878 1879 // Decode the second character of the format string. 1880 if (FormatStr[1] == 'c') { 1881 // fprintf(F, "%c", chr) --> fputc(chr, F) 1882 if (!CI->getArgOperand(2)->getType()->isIntegerTy()) return nullptr; 1883 return EmitFPutC(CI->getArgOperand(2), CI->getArgOperand(0), B, DL, TLI); 1884 } 1885 1886 if (FormatStr[1] == 's') { 1887 // fprintf(F, "%s", str) --> fputs(str, F) 1888 if (!CI->getArgOperand(2)->getType()->isPointerTy()) 1889 return nullptr; 1890 return EmitFPutS(CI->getArgOperand(2), CI->getArgOperand(0), B, DL, TLI); 1891 } 1892 return nullptr; 1893 } 1894 1895 Value *callOptimizer(Function *Callee, CallInst *CI, 1896 IRBuilder<> &B) override { 1897 // Require two fixed paramters as pointers and integer result. 1898 FunctionType *FT = Callee->getFunctionType(); 1899 if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() || 1900 !FT->getParamType(1)->isPointerTy() || 1901 !FT->getReturnType()->isIntegerTy()) 1902 return nullptr; 1903 1904 if (Value *V = optimizeFixedFormatString(Callee, CI, B)) { 1905 return V; 1906 } 1907 1908 // fprintf(stream, format, ...) -> fiprintf(stream, format, ...) if no 1909 // floating point arguments. 1910 if (TLI->has(LibFunc::fiprintf) && !callHasFloatingPointArgument(CI)) { 1911 Module *M = B.GetInsertBlock()->getParent()->getParent(); 1912 Constant *FIPrintFFn = 1913 M->getOrInsertFunction("fiprintf", FT, Callee->getAttributes()); 1914 CallInst *New = cast<CallInst>(CI->clone()); 1915 New->setCalledFunction(FIPrintFFn); 1916 B.Insert(New); 1917 return New; 1918 } 1919 return nullptr; 1920 } 1921}; 1922 1923struct FWriteOpt : public LibCallOptimization { 1924 Value *callOptimizer(Function *Callee, CallInst *CI, 1925 IRBuilder<> &B) override { 1926 ErrorReportingOpt ER(/* StreamArg = */ 3); 1927 (void) ER.callOptimizer(Callee, CI, B); 1928 1929 // Require a pointer, an integer, an integer, a pointer, returning integer. 1930 FunctionType *FT = Callee->getFunctionType(); 1931 if (FT->getNumParams() != 4 || !FT->getParamType(0)->isPointerTy() || 1932 !FT->getParamType(1)->isIntegerTy() || 1933 !FT->getParamType(2)->isIntegerTy() || 1934 !FT->getParamType(3)->isPointerTy() || 1935 !FT->getReturnType()->isIntegerTy()) 1936 return nullptr; 1937 1938 // Get the element size and count. 1939 ConstantInt *SizeC = dyn_cast<ConstantInt>(CI->getArgOperand(1)); 1940 ConstantInt *CountC = dyn_cast<ConstantInt>(CI->getArgOperand(2)); 1941 if (!SizeC || !CountC) return nullptr; 1942 uint64_t Bytes = SizeC->getZExtValue()*CountC->getZExtValue(); 1943 1944 // If this is writing zero records, remove the call (it's a noop). 1945 if (Bytes == 0) 1946 return ConstantInt::get(CI->getType(), 0); 1947 1948 // If this is writing one byte, turn it into fputc. 1949 // This optimisation is only valid, if the return value is unused. 1950 if (Bytes == 1 && CI->use_empty()) { // fwrite(S,1,1,F) -> fputc(S[0],F) 1951 Value *Char = B.CreateLoad(CastToCStr(CI->getArgOperand(0), B), "char"); 1952 Value *NewCI = EmitFPutC(Char, CI->getArgOperand(3), B, DL, TLI); 1953 return NewCI ? ConstantInt::get(CI->getType(), 1) : nullptr; 1954 } 1955 1956 return nullptr; 1957 } 1958}; 1959 1960struct FPutsOpt : public LibCallOptimization { 1961 Value *callOptimizer(Function *Callee, CallInst *CI, 1962 IRBuilder<> &B) override { 1963 ErrorReportingOpt ER(/* StreamArg = */ 1); 1964 (void) ER.callOptimizer(Callee, CI, B); 1965 1966 // These optimizations require DataLayout. 1967 if (!DL) return nullptr; 1968 1969 // Require two pointers. Also, we can't optimize if return value is used. 1970 FunctionType *FT = Callee->getFunctionType(); 1971 if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() || 1972 !FT->getParamType(1)->isPointerTy() || 1973 !CI->use_empty()) 1974 return nullptr; 1975 1976 // fputs(s,F) --> fwrite(s,1,strlen(s),F) 1977 uint64_t Len = GetStringLength(CI->getArgOperand(0)); 1978 if (!Len) return nullptr; 1979 // Known to have no uses (see above). 1980 return EmitFWrite(CI->getArgOperand(0), 1981 ConstantInt::get(DL->getIntPtrType(*Context), Len-1), 1982 CI->getArgOperand(1), B, DL, TLI); 1983 } 1984}; 1985 1986struct PutsOpt : public LibCallOptimization { 1987 Value *callOptimizer(Function *Callee, CallInst *CI, 1988 IRBuilder<> &B) override { 1989 // Require one fixed pointer argument and an integer/void result. 1990 FunctionType *FT = Callee->getFunctionType(); 1991 if (FT->getNumParams() < 1 || !FT->getParamType(0)->isPointerTy() || 1992 !(FT->getReturnType()->isIntegerTy() || 1993 FT->getReturnType()->isVoidTy())) 1994 return nullptr; 1995 1996 // Check for a constant string. 1997 StringRef Str; 1998 if (!getConstantStringInfo(CI->getArgOperand(0), Str)) 1999 return nullptr; 2000 2001 if (Str.empty() && CI->use_empty()) { 2002 // puts("") -> putchar('\n') 2003 Value *Res = EmitPutChar(B.getInt32('\n'), B, DL, TLI); 2004 if (CI->use_empty() || !Res) return Res; 2005 return B.CreateIntCast(Res, CI->getType(), true); 2006 } 2007 2008 return nullptr; 2009 } 2010}; 2011 2012} // End anonymous namespace. 2013 2014namespace llvm { 2015 2016class LibCallSimplifierImpl { 2017 const DataLayout *DL; 2018 const TargetLibraryInfo *TLI; 2019 const LibCallSimplifier *LCS; 2020 bool UnsafeFPShrink; 2021 2022 // Math library call optimizations. 2023 CosOpt Cos; 2024 PowOpt Pow; 2025 Exp2Opt Exp2; 2026public: 2027 LibCallSimplifierImpl(const DataLayout *DL, const TargetLibraryInfo *TLI, 2028 const LibCallSimplifier *LCS, 2029 bool UnsafeFPShrink = false) 2030 : Cos(UnsafeFPShrink), Pow(UnsafeFPShrink), Exp2(UnsafeFPShrink) { 2031 this->DL = DL; 2032 this->TLI = TLI; 2033 this->LCS = LCS; 2034 this->UnsafeFPShrink = UnsafeFPShrink; 2035 } 2036 2037 Value *optimizeCall(CallInst *CI); 2038 LibCallOptimization *lookupOptimization(CallInst *CI); 2039 bool hasFloatVersion(StringRef FuncName); 2040}; 2041 2042bool LibCallSimplifierImpl::hasFloatVersion(StringRef FuncName) { 2043 LibFunc::Func Func; 2044 SmallString<20> FloatFuncName = FuncName; 2045 FloatFuncName += 'f'; 2046 if (TLI->getLibFunc(FloatFuncName, Func)) 2047 return TLI->has(Func); 2048 return false; 2049} 2050 2051// Fortified library call optimizations. 2052static MemCpyChkOpt MemCpyChk; 2053static MemMoveChkOpt MemMoveChk; 2054static MemSetChkOpt MemSetChk; 2055static StrCpyChkOpt StrCpyChk; 2056static StpCpyChkOpt StpCpyChk; 2057static StrNCpyChkOpt StrNCpyChk; 2058 2059// String library call optimizations. 2060static StrCatOpt StrCat; 2061static StrNCatOpt StrNCat; 2062static StrChrOpt StrChr; 2063static StrRChrOpt StrRChr; 2064static StrCmpOpt StrCmp; 2065static StrNCmpOpt StrNCmp; 2066static StrCpyOpt StrCpy; 2067static StpCpyOpt StpCpy; 2068static StrNCpyOpt StrNCpy; 2069static StrLenOpt StrLen; 2070static StrPBrkOpt StrPBrk; 2071static StrToOpt StrTo; 2072static StrSpnOpt StrSpn; 2073static StrCSpnOpt StrCSpn; 2074static StrStrOpt StrStr; 2075 2076// Memory library call optimizations. 2077static MemCmpOpt MemCmp; 2078static MemCpyOpt MemCpy; 2079static MemMoveOpt MemMove; 2080static MemSetOpt MemSet; 2081 2082// Math library call optimizations. 2083static UnaryDoubleFPOpt UnaryDoubleFP(false); 2084static BinaryDoubleFPOpt BinaryDoubleFP(false); 2085static UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true); 2086static SinCosPiOpt SinCosPi; 2087 2088 // Integer library call optimizations. 2089static FFSOpt FFS; 2090static AbsOpt Abs; 2091static IsDigitOpt IsDigit; 2092static IsAsciiOpt IsAscii; 2093static ToAsciiOpt ToAscii; 2094 2095// Formatting and IO library call optimizations. 2096static ErrorReportingOpt ErrorReporting; 2097static ErrorReportingOpt ErrorReporting0(0); 2098static ErrorReportingOpt ErrorReporting1(1); 2099static PrintFOpt PrintF; 2100static SPrintFOpt SPrintF; 2101static FPrintFOpt FPrintF; 2102static FWriteOpt FWrite; 2103static FPutsOpt FPuts; 2104static PutsOpt Puts; 2105 2106LibCallOptimization *LibCallSimplifierImpl::lookupOptimization(CallInst *CI) { 2107 LibFunc::Func Func; 2108 Function *Callee = CI->getCalledFunction(); 2109 StringRef FuncName = Callee->getName(); 2110 2111 // Next check for intrinsics. 2112 if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) { 2113 switch (II->getIntrinsicID()) { 2114 case Intrinsic::pow: 2115 return &Pow; 2116 case Intrinsic::exp2: 2117 return &Exp2; 2118 default: 2119 return nullptr; 2120 } 2121 } 2122 2123 // Then check for known library functions. 2124 if (TLI->getLibFunc(FuncName, Func) && TLI->has(Func)) { 2125 switch (Func) { 2126 case LibFunc::strcat: 2127 return &StrCat; 2128 case LibFunc::strncat: 2129 return &StrNCat; 2130 case LibFunc::strchr: 2131 return &StrChr; 2132 case LibFunc::strrchr: 2133 return &StrRChr; 2134 case LibFunc::strcmp: 2135 return &StrCmp; 2136 case LibFunc::strncmp: 2137 return &StrNCmp; 2138 case LibFunc::strcpy: 2139 return &StrCpy; 2140 case LibFunc::stpcpy: 2141 return &StpCpy; 2142 case LibFunc::strncpy: 2143 return &StrNCpy; 2144 case LibFunc::strlen: 2145 return &StrLen; 2146 case LibFunc::strpbrk: 2147 return &StrPBrk; 2148 case LibFunc::strtol: 2149 case LibFunc::strtod: 2150 case LibFunc::strtof: 2151 case LibFunc::strtoul: 2152 case LibFunc::strtoll: 2153 case LibFunc::strtold: 2154 case LibFunc::strtoull: 2155 return &StrTo; 2156 case LibFunc::strspn: 2157 return &StrSpn; 2158 case LibFunc::strcspn: 2159 return &StrCSpn; 2160 case LibFunc::strstr: 2161 return &StrStr; 2162 case LibFunc::memcmp: 2163 return &MemCmp; 2164 case LibFunc::memcpy: 2165 return &MemCpy; 2166 case LibFunc::memmove: 2167 return &MemMove; 2168 case LibFunc::memset: 2169 return &MemSet; 2170 case LibFunc::cosf: 2171 case LibFunc::cos: 2172 case LibFunc::cosl: 2173 return &Cos; 2174 case LibFunc::sinpif: 2175 case LibFunc::sinpi: 2176 case LibFunc::cospif: 2177 case LibFunc::cospi: 2178 return &SinCosPi; 2179 case LibFunc::powf: 2180 case LibFunc::pow: 2181 case LibFunc::powl: 2182 return &Pow; 2183 case LibFunc::exp2l: 2184 case LibFunc::exp2: 2185 case LibFunc::exp2f: 2186 return &Exp2; 2187 case LibFunc::ffs: 2188 case LibFunc::ffsl: 2189 case LibFunc::ffsll: 2190 return &FFS; 2191 case LibFunc::abs: 2192 case LibFunc::labs: 2193 case LibFunc::llabs: 2194 return &Abs; 2195 case LibFunc::isdigit: 2196 return &IsDigit; 2197 case LibFunc::isascii: 2198 return &IsAscii; 2199 case LibFunc::toascii: 2200 return &ToAscii; 2201 case LibFunc::printf: 2202 return &PrintF; 2203 case LibFunc::sprintf: 2204 return &SPrintF; 2205 case LibFunc::fprintf: 2206 return &FPrintF; 2207 case LibFunc::fwrite: 2208 return &FWrite; 2209 case LibFunc::fputs: 2210 return &FPuts; 2211 case LibFunc::puts: 2212 return &Puts; 2213 case LibFunc::perror: 2214 return &ErrorReporting; 2215 case LibFunc::vfprintf: 2216 case LibFunc::fiprintf: 2217 return &ErrorReporting0; 2218 case LibFunc::fputc: 2219 return &ErrorReporting1; 2220 case LibFunc::ceil: 2221 case LibFunc::fabs: 2222 case LibFunc::floor: 2223 case LibFunc::rint: 2224 case LibFunc::round: 2225 case LibFunc::nearbyint: 2226 case LibFunc::trunc: 2227 if (hasFloatVersion(FuncName)) 2228 return &UnaryDoubleFP; 2229 return nullptr; 2230 case LibFunc::acos: 2231 case LibFunc::acosh: 2232 case LibFunc::asin: 2233 case LibFunc::asinh: 2234 case LibFunc::atan: 2235 case LibFunc::atanh: 2236 case LibFunc::cbrt: 2237 case LibFunc::cosh: 2238 case LibFunc::exp: 2239 case LibFunc::exp10: 2240 case LibFunc::expm1: 2241 case LibFunc::log: 2242 case LibFunc::log10: 2243 case LibFunc::log1p: 2244 case LibFunc::log2: 2245 case LibFunc::logb: 2246 case LibFunc::sin: 2247 case LibFunc::sinh: 2248 case LibFunc::sqrt: 2249 case LibFunc::tan: 2250 case LibFunc::tanh: 2251 if (UnsafeFPShrink && hasFloatVersion(FuncName)) 2252 return &UnsafeUnaryDoubleFP; 2253 return nullptr; 2254 case LibFunc::fmin: 2255 case LibFunc::fmax: 2256 if (hasFloatVersion(FuncName)) 2257 return &BinaryDoubleFP; 2258 return nullptr; 2259 case LibFunc::memcpy_chk: 2260 return &MemCpyChk; 2261 default: 2262 return nullptr; 2263 } 2264 } 2265 2266 // Finally check for fortified library calls. 2267 if (FuncName.endswith("_chk")) { 2268 if (FuncName == "__memmove_chk") 2269 return &MemMoveChk; 2270 else if (FuncName == "__memset_chk") 2271 return &MemSetChk; 2272 else if (FuncName == "__strcpy_chk") 2273 return &StrCpyChk; 2274 else if (FuncName == "__stpcpy_chk") 2275 return &StpCpyChk; 2276 else if (FuncName == "__strncpy_chk") 2277 return &StrNCpyChk; 2278 else if (FuncName == "__stpncpy_chk") 2279 return &StrNCpyChk; 2280 } 2281 2282 return nullptr; 2283 2284} 2285 2286Value *LibCallSimplifierImpl::optimizeCall(CallInst *CI) { 2287 LibCallOptimization *LCO = lookupOptimization(CI); 2288 if (LCO) { 2289 IRBuilder<> Builder(CI); 2290 return LCO->optimizeCall(CI, DL, TLI, LCS, Builder); 2291 } 2292 return nullptr; 2293} 2294 2295LibCallSimplifier::LibCallSimplifier(const DataLayout *DL, 2296 const TargetLibraryInfo *TLI, 2297 bool UnsafeFPShrink) { 2298 Impl = new LibCallSimplifierImpl(DL, TLI, this, UnsafeFPShrink); 2299} 2300 2301LibCallSimplifier::~LibCallSimplifier() { 2302 delete Impl; 2303} 2304 2305Value *LibCallSimplifier::optimizeCall(CallInst *CI) { 2306 if (CI->isNoBuiltin()) return nullptr; 2307 return Impl->optimizeCall(CI); 2308} 2309 2310void LibCallSimplifier::replaceAllUsesWith(Instruction *I, Value *With) const { 2311 I->replaceAllUsesWith(With); 2312 I->eraseFromParent(); 2313} 2314 2315} 2316 2317// TODO: 2318// Additional cases that we need to add to this file: 2319// 2320// cbrt: 2321// * cbrt(expN(X)) -> expN(x/3) 2322// * cbrt(sqrt(x)) -> pow(x,1/6) 2323// * cbrt(sqrt(x)) -> pow(x,1/9) 2324// 2325// exp, expf, expl: 2326// * exp(log(x)) -> x 2327// 2328// log, logf, logl: 2329// * log(exp(x)) -> x 2330// * log(x**y) -> y*log(x) 2331// * log(exp(y)) -> y*log(e) 2332// * log(exp2(y)) -> y*log(2) 2333// * log(exp10(y)) -> y*log(10) 2334// * log(sqrt(x)) -> 0.5*log(x) 2335// * log(pow(x,y)) -> y*log(x) 2336// 2337// lround, lroundf, lroundl: 2338// * lround(cnst) -> cnst' 2339// 2340// pow, powf, powl: 2341// * pow(exp(x),y) -> exp(x*y) 2342// * pow(sqrt(x),y) -> pow(x,y*0.5) 2343// * pow(pow(x,y),z)-> pow(x,y*z) 2344// 2345// round, roundf, roundl: 2346// * round(cnst) -> cnst' 2347// 2348// signbit: 2349// * signbit(cnst) -> cnst' 2350// * signbit(nncst) -> 0 (if pstv is a non-negative constant) 2351// 2352// sqrt, sqrtf, sqrtl: 2353// * sqrt(expN(x)) -> expN(x*0.5) 2354// * sqrt(Nroot(x)) -> pow(x,1/(2*N)) 2355// * sqrt(pow(x,y)) -> pow(|x|,y*0.5) 2356// 2357// tan, tanf, tanl: 2358// * tan(atan(x)) -> x 2359// 2360// trunc, truncf, truncl: 2361// * trunc(cnst) -> cnst' 2362// 2363// 2364