diff options
author | Roman Lebedev <lebedev.ri@gmail.com> | 2021-03-15 11:51:23 +0300 |
---|---|---|
committer | Roman Lebedev <lebedev.ri@gmail.com> | 2021-03-15 13:51:02 +0300 |
commit | aa440ba24dc25e4c95f6dcf8ff647024f3b12661 (patch) | |
tree | d8c48ded0ce1847e63bafda4790e4ee264127301 /llvm/lib/Analysis/ValueTracking.cpp | |
parent | 0c5b789c7342ee8384507c3242fc256e23248c4d (diff) | |
download | llvm-aa440ba24dc25e4c95f6dcf8ff647024f3b12661.zip llvm-aa440ba24dc25e4c95f6dcf8ff647024f3b12661.tar.gz llvm-aa440ba24dc25e4c95f6dcf8ff647024f3b12661.tar.bz2 |
[NFCI][ValueTracking] getUnderlyingObject(): gracefully handle cycles
Normally, this function just doesn't bother about cycles,
and hopes that the caller supplied small-enough depth
so that at worst it will take a potentially large,
but limited amount of time. But that obviously doesn't work
if there is no depth limit.
This reapples 36f1c3db66f7268ea3183bcf0bbf05b3e1c570b4,
but without asserting, just bailout once cycle is detected.
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 79399cf..5fe0269 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4165,7 +4165,13 @@ static bool isSameUnderlyingObjectInLoop(const PHINode *PN, const Value *llvm::getUnderlyingObject(const Value *V, unsigned MaxLookup) { if (!V->getType()->isPointerTy()) return V; + // Keep track of all the values we have recursed through. + SmallPtrSet<const Value *, 8> Visited; for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) { + // Did we encounter this value already? + if (!Visited.insert(V).second) + return V; // Cycle detected, we must be in an unreachable code. + // Otherwise, recurse further. if (auto *GEP = dyn_cast<GEPOperator>(V)) { V = GEP->getPointerOperand(); } else if (Operator::getOpcode(V) == Instruction::BitCast || |