1f22ef01cSRoman Divacky //===--- CaptureTracking.cpp - Determine whether a pointer is captured ----===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This file contains routines that help determine which pointers are captured.
11f22ef01cSRoman Divacky // A pointer value is captured if the function makes a copy of any part of the
12f22ef01cSRoman Divacky // pointer that outlives the call. Not being captured means, more or less, that
13f22ef01cSRoman Divacky // the pointer is only dereferenced and not stored in a global. Returning part
14f22ef01cSRoman Divacky // of the pointer as the function return value may or may not count as capturing
15f22ef01cSRoman Divacky // the pointer, depending on the context.
16f22ef01cSRoman Divacky //
17f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
18f22ef01cSRoman Divacky
19db17bf38SDimitry Andric #include "llvm/Analysis/CaptureTracking.h"
20f22ef01cSRoman Divacky #include "llvm/ADT/SmallSet.h"
21f22ef01cSRoman Divacky #include "llvm/ADT/SmallVector.h"
22139f7f9bSDimitry Andric #include "llvm/Analysis/AliasAnalysis.h"
2391bc56edSDimitry Andric #include "llvm/Analysis/CFG.h"
247d523365SDimitry Andric #include "llvm/Analysis/OrderedBasicBlock.h"
254ba319b5SDimitry Andric #include "llvm/Analysis/ValueTracking.h"
26139f7f9bSDimitry Andric #include "llvm/IR/Constants.h"
2791bc56edSDimitry Andric #include "llvm/IR/Dominators.h"
28139f7f9bSDimitry Andric #include "llvm/IR/Instructions.h"
293ca95b02SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
30139f7f9bSDimitry Andric
31f22ef01cSRoman Divacky using namespace llvm;
32f22ef01cSRoman Divacky
~CaptureTracker()33dff0c46cSDimitry Andric CaptureTracker::~CaptureTracker() {}
34dff0c46cSDimitry Andric
shouldExplore(const Use * U)3591bc56edSDimitry Andric bool CaptureTracker::shouldExplore(const Use *U) { return true; }
363861d79fSDimitry Andric
37dff0c46cSDimitry Andric namespace {
38dff0c46cSDimitry Andric struct SimpleCaptureTracker : public CaptureTracker {
SimpleCaptureTracker__anon3cd3bb0f0111::SimpleCaptureTracker39dff0c46cSDimitry Andric explicit SimpleCaptureTracker(bool ReturnCaptures)
40dff0c46cSDimitry Andric : ReturnCaptures(ReturnCaptures), Captured(false) {}
41dff0c46cSDimitry Andric
tooManyUses__anon3cd3bb0f0111::SimpleCaptureTracker4291bc56edSDimitry Andric void tooManyUses() override { Captured = true; }
43dff0c46cSDimitry Andric
captured__anon3cd3bb0f0111::SimpleCaptureTracker4491bc56edSDimitry Andric bool captured(const Use *U) override {
45dff0c46cSDimitry Andric if (isa<ReturnInst>(U->getUser()) && !ReturnCaptures)
46dff0c46cSDimitry Andric return false;
47dff0c46cSDimitry Andric
48dff0c46cSDimitry Andric Captured = true;
49dff0c46cSDimitry Andric return true;
50dff0c46cSDimitry Andric }
51dff0c46cSDimitry Andric
52dff0c46cSDimitry Andric bool ReturnCaptures;
53dff0c46cSDimitry Andric
54dff0c46cSDimitry Andric bool Captured;
55dff0c46cSDimitry Andric };
5691bc56edSDimitry Andric
5791bc56edSDimitry Andric /// Only find pointer captures which happen before the given instruction. Uses
5891bc56edSDimitry Andric /// the dominator tree to determine whether one instruction is before another.
5991bc56edSDimitry Andric /// Only support the case where the Value is defined in the same basic block
6091bc56edSDimitry Andric /// as the given instruction and the use.
6191bc56edSDimitry Andric struct CapturesBefore : public CaptureTracker {
623dac3a9bSDimitry Andric
CapturesBefore__anon3cd3bb0f0111::CapturesBefore634ba319b5SDimitry Andric CapturesBefore(bool ReturnCaptures, const Instruction *I, const DominatorTree *DT,
647d523365SDimitry Andric bool IncludeI, OrderedBasicBlock *IC)
657d523365SDimitry Andric : OrderedBB(IC), BeforeHere(I), DT(DT),
663dac3a9bSDimitry Andric ReturnCaptures(ReturnCaptures), IncludeI(IncludeI), Captured(false) {}
6791bc56edSDimitry Andric
tooManyUses__anon3cd3bb0f0111::CapturesBefore6891bc56edSDimitry Andric void tooManyUses() override { Captured = true; }
6991bc56edSDimitry Andric
isSafeToPrune__anon3cd3bb0f0111::CapturesBefore703dac3a9bSDimitry Andric bool isSafeToPrune(Instruction *I) {
7191bc56edSDimitry Andric BasicBlock *BB = I->getParent();
7291bc56edSDimitry Andric // We explore this usage only if the usage can reach "BeforeHere".
7391bc56edSDimitry Andric // If use is not reachable from entry, there is no need to explore.
7491bc56edSDimitry Andric if (BeforeHere != I && !DT->isReachableFromEntry(BB))
753dac3a9bSDimitry Andric return true;
763dac3a9bSDimitry Andric
773dac3a9bSDimitry Andric // Compute the case where both instructions are inside the same basic
783dac3a9bSDimitry Andric // block. Since instructions in the same BB as BeforeHere are numbered in
797d523365SDimitry Andric // 'OrderedBB', avoid using 'dominates' and 'isPotentiallyReachable'
803dac3a9bSDimitry Andric // which are very expensive for large basic blocks.
813dac3a9bSDimitry Andric if (BB == BeforeHere->getParent()) {
823dac3a9bSDimitry Andric // 'I' dominates 'BeforeHere' => not safe to prune.
833dac3a9bSDimitry Andric //
847d523365SDimitry Andric // The value defined by an invoke dominates an instruction only
857d523365SDimitry Andric // if it dominates every instruction in UseBB. A PHI is dominated only
867d523365SDimitry Andric // if the instruction dominates every possible use in the UseBB. Since
873dac3a9bSDimitry Andric // UseBB == BB, avoid pruning.
883dac3a9bSDimitry Andric if (isa<InvokeInst>(BeforeHere) || isa<PHINode>(I) || I == BeforeHere)
8991bc56edSDimitry Andric return false;
907d523365SDimitry Andric if (!OrderedBB->dominates(BeforeHere, I))
913dac3a9bSDimitry Andric return false;
923dac3a9bSDimitry Andric
933dac3a9bSDimitry Andric // 'BeforeHere' comes before 'I', it's safe to prune if we also
943dac3a9bSDimitry Andric // guarantee that 'I' never reaches 'BeforeHere' through a back-edge or
953dac3a9bSDimitry Andric // by its successors, i.e, prune if:
963dac3a9bSDimitry Andric //
97c4394386SDimitry Andric // (1) BB is an entry block or have no successors.
98c4394386SDimitry Andric // (2) There's no path coming back through BB successors.
993dac3a9bSDimitry Andric if (BB == &BB->getParent()->getEntryBlock() ||
1003dac3a9bSDimitry Andric !BB->getTerminator()->getNumSuccessors())
1013dac3a9bSDimitry Andric return true;
1023dac3a9bSDimitry Andric
1033dac3a9bSDimitry Andric SmallVector<BasicBlock*, 32> Worklist;
1043dac3a9bSDimitry Andric Worklist.append(succ_begin(BB), succ_end(BB));
1057d523365SDimitry Andric return !isPotentiallyReachableFromMany(Worklist, BB, DT);
1063dac3a9bSDimitry Andric }
1073dac3a9bSDimitry Andric
10891bc56edSDimitry Andric // If the value is defined in the same basic block as use and BeforeHere,
10991bc56edSDimitry Andric // there is no need to explore the use if BeforeHere dominates use.
11091bc56edSDimitry Andric // Check whether there is a path from I to BeforeHere.
11191bc56edSDimitry Andric if (BeforeHere != I && DT->dominates(BeforeHere, I) &&
11291bc56edSDimitry Andric !isPotentiallyReachable(I, BeforeHere, DT))
1133dac3a9bSDimitry Andric return true;
1143dac3a9bSDimitry Andric
11591bc56edSDimitry Andric return false;
1163dac3a9bSDimitry Andric }
1173dac3a9bSDimitry Andric
shouldExplore__anon3cd3bb0f0111::CapturesBefore1183dac3a9bSDimitry Andric bool shouldExplore(const Use *U) override {
1193dac3a9bSDimitry Andric Instruction *I = cast<Instruction>(U->getUser());
1203dac3a9bSDimitry Andric
1213dac3a9bSDimitry Andric if (BeforeHere == I && !IncludeI)
1223dac3a9bSDimitry Andric return false;
1233dac3a9bSDimitry Andric
1243dac3a9bSDimitry Andric if (isSafeToPrune(I))
1253dac3a9bSDimitry Andric return false;
1263dac3a9bSDimitry Andric
12791bc56edSDimitry Andric return true;
12891bc56edSDimitry Andric }
12991bc56edSDimitry Andric
captured__anon3cd3bb0f0111::CapturesBefore13091bc56edSDimitry Andric bool captured(const Use *U) override {
13191bc56edSDimitry Andric if (isa<ReturnInst>(U->getUser()) && !ReturnCaptures)
13291bc56edSDimitry Andric return false;
13391bc56edSDimitry Andric
1343dac3a9bSDimitry Andric if (!shouldExplore(U))
13591bc56edSDimitry Andric return false;
13691bc56edSDimitry Andric
13791bc56edSDimitry Andric Captured = true;
13891bc56edSDimitry Andric return true;
13991bc56edSDimitry Andric }
14091bc56edSDimitry Andric
1417d523365SDimitry Andric OrderedBasicBlock *OrderedBB;
14291bc56edSDimitry Andric const Instruction *BeforeHere;
1434ba319b5SDimitry Andric const DominatorTree *DT;
14491bc56edSDimitry Andric
14591bc56edSDimitry Andric bool ReturnCaptures;
14691bc56edSDimitry Andric bool IncludeI;
14791bc56edSDimitry Andric
14891bc56edSDimitry Andric bool Captured;
14991bc56edSDimitry Andric };
1503dac3a9bSDimitry Andric }
151f22ef01cSRoman Divacky
152f22ef01cSRoman Divacky /// PointerMayBeCaptured - Return true if this pointer value may be captured
153f22ef01cSRoman Divacky /// by the enclosing function (which is required to exist). This routine can
154f22ef01cSRoman Divacky /// be expensive, so consider caching the results. The boolean ReturnCaptures
155f22ef01cSRoman Divacky /// specifies whether returning the value (or part of it) from the function
156f22ef01cSRoman Divacky /// counts as capturing it or not. The boolean StoreCaptures specified whether
157f22ef01cSRoman Divacky /// storing the value (or part of it) into memory anywhere automatically
158f22ef01cSRoman Divacky /// counts as capturing it or not.
PointerMayBeCaptured(const Value * V,bool ReturnCaptures,bool StoreCaptures,unsigned MaxUsesToExplore)159f22ef01cSRoman Divacky bool llvm::PointerMayBeCaptured(const Value *V,
160*b5893f02SDimitry Andric bool ReturnCaptures, bool StoreCaptures,
161*b5893f02SDimitry Andric unsigned MaxUsesToExplore) {
162dff0c46cSDimitry Andric assert(!isa<GlobalValue>(V) &&
163dff0c46cSDimitry Andric "It doesn't make sense to ask whether a global is captured.");
164dff0c46cSDimitry Andric
165dff0c46cSDimitry Andric // TODO: If StoreCaptures is not true, we could do Fancy analysis
166dff0c46cSDimitry Andric // to determine whether this store is not actually an escape point.
167dff0c46cSDimitry Andric // In that case, BasicAliasAnalysis should be updated as well to
168dff0c46cSDimitry Andric // take advantage of this.
169dff0c46cSDimitry Andric (void)StoreCaptures;
170dff0c46cSDimitry Andric
171dff0c46cSDimitry Andric SimpleCaptureTracker SCT(ReturnCaptures);
172*b5893f02SDimitry Andric PointerMayBeCaptured(V, &SCT, MaxUsesToExplore);
173dff0c46cSDimitry Andric return SCT.Captured;
174dff0c46cSDimitry Andric }
175dff0c46cSDimitry Andric
17691bc56edSDimitry Andric /// PointerMayBeCapturedBefore - Return true if this pointer value may be
17791bc56edSDimitry Andric /// captured by the enclosing function (which is required to exist). If a
17891bc56edSDimitry Andric /// DominatorTree is provided, only captures which happen before the given
17991bc56edSDimitry Andric /// instruction are considered. This routine can be expensive, so consider
18091bc56edSDimitry Andric /// caching the results. The boolean ReturnCaptures specifies whether
18191bc56edSDimitry Andric /// returning the value (or part of it) from the function counts as capturing
18291bc56edSDimitry Andric /// it or not. The boolean StoreCaptures specified whether storing the value
18391bc56edSDimitry Andric /// (or part of it) into memory anywhere automatically counts as capturing it
1847d523365SDimitry Andric /// or not. A ordered basic block \p OBB can be used in order to speed up
1857d523365SDimitry Andric /// queries about relative order among instructions in the same basic block.
PointerMayBeCapturedBefore(const Value * V,bool ReturnCaptures,bool StoreCaptures,const Instruction * I,const DominatorTree * DT,bool IncludeI,OrderedBasicBlock * OBB,unsigned MaxUsesToExplore)18691bc56edSDimitry Andric bool llvm::PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures,
18791bc56edSDimitry Andric bool StoreCaptures, const Instruction *I,
1884ba319b5SDimitry Andric const DominatorTree *DT, bool IncludeI,
189*b5893f02SDimitry Andric OrderedBasicBlock *OBB,
190*b5893f02SDimitry Andric unsigned MaxUsesToExplore) {
19191bc56edSDimitry Andric assert(!isa<GlobalValue>(V) &&
19291bc56edSDimitry Andric "It doesn't make sense to ask whether a global is captured.");
1937d523365SDimitry Andric bool UseNewOBB = OBB == nullptr;
19491bc56edSDimitry Andric
19591bc56edSDimitry Andric if (!DT)
196*b5893f02SDimitry Andric return PointerMayBeCaptured(V, ReturnCaptures, StoreCaptures,
197*b5893f02SDimitry Andric MaxUsesToExplore);
1987d523365SDimitry Andric if (UseNewOBB)
1997d523365SDimitry Andric OBB = new OrderedBasicBlock(I->getParent());
20091bc56edSDimitry Andric
20191bc56edSDimitry Andric // TODO: See comment in PointerMayBeCaptured regarding what could be done
20291bc56edSDimitry Andric // with StoreCaptures.
20391bc56edSDimitry Andric
2047d523365SDimitry Andric CapturesBefore CB(ReturnCaptures, I, DT, IncludeI, OBB);
205*b5893f02SDimitry Andric PointerMayBeCaptured(V, &CB, MaxUsesToExplore);
2067d523365SDimitry Andric
2077d523365SDimitry Andric if (UseNewOBB)
2087d523365SDimitry Andric delete OBB;
20991bc56edSDimitry Andric return CB.Captured;
21091bc56edSDimitry Andric }
21191bc56edSDimitry Andric
PointerMayBeCaptured(const Value * V,CaptureTracker * Tracker,unsigned MaxUsesToExplore)212*b5893f02SDimitry Andric void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker,
213*b5893f02SDimitry Andric unsigned MaxUsesToExplore) {
214f22ef01cSRoman Divacky assert(V->getType()->isPointerTy() && "Capture is for pointers only!");
215*b5893f02SDimitry Andric SmallVector<const Use *, DefaultMaxUsesToExplore> Worklist;
216*b5893f02SDimitry Andric SmallSet<const Use *, DefaultMaxUsesToExplore> Visited;
217f22ef01cSRoman Divacky
2184ba319b5SDimitry Andric auto AddUses = [&](const Value *V) {
219*b5893f02SDimitry Andric unsigned Count = 0;
22091bc56edSDimitry Andric for (const Use &U : V->uses()) {
221f22ef01cSRoman Divacky // If there are lots of uses, conservatively say that the value
222f22ef01cSRoman Divacky // is captured to avoid taking too much compile time.
223*b5893f02SDimitry Andric if (Count++ >= MaxUsesToExplore)
224dff0c46cSDimitry Andric return Tracker->tooManyUses();
2254ba319b5SDimitry Andric if (!Visited.insert(&U).second)
2264ba319b5SDimitry Andric continue;
2274ba319b5SDimitry Andric if (!Tracker->shouldExplore(&U))
2284ba319b5SDimitry Andric continue;
22991bc56edSDimitry Andric Worklist.push_back(&U);
230f22ef01cSRoman Divacky }
2314ba319b5SDimitry Andric };
2324ba319b5SDimitry Andric AddUses(V);
233f22ef01cSRoman Divacky
234f22ef01cSRoman Divacky while (!Worklist.empty()) {
23591bc56edSDimitry Andric const Use *U = Worklist.pop_back_val();
236f22ef01cSRoman Divacky Instruction *I = cast<Instruction>(U->getUser());
237f22ef01cSRoman Divacky V = U->get();
238f22ef01cSRoman Divacky
239f22ef01cSRoman Divacky switch (I->getOpcode()) {
240f22ef01cSRoman Divacky case Instruction::Call:
241f22ef01cSRoman Divacky case Instruction::Invoke: {
242*b5893f02SDimitry Andric auto *Call = cast<CallBase>(I);
243f22ef01cSRoman Divacky // Not captured if the callee is readonly, doesn't return a copy through
244f22ef01cSRoman Divacky // its return value and doesn't unwind (a readonly function can leak bits
245f22ef01cSRoman Divacky // by throwing an exception or not depending on the input value).
246*b5893f02SDimitry Andric if (Call->onlyReadsMemory() && Call->doesNotThrow() &&
247*b5893f02SDimitry Andric Call->getType()->isVoidTy())
248f22ef01cSRoman Divacky break;
249f22ef01cSRoman Divacky
2504ba319b5SDimitry Andric // The pointer is not captured if returned pointer is not captured.
2514ba319b5SDimitry Andric // NOTE: CaptureTracking users should not assume that only functions
2524ba319b5SDimitry Andric // marked with nocapture do not capture. This means that places like
2534ba319b5SDimitry Andric // GetUnderlyingObject in ValueTracking or DecomposeGEPExpression
2544ba319b5SDimitry Andric // in BasicAA also need to know about this property.
255*b5893f02SDimitry Andric if (isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(Call)) {
256*b5893f02SDimitry Andric AddUses(Call);
2574ba319b5SDimitry Andric break;
2584ba319b5SDimitry Andric }
2594ba319b5SDimitry Andric
2603ca95b02SDimitry Andric // Volatile operations effectively capture the memory location that they
2613ca95b02SDimitry Andric // load and store to.
262*b5893f02SDimitry Andric if (auto *MI = dyn_cast<MemIntrinsic>(Call))
2633ca95b02SDimitry Andric if (MI->isVolatile())
2643ca95b02SDimitry Andric if (Tracker->captured(U))
2653ca95b02SDimitry Andric return;
2663ca95b02SDimitry Andric
267f22ef01cSRoman Divacky // Not captured if only passed via 'nocapture' arguments. Note that
268f22ef01cSRoman Divacky // calling a function pointer does not in itself cause the pointer to
269f22ef01cSRoman Divacky // be captured. This is a subtle point considering that (for example)
270f22ef01cSRoman Divacky // the callee might return its own address. It is analogous to saying
271f22ef01cSRoman Divacky // that loading a value from a pointer does not cause the pointer to be
272f22ef01cSRoman Divacky // captured, even though the loaded value might be the pointer itself
273f22ef01cSRoman Divacky // (think of self-referential objects).
274*b5893f02SDimitry Andric for (auto IdxOpPair : enumerate(Call->data_ops())) {
275*b5893f02SDimitry Andric int Idx = IdxOpPair.index();
276*b5893f02SDimitry Andric Value *A = IdxOpPair.value();
277*b5893f02SDimitry Andric if (A == V && !Call->doesNotCapture(Idx))
278f22ef01cSRoman Divacky // The parameter is not marked 'nocapture' - captured.
279dff0c46cSDimitry Andric if (Tracker->captured(U))
280dff0c46cSDimitry Andric return;
281*b5893f02SDimitry Andric }
282f22ef01cSRoman Divacky break;
283f22ef01cSRoman Divacky }
284f22ef01cSRoman Divacky case Instruction::Load:
2853ca95b02SDimitry Andric // Volatile loads make the address observable.
2863ca95b02SDimitry Andric if (cast<LoadInst>(I)->isVolatile())
2873ca95b02SDimitry Andric if (Tracker->captured(U))
2883ca95b02SDimitry Andric return;
289f22ef01cSRoman Divacky break;
2902754fe60SDimitry Andric case Instruction::VAArg:
2912754fe60SDimitry Andric // "va-arg" from a pointer does not cause it to be captured.
2922754fe60SDimitry Andric break;
293f22ef01cSRoman Divacky case Instruction::Store:
294f22ef01cSRoman Divacky // Stored the pointer - conservatively assume it may be captured.
2953ca95b02SDimitry Andric // Volatile stores make the address observable.
2963ca95b02SDimitry Andric if (V == I->getOperand(0) || cast<StoreInst>(I)->isVolatile())
297dff0c46cSDimitry Andric if (Tracker->captured(U))
298dff0c46cSDimitry Andric return;
299f22ef01cSRoman Divacky break;
3003ca95b02SDimitry Andric case Instruction::AtomicRMW: {
3013ca95b02SDimitry Andric // atomicrmw conceptually includes both a load and store from
3023ca95b02SDimitry Andric // the same location.
3033ca95b02SDimitry Andric // As with a store, the location being accessed is not captured,
3043ca95b02SDimitry Andric // but the value being stored is.
3053ca95b02SDimitry Andric // Volatile stores make the address observable.
3063ca95b02SDimitry Andric auto *ARMWI = cast<AtomicRMWInst>(I);
3073ca95b02SDimitry Andric if (ARMWI->getValOperand() == V || ARMWI->isVolatile())
3083ca95b02SDimitry Andric if (Tracker->captured(U))
3093ca95b02SDimitry Andric return;
3103ca95b02SDimitry Andric break;
3113ca95b02SDimitry Andric }
3123ca95b02SDimitry Andric case Instruction::AtomicCmpXchg: {
3133ca95b02SDimitry Andric // cmpxchg conceptually includes both a load and store from
3143ca95b02SDimitry Andric // the same location.
3153ca95b02SDimitry Andric // As with a store, the location being accessed is not captured,
3163ca95b02SDimitry Andric // but the value being stored is.
3173ca95b02SDimitry Andric // Volatile stores make the address observable.
3183ca95b02SDimitry Andric auto *ACXI = cast<AtomicCmpXchgInst>(I);
3193ca95b02SDimitry Andric if (ACXI->getCompareOperand() == V || ACXI->getNewValOperand() == V ||
3203ca95b02SDimitry Andric ACXI->isVolatile())
3213ca95b02SDimitry Andric if (Tracker->captured(U))
3223ca95b02SDimitry Andric return;
3233ca95b02SDimitry Andric break;
3243ca95b02SDimitry Andric }
325f22ef01cSRoman Divacky case Instruction::BitCast:
326f22ef01cSRoman Divacky case Instruction::GetElementPtr:
327f22ef01cSRoman Divacky case Instruction::PHI:
328f22ef01cSRoman Divacky case Instruction::Select:
32991bc56edSDimitry Andric case Instruction::AddrSpaceCast:
330f22ef01cSRoman Divacky // The original value is not captured via this if the new value isn't.
3314ba319b5SDimitry Andric AddUses(I);
332f22ef01cSRoman Divacky break;
3333ca95b02SDimitry Andric case Instruction::ICmp: {
334f22ef01cSRoman Divacky // Don't count comparisons of a no-alias return value against null as
335f22ef01cSRoman Divacky // captures. This allows us to ignore comparisons of malloc results
336f22ef01cSRoman Divacky // with null, for example.
337f22ef01cSRoman Divacky if (ConstantPointerNull *CPN =
338f22ef01cSRoman Divacky dyn_cast<ConstantPointerNull>(I->getOperand(1)))
339f22ef01cSRoman Divacky if (CPN->getType()->getAddressSpace() == 0)
340f785676fSDimitry Andric if (isNoAliasCall(V->stripPointerCasts()))
341f22ef01cSRoman Divacky break;
3423ca95b02SDimitry Andric // Comparison against value stored in global variable. Given the pointer
3433ca95b02SDimitry Andric // does not escape, its value cannot be guessed and stored separately in a
3443ca95b02SDimitry Andric // global variable.
3453ca95b02SDimitry Andric unsigned OtherIndex = (I->getOperand(0) == V) ? 1 : 0;
3463ca95b02SDimitry Andric auto *LI = dyn_cast<LoadInst>(I->getOperand(OtherIndex));
3473ca95b02SDimitry Andric if (LI && isa<GlobalVariable>(LI->getPointerOperand()))
3483ca95b02SDimitry Andric break;
349f22ef01cSRoman Divacky // Otherwise, be conservative. There are crazy ways to capture pointers
350f22ef01cSRoman Divacky // using comparisons.
351dff0c46cSDimitry Andric if (Tracker->captured(U))
352dff0c46cSDimitry Andric return;
353dff0c46cSDimitry Andric break;
3543ca95b02SDimitry Andric }
355f22ef01cSRoman Divacky default:
356f22ef01cSRoman Divacky // Something else - be conservative and say it is captured.
357dff0c46cSDimitry Andric if (Tracker->captured(U))
358dff0c46cSDimitry Andric return;
359dff0c46cSDimitry Andric break;
360f22ef01cSRoman Divacky }
361f22ef01cSRoman Divacky }
362f22ef01cSRoman Divacky
363dff0c46cSDimitry Andric // All uses examined.
364f22ef01cSRoman Divacky }
365