[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 36f1c3db66,
but without asserting, just bailout once cycle is detected.
This commit is contained in:
Roman Lebedev 2021-03-15 11:51:23 +03:00
parent 0c5b789c73
commit aa440ba24d
No known key found for this signature in database
GPG Key ID: 083C3EBB4A1689E0
1 changed files with 6 additions and 0 deletions

View File

@ -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 ||