Index: include/llvm/Analysis/CaptureTracking.h =================================================================== --- include/llvm/Analysis/CaptureTracking.h +++ include/llvm/Analysis/CaptureTracking.h @@ -21,6 +21,7 @@ class Instruction; class DominatorTree; class OrderedBasicBlock; + class TargetLibraryInfo; /// The default value for MaxUsesToExplore argument. It's relatively small to /// keep the cost of analysis reasonable for clients like BasicAliasAnalysis, @@ -42,6 +43,7 @@ bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, bool StoreCaptures, + const TargetLibraryInfo *TLI, unsigned MaxUsesToExplore = DefaultMaxUsesToExplore); /// PointerMayBeCapturedBefore - Return true if this pointer value may be @@ -59,7 +61,8 @@ /// one value before giving up due too "too many uses". bool PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures, bool StoreCaptures, const Instruction *I, - const DominatorTree *DT, bool IncludeI = false, + const DominatorTree *DT, const TargetLibraryInfo *TLI, + bool IncludeI = false, OrderedBasicBlock *OBB = nullptr, unsigned MaxUsesToExplore = DefaultMaxUsesToExplore); @@ -92,6 +95,7 @@ /// MaxUsesToExplore specifies how many uses should the analysis explore for /// one value before giving up due too "too many uses". void PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker, + const TargetLibraryInfo *TLI, unsigned MaxUsesToExplore = DefaultMaxUsesToExplore); } // end namespace llvm Index: include/llvm/Analysis/ValueTracking.h =================================================================== --- include/llvm/Analysis/ValueTracking.h +++ include/llvm/Analysis/ValueTracking.h @@ -251,6 +251,13 @@ bool isGEPBasedOnPointerToString(const GEPOperator *GEP, unsigned CharSize = 8); + /// Returns true if it is guaranteed that V is not based on a pointer casted + // from an integer. + bool isGuaranteedToBeLogicalPointer(Value *V, const DataLayout &DL, + LoopInfo *LI, + const TargetLibraryInfo *TLI, + unsigned MaxLookup); + /// Represents offset+length into a ConstantDataArray. struct ConstantDataArraySlice { /// ConstantDataArray pointer. nullptr indicates a zeroinitializer (a valid Index: include/llvm/Transforms/Utils/Cloning.h =================================================================== --- include/llvm/Transforms/Utils/Cloning.h +++ include/llvm/Transforms/Utils/Cloning.h @@ -232,14 +232,17 @@ /// are only used by ForwardVarArgsTo. InlineResult InlineFunction(CallInst *C, InlineFunctionInfo &IFI, AAResults *CalleeAAR = nullptr, - bool InsertLifetime = true); + bool InsertLifetime = true, + const TargetLibraryInfo *TLI = nullptr); InlineResult InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI, AAResults *CalleeAAR = nullptr, - bool InsertLifetime = true); + bool InsertLifetime = true, + const TargetLibraryInfo *TLI = nullptr); InlineResult InlineFunction(CallSite CS, InlineFunctionInfo &IFI, AAResults *CalleeAAR = nullptr, bool InsertLifetime = true, - Function *ForwardVarArgsTo = nullptr); + Function *ForwardVarArgsTo = nullptr, + const TargetLibraryInfo *TLI = nullptr); /// Clones a loop \p OrigLoop. Returns the loop and the blocks in \p /// Blocks. Index: lib/Analysis/AliasAnalysis.cpp =================================================================== --- lib/Analysis/AliasAnalysis.cpp +++ lib/Analysis/AliasAnalysis.cpp @@ -566,7 +566,7 @@ return ModRefInfo::ModRef; if (PointerMayBeCapturedBefore(Object, /* ReturnCaptures */ true, - /* StoreCaptures */ true, I, DT, + /* StoreCaptures */ true, I, DT, &TLI, /* include Object */ true, /* OrderedBasicBlock */ OBB)) return ModRefInfo::ModRef; Index: lib/Analysis/BasicAliasAnalysis.cpp =================================================================== --- lib/Analysis/BasicAliasAnalysis.cpp +++ lib/Analysis/BasicAliasAnalysis.cpp @@ -117,7 +117,8 @@ /// Returns true if the pointer is to a function-local object that never /// escapes from the function. -static bool isNonEscapingLocalObject(const Value *V) { +static bool isNonEscapingLocalObject(const Value *V, + const TargetLibraryInfo *TLI) { // If this is a local allocation, check to see if it escapes. if (isa(V) || isNoAliasCall(V)) // Set StoreCaptures to True so that we can assume in our callers that the @@ -125,7 +126,7 @@ // PointerMayBeCaptured doesn't have any special analysis for the // StoreCaptures=false case; if it did, our callers could be refined to be // more precise. - return !PointerMayBeCaptured(V, false, /*StoreCaptures=*/true); + return !PointerMayBeCaptured(V, false, /*StoreCaptures=*/true, TLI); // If this is an argument that corresponds to a byval or noalias argument, // then it has not escaped before entering the function. Check if it escapes @@ -135,7 +136,7 @@ // Note even if the argument is marked nocapture, we still need to check // for copies made inside the function. The nocapture attribute only // specifies that there are no copies made that outlive the function. - return !PointerMayBeCaptured(V, false, /*StoreCaptures=*/true); + return !PointerMayBeCaptured(V, false, /*StoreCaptures=*/true, TLI); return false; } @@ -855,7 +856,7 @@ // then the call can not mod/ref the pointer unless the call takes the pointer // as an argument, and itself doesn't capture it. if (!isa(Object) && Call != Object && - isNonEscapingLocalObject(Object)) { + isNonEscapingLocalObject(Object, &TLI)) { // Optimistically assume that call doesn't touch Object and check this // assumption in the following loop. @@ -1755,9 +1756,9 @@ // temporary store the nocapture argument's value in a temporary memory // location if that memory location doesn't escape. Or it may pass a // nocapture value to other functions as long as they don't capture it. - if (isEscapeSource(O1) && isNonEscapingLocalObject(O2)) + if (isEscapeSource(O1) && isNonEscapingLocalObject(O2, &TLI)) return NoAlias; - if (isEscapeSource(O2) && isNonEscapingLocalObject(O1)) + if (isEscapeSource(O2) && isNonEscapingLocalObject(O1, &TLI)) return NoAlias; } Index: lib/Analysis/CaptureTracking.cpp =================================================================== --- lib/Analysis/CaptureTracking.cpp +++ lib/Analysis/CaptureTracking.cpp @@ -158,6 +158,7 @@ /// counts as capturing it or not. bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures, bool StoreCaptures, + const TargetLibraryInfo *TLI, unsigned MaxUsesToExplore) { assert(!isa(V) && "It doesn't make sense to ask whether a global is captured."); @@ -169,7 +170,7 @@ (void)StoreCaptures; SimpleCaptureTracker SCT(ReturnCaptures); - PointerMayBeCaptured(V, &SCT, MaxUsesToExplore); + PointerMayBeCaptured(V, &SCT, TLI, MaxUsesToExplore); return SCT.Captured; } @@ -185,15 +186,16 @@ /// queries about relative order among instructions in the same basic block. bool llvm::PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures, bool StoreCaptures, const Instruction *I, - const DominatorTree *DT, bool IncludeI, - OrderedBasicBlock *OBB, + const DominatorTree *DT, + const TargetLibraryInfo *TLI, + bool IncludeI, OrderedBasicBlock *OBB, unsigned MaxUsesToExplore) { assert(!isa(V) && "It doesn't make sense to ask whether a global is captured."); bool UseNewOBB = OBB == nullptr; if (!DT) - return PointerMayBeCaptured(V, ReturnCaptures, StoreCaptures, + return PointerMayBeCaptured(V, ReturnCaptures, StoreCaptures, TLI, MaxUsesToExplore); if (UseNewOBB) OBB = new OrderedBasicBlock(I->getParent()); @@ -202,7 +204,7 @@ // with StoreCaptures. CapturesBefore CB(ReturnCaptures, I, DT, IncludeI, OBB); - PointerMayBeCaptured(V, &CB, MaxUsesToExplore); + PointerMayBeCaptured(V, &CB, TLI, MaxUsesToExplore); if (UseNewOBB) delete OBB; @@ -210,6 +212,7 @@ } void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker, + const TargetLibraryInfo *TLI, unsigned MaxUsesToExplore) { assert(V->getType()->isPointerTy() && "Capture is for pointers only!"); SmallVector Worklist; @@ -234,6 +237,7 @@ while (!Worklist.empty()) { const Use *U = Worklist.pop_back_val(); Instruction *I = cast(U->getUser()); + const DataLayout &DL = I->getModule()->getDataLayout(); V = U->get(); switch (I->getOpcode()) { @@ -264,6 +268,22 @@ if (Tracker->captured(U)) return; + // psub intrinsics on logical pointer does not capture address. :) + if (auto *II = dyn_cast(I)) { + if (II->getIntrinsicID() == Intrinsic::psub) { + Value *AddrToCheck = nullptr; + if (II->getArgOperand(0) == V) + AddrToCheck = II->getArgOperand(1); + else if (II->getArgOperand(1) == V) + AddrToCheck = II->getArgOperand(0); + else + llvm_unreachable("at least one of argument should be Addr"); + unsigned Depth = 6; + if (isGuaranteedToBeLogicalPointer(AddrToCheck, DL, nullptr, + TLI, Depth)) + break; + } + } // Not captured if only passed via 'nocapture' arguments. Note that // calling a function pointer does not in itself cause the pointer to // be captured. This is a subtle point considering that (for example) Index: lib/Analysis/InstructionSimplify.cpp =================================================================== --- lib/Analysis/InstructionSimplify.cpp +++ lib/Analysis/InstructionSimplify.cpp @@ -2326,7 +2326,7 @@ MI = RHS; // FIXME: We should also fold the compare when the pointer escapes, but the // compare dominates the pointer escape - if (MI && !PointerMayBeCaptured(MI, true, true)) + if (MI && !PointerMayBeCaptured(MI, true, true, TLI)) return ConstantInt::get(GetCompareTy(LHS), CmpInst::isFalseWhenEqual(Pred)); } Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -30,6 +30,7 @@ #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/Loads.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/Argument.h" @@ -1861,6 +1862,26 @@ return false; } +bool llvm::isGuaranteedToBeLogicalPointer(Value *V, const DataLayout &DL, LoopInfo *LI, + const TargetLibraryInfo *TLI, unsigned MaxLookup) { + SmallVector Objects; + GetUnderlyingObjects(V, Objects, DL, LI, MaxLookup); + if (Objects.begin() == Objects.end()) + return false; + + for (auto itr = Objects.begin(); itr != Objects.end(); itr++) { + Value *V = *itr; + if (isa(V)) + continue; + if (isa(V)) + continue; + if (TLI && isAllocationFn(V, TLI, true)) + continue; + return false; + } + return true; +} + static bool isKnownNonNullFromDominatingCondition(const Value *V, const Instruction *CtxI, const DominatorTree *DT) { Index: lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp +++ lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp @@ -570,7 +570,7 @@ if (UseInst->getOpcode() == Instruction::AddrSpaceCast) { // Give up if the pointer may be captured. - if (PointerMayBeCaptured(UseInst, true, true)) + if (PointerMayBeCaptured(UseInst, true, true, nullptr)) return false; // Don't collect the users of this. WorkList.push_back(User); Index: lib/Transforms/IPO/FunctionAttrs.cpp =================================================================== --- lib/Transforms/IPO/FunctionAttrs.cpp +++ lib/Transforms/IPO/FunctionAttrs.cpp @@ -657,7 +657,8 @@ } /// Deduce nocapture attributes for the SCC. -static bool addArgumentAttrs(const SCCNodeSet &SCCNodes) { +static bool addArgumentAttrs(const SCCNodeSet &SCCNodes, + const TargetLibraryInfo *TLI) { bool Changed = false; ArgumentGraph AG; @@ -695,7 +696,7 @@ bool HasNonLocalUses = false; if (!A->hasNoCaptureAttr()) { ArgumentUsesTracker Tracker(SCCNodes); - PointerMayBeCaptured(&*A, &Tracker); + PointerMayBeCaptured(&*A, &Tracker, TLI); if (!Tracker.Captured) { if (Tracker.Uses.empty()) { // If it's trivially not captured, mark it nocapture now. @@ -842,7 +843,8 @@ /// /// A function is "malloc-like" if it returns either null or a pointer that /// doesn't alias any other pointer visible to the caller. -static bool isFunctionMallocLike(Function *F, const SCCNodeSet &SCCNodes) { +static bool isFunctionMallocLike(Function *F, const SCCNodeSet &SCCNodes, + const TargetLibraryInfo *TLI) { SmallSetVector FlowsToReturn; for (BasicBlock &BB : *F) if (ReturnInst *Ret = dyn_cast(BB.getTerminator())) @@ -898,7 +900,7 @@ return false; // Did not come from an allocation. } - if (PointerMayBeCaptured(RetVal, false, /*StoreCaptures=*/false)) + if (PointerMayBeCaptured(RetVal, false, /*StoreCaptures=*/false, TLI)) return false; } @@ -906,7 +908,8 @@ } /// Deduce noalias attributes for the SCC. -static bool addNoAliasAttrs(const SCCNodeSet &SCCNodes) { +static bool addNoAliasAttrs(const SCCNodeSet &SCCNodes, + const TargetLibraryInfo *TLI) { // Check each function in turn, determining which functions return noalias // pointers. for (Function *F : SCCNodes) { @@ -925,7 +928,7 @@ if (!F->getReturnType()->isPointerTy()) continue; - if (!isFunctionMallocLike(F, SCCNodes)) + if (!isFunctionMallocLike(F, SCCNodes, TLI)) return false; } @@ -1324,7 +1327,8 @@ template static bool deriveAttrsInPostOrder(SCCNodeSet &SCCNodes, AARGetterT &&AARGetter, - bool HasUnknownCall) { + bool HasUnknownCall, + const TargetLibraryInfo *TLI) { bool Changed = false; // Bail if the SCC only contains optnone functions. @@ -1333,12 +1337,12 @@ Changed |= addArgumentReturnedAttrs(SCCNodes); Changed |= addReadAttrs(SCCNodes, AARGetter); - Changed |= addArgumentAttrs(SCCNodes); + Changed |= addArgumentAttrs(SCCNodes, TLI); // If we have no external nodes participating in the SCC, we can deduce some // more precise attributes as well. if (!HasUnknownCall) { - Changed |= addNoAliasAttrs(SCCNodes); + Changed |= addNoAliasAttrs(SCCNodes, TLI); Changed |= addNonNullAttrs(SCCNodes); Changed |= inferAttrsFromFunctionBodies(SCCNodes); Changed |= addNoRecurseAttrs(SCCNodes); @@ -1353,12 +1357,12 @@ CGSCCUpdateResult &) { FunctionAnalysisManager &FAM = AM.getResult(C, CG).getManager(); - // We pass a lambda into functions to wire them up to the analysis manager // for getting function analyses. auto AARGetter = [&](Function &F) -> AAResults & { return FAM.getResult(F); }; + TargetLibraryInfo *TLI = nullptr; // Fill SCCNodes with the elements of the SCC. Also track whether there are // any external or opt-none nodes that will prevent us from optimizing any @@ -1387,9 +1391,11 @@ } SCCNodes.insert(&F); + if (!TLI) + TLI = &FAM.getResult(F); } - if (deriveAttrsInPostOrder(SCCNodes, AARGetter, HasUnknownCall)) + if (deriveAttrsInPostOrder(SCCNodes, AARGetter, HasUnknownCall, TLI)) return PreservedAnalyses::none(); return PreservedAnalyses::all(); @@ -1411,6 +1417,7 @@ void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); AU.addRequired(); + AU.addRequired(); getAAResultsAnalysisUsage(AU); CallGraphSCCPass::getAnalysisUsage(AU); } @@ -1422,6 +1429,7 @@ INITIALIZE_PASS_BEGIN(PostOrderFunctionAttrsLegacyPass, "functionattrs", "Deduce function attributes", false, false) INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) +INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) INITIALIZE_PASS_END(PostOrderFunctionAttrsLegacyPass, "functionattrs", "Deduce function attributes", false, false) @@ -1431,7 +1439,8 @@ } template -static bool runImpl(CallGraphSCC &SCC, AARGetterT AARGetter) { +static bool runImpl(CallGraphSCC &SCC, AARGetterT AARGetter, + const TargetLibraryInfo *TLI) { // Fill SCCNodes with the elements of the SCC. Used for quickly looking up // whether a given CallGraphNode is in this SCC. Also track whether there are @@ -1452,13 +1461,16 @@ SCCNodes.insert(F); } - return deriveAttrsInPostOrder(SCCNodes, AARGetter, ExternalNode); + return deriveAttrsInPostOrder(SCCNodes, AARGetter, ExternalNode, TLI); } bool PostOrderFunctionAttrsLegacyPass::runOnSCC(CallGraphSCC &SCC) { if (skipSCC(SCC)) return false; - return runImpl(SCC, LegacyAARGetter(*this)); + + auto &TLI = getAnalysis().getTLI(); + + return runImpl(SCC, LegacyAARGetter(*this), &TLI); } namespace { Index: lib/Transforms/IPO/Inliner.cpp =================================================================== --- lib/Transforms/IPO/Inliner.cpp +++ lib/Transforms/IPO/Inliner.cpp @@ -276,7 +276,8 @@ CallSite CS, InlineFunctionInfo &IFI, InlinedArrayAllocasTy &InlinedArrayAllocas, int InlineHistory, bool InsertLifetime, function_ref &AARGetter, - ImportedFunctionsInliningStatistics &ImportedFunctionsStats) { + ImportedFunctionsInliningStatistics &ImportedFunctionsStats, + const TargetLibraryInfo *TLI) { Function *Callee = CS.getCalledFunction(); Function *Caller = CS.getCaller(); @@ -284,7 +285,7 @@ // Try to inline the function. Get the list of static allocas that were // inlined. - InlineResult IR = InlineFunction(CS, IFI, &AAR, InsertLifetime); + InlineResult IR = InlineFunction(CS, IFI, &AAR, InsertLifetime, nullptr, TLI); if (!IR) return IR; @@ -685,7 +686,7 @@ InlineResult IR = InlineCallIfPossible( CS, InlineInfo, InlinedArrayAllocas, InlineHistoryID, - InsertLifetime, AARGetter, ImportedFunctionsStats); + InsertLifetime, AARGetter, ImportedFunctionsStats, &TLI); if (!IR) { setInlineRemark(CS, std::string(IR) + "; " + inlineCostStr(*OIC)); ORE.emit([&]() { Index: lib/Transforms/IPO/PartialInlining.cpp =================================================================== --- lib/Transforms/IPO/PartialInlining.cpp +++ lib/Transforms/IPO/PartialInlining.cpp @@ -202,8 +202,9 @@ std::function *GetAC, std::function *GTTI, Optional> GBFI, - ProfileSummaryInfo *ProfSI) - : GetAssumptionCache(GetAC), GetTTI(GTTI), GetBFI(GBFI), PSI(ProfSI) {} + ProfileSummaryInfo *ProfSI, const TargetLibraryInfo *TLI) + : GetAssumptionCache(GetAC), GetTTI(GTTI), GetBFI(GBFI), PSI(ProfSI), + TLI(TLI) {} bool run(Module &M); // Main part of the transformation that calls helper functions to find @@ -269,6 +270,7 @@ std::function *GetTTI; Optional> GetBFI; ProfileSummaryInfo *PSI; + const TargetLibraryInfo *TLI; // Return the frequency of the OutlininingBB relative to F's entry point. // The result is no larger than 1 and is represented using BP. @@ -349,6 +351,7 @@ AU.addRequired(); AU.addRequired(); AU.addRequired(); + AU.addRequired(); } bool runOnModule(Module &M) override { @@ -360,6 +363,7 @@ &getAnalysis(); ProfileSummaryInfo *PSI = &getAnalysis().getPSI(); + auto &TLI = getAnalysis().getTLI(); std::function GetAssumptionCache = [&ACT](Function &F) -> AssumptionCache & { @@ -371,7 +375,7 @@ return TTIWP->getTTI(F); }; - return PartialInlinerImpl(&GetAssumptionCache, &GetTTI, NoneType::None, PSI) + return PartialInlinerImpl(&GetAssumptionCache, &GetTTI, NoneType::None, PSI, &TLI) .run(M); } }; @@ -1388,7 +1392,7 @@ // bail on vararg functions. if (!InlineFunction(CS, IFI, nullptr, true, (Cloner.ClonedOI ? Cloner.OutlinedFunctions.back().first - : nullptr))) + : nullptr), TLI)) continue; CallerORE.emit(OR); @@ -1469,6 +1473,7 @@ INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) +INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_END(PartialInlinerLegacyPass, "partial-inliner", "Partial Inliner", false, false) @@ -1497,7 +1502,8 @@ ProfileSummaryInfo *PSI = &AM.getResult(M); - if (PartialInlinerImpl(&GetAssumptionCache, &GetTTI, {GetBFI}, PSI) + auto &TLI = AM.getResult(M); + if (PartialInlinerImpl(&GetAssumptionCache, &GetTTI, {GetBFI}, PSI, &TLI) .run(M)) return PreservedAnalyses::none(); return PreservedAnalyses::all(); Index: lib/Transforms/Instrumentation/ThreadSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/ThreadSanitizer.cpp +++ lib/Transforms/Instrumentation/ThreadSanitizer.cpp @@ -101,7 +101,8 @@ bool instrumentMemIntrinsic(Instruction *I); void chooseInstructionsToInstrument(SmallVectorImpl &Local, SmallVectorImpl &All, - const DataLayout &DL); + const DataLayout &DL, + const TargetLibraryInfo *TLI); bool addrPointsToConstantData(Value *Addr); int getMemoryAccessFuncIndex(Value *Addr, const DataLayout &DL); void InsertRuntimeIgnores(Function &F); @@ -338,7 +339,7 @@ // 'All' is a vector of insns that will be instrumented. void ThreadSanitizer::chooseInstructionsToInstrument( SmallVectorImpl &Local, SmallVectorImpl &All, - const DataLayout &DL) { + const DataLayout &DL, const TargetLibraryInfo *TLI) { SmallPtrSet WriteTargets; // Iterate from the end. for (Instruction *I : reverse(Local)) { @@ -366,7 +367,7 @@ ? cast(I)->getPointerOperand() : cast(I)->getPointerOperand(); if (isa(GetUnderlyingObject(Addr, DL)) && - !PointerMayBeCaptured(Addr, true, true)) { + !PointerMayBeCaptured(Addr, true, true, TLI)) { // The variable is addressable but not captured, so it cannot be // referenced from a different thread and participate in a data race // (see llvm/Analysis/CaptureTracking.h for details). @@ -433,10 +434,11 @@ MemIntrinCalls.push_back(&Inst); HasCalls = true; chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores, - DL); + DL, TLI); } } - chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores, DL); + chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores, + DL, TLI); } // We have collected all loads and stores. Index: lib/Transforms/Scalar/DeadStoreElimination.cpp =================================================================== --- lib/Transforms/Scalar/DeadStoreElimination.cpp +++ lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -765,7 +765,8 @@ // Okay, so these are dead heap objects, but if the pointer never escapes // then it's leaked by this function anyways. - else if (isAllocLikeFn(&I, TLI) && !PointerMayBeCaptured(&I, true, true)) + else if (isAllocLikeFn(&I, TLI) && + !PointerMayBeCaptured(&I, true, true, TLI)) DeadStackObjects.insert(&I); } @@ -1169,7 +1170,7 @@ // throwing instruction; PointerMayBeCaptured // reasonably fast approximation. IsStoreDeadOnUnwind = isAllocLikeFn(Underlying, TLI) && - !PointerMayBeCaptured(Underlying, false, true); + !PointerMayBeCaptured(Underlying, false, true, TLI); } if (!IsStoreDeadOnUnwind) break; Index: lib/Transforms/Scalar/LICM.cpp =================================================================== --- lib/Transforms/Scalar/LICM.cpp +++ lib/Transforms/Scalar/LICM.cpp @@ -1708,7 +1708,7 @@ // weaker condition and handle only AllocLikeFunctions (which are // known to be noalias). TODO return isAllocLikeFn(Object, TLI) && - !PointerMayBeCaptured(Object, true, true); + !PointerMayBeCaptured(Object, true, true, TLI); } } // namespace @@ -1913,7 +1913,7 @@ Value *Object = GetUnderlyingObject(SomePtr, MDL); SafeToInsertStore = (isAllocLikeFn(Object, TLI) || isa(Object)) && - !PointerMayBeCaptured(Object, true, true); + !PointerMayBeCaptured(Object, true, true, TLI); } } Index: lib/Transforms/Scalar/PlaceSafepoints.cpp =================================================================== --- lib/Transforms/Scalar/PlaceSafepoints.cpp +++ lib/Transforms/Scalar/PlaceSafepoints.cpp @@ -653,7 +653,7 @@ // Do the actual inlining InlineFunctionInfo IFI; - bool InlineStatus = InlineFunction(PollCall, IFI); + bool InlineStatus = InlineFunction(PollCall, IFI, nullptr, true, &TLI); assert(InlineStatus && "inline must succeed"); (void)InlineStatus; // suppress warning in release-asserts Index: lib/Transforms/Utils/InlineFunction.cpp =================================================================== --- lib/Transforms/Utils/InlineFunction.cpp +++ lib/Transforms/Utils/InlineFunction.cpp @@ -87,14 +87,18 @@ llvm::InlineResult llvm::InlineFunction(CallInst *CI, InlineFunctionInfo &IFI, AAResults *CalleeAAR, - bool InsertLifetime) { - return InlineFunction(CallSite(CI), IFI, CalleeAAR, InsertLifetime); + bool InsertLifetime, + const TargetLibraryInfo *TLI) { + return InlineFunction(CallSite(CI), IFI, CalleeAAR, InsertLifetime, nullptr, + TLI); } llvm::InlineResult llvm::InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI, AAResults *CalleeAAR, - bool InsertLifetime) { - return InlineFunction(CallSite(II), IFI, CalleeAAR, InsertLifetime); + bool InsertLifetime, + const TargetLibraryInfo *TLI) { + return InlineFunction(CallSite(II), IFI, CalleeAAR, InsertLifetime, nullptr, + TLI); } namespace { @@ -924,7 +928,8 @@ /// parameters with noalias metadata specifying the new scope, and tag all /// non-derived loads, stores and memory intrinsics with the new alias scopes. static void AddAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap, - const DataLayout &DL, AAResults *CalleeAAR) { + const DataLayout &DL, AAResults *CalleeAAR, + const TargetLibraryInfo *TLI) { if (!EnableNoAliasConversion) return; @@ -1105,7 +1110,7 @@ // that the value cannot be locally captured. !PointerMayBeCapturedBefore(A, /* ReturnCaptures */ false, - /* StoreCaptures */ false, I, &DT))) + /* StoreCaptures */ false, I, &DT, TLI))) NoAliases.push_back(NewScopes[A]); } @@ -1502,7 +1507,8 @@ llvm::InlineResult llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, AAResults *CalleeAAR, bool InsertLifetime, - Function *ForwardVarArgsTo) { + Function *ForwardVarArgsTo, + const TargetLibraryInfo *TLI) { Instruction *TheCall = CS.getInstruction(); assert(TheCall->getParent() && TheCall->getFunction() && "Instruction not in function!"); @@ -1760,7 +1766,7 @@ CloneAliasScopeMetadata(CS, VMap); // Add noalias metadata if necessary. - AddAliasScopeMetadata(CS, VMap, DL, CalleeAAR); + AddAliasScopeMetadata(CS, VMap, DL, CalleeAAR, TLI); // Propagate llvm.mem.parallel_loop_access if necessary. PropagateParallelLoopAccessMetadata(CS, VMap); Index: lib/Transforms/Utils/SimplifyLibCalls.cpp =================================================================== --- lib/Transforms/Utils/SimplifyLibCalls.cpp +++ lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -146,7 +146,7 @@ return false; inferLibFuncAttributes(*CI->getCalledFunction(), *TLI); - if (PointerMayBeCaptured(File, true, true)) + if (PointerMayBeCaptured(File, true, true, TLI)) return false; return true;