aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/MemoryBuiltins.cpp
diff options
context:
space:
mode:
authorErik Pilkington <erik.pilkington@gmail.com>2019-04-10 23:42:11 +0000
committerErik Pilkington <erik.pilkington@gmail.com>2019-04-10 23:42:11 +0000
commitcb5c7bd9ebfa004751a1b8815a281f51de2083dc (patch)
treeafab549d77bf0b2dac02196a236c12667eea244d /llvm/lib/Analysis/MemoryBuiltins.cpp
parent2f46de8c0b253e40ea84bb99e6a77079abd86daa (diff)
downloadllvm-cb5c7bd9ebfa004751a1b8815a281f51de2083dc.zip
llvm-cb5c7bd9ebfa004751a1b8815a281f51de2083dc.tar.gz
llvm-cb5c7bd9ebfa004751a1b8815a281f51de2083dc.tar.bz2
Fix a hang when lowering __builtin_dynamic_object_size
If the ObjectSizeOffsetEvaluator fails to fold the object size call, then it may litter some unused instructions in the function. When done repeatably in InstCombine, this results in an infinite loop. Fix this by tracking the set of instructions that were inserted, then removing them on failure. rdar://49172227 Differential revision: https://reviews.llvm.org/D60298 llvm-svn: 358146
Diffstat (limited to 'llvm/lib/Analysis/MemoryBuiltins.cpp')
-rw-r--r--llvm/lib/Analysis/MemoryBuiltins.cpp22
1 files changed, 18 insertions, 4 deletions
diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp
index 56332bb..0825426 100644
--- a/llvm/lib/Analysis/MemoryBuiltins.cpp
+++ b/llvm/lib/Analysis/MemoryBuiltins.cpp
@@ -765,7 +765,10 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitInstruction(Instruction &I) {
ObjectSizeOffsetEvaluator::ObjectSizeOffsetEvaluator(
const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context,
ObjectSizeOpts EvalOpts)
- : DL(DL), TLI(TLI), Context(Context), Builder(Context, TargetFolder(DL)),
+ : DL(DL), TLI(TLI), Context(Context),
+ Builder(Context, TargetFolder(DL),
+ IRBuilderCallbackInserter(
+ [&](Instruction *I) { InsertedInstructions.insert(I); })),
EvalOpts(EvalOpts) {
// IntTy and Zero must be set for each compute() since the address space may
// be different for later objects.
@@ -788,9 +791,16 @@ SizeOffsetEvalType ObjectSizeOffsetEvaluator::compute(Value *V) {
if (CacheIt != CacheMap.end() && anyKnown(CacheIt->second))
CacheMap.erase(CacheIt);
}
+
+ // Erase any instructions we inserted as part of the traversal.
+ for (Instruction *I : InsertedInstructions) {
+ I->replaceAllUsesWith(UndefValue::get(I->getType()));
+ I->eraseFromParent();
+ }
}
SeenVals.clear();
+ InsertedInstructions.clear();
return Result;
}
@@ -934,24 +944,28 @@ SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitPHINode(PHINode &PHI) {
if (!bothKnown(EdgeData)) {
OffsetPHI->replaceAllUsesWith(UndefValue::get(IntTy));
OffsetPHI->eraseFromParent();
+ InsertedInstructions.erase(OffsetPHI);
SizePHI->replaceAllUsesWith(UndefValue::get(IntTy));
SizePHI->eraseFromParent();
+ InsertedInstructions.erase(SizePHI);
return unknown();
}
SizePHI->addIncoming(EdgeData.first, PHI.getIncomingBlock(i));
OffsetPHI->addIncoming(EdgeData.second, PHI.getIncomingBlock(i));
}
- Value *Size = SizePHI, *Offset = OffsetPHI, *Tmp;
- if ((Tmp = SizePHI->hasConstantValue())) {
+ Value *Size = SizePHI, *Offset = OffsetPHI;
+ if (Value *Tmp = SizePHI->hasConstantValue()) {
Size = Tmp;
SizePHI->replaceAllUsesWith(Size);
SizePHI->eraseFromParent();
+ InsertedInstructions.erase(SizePHI);
}
- if ((Tmp = OffsetPHI->hasConstantValue())) {
+ if (Value *Tmp = OffsetPHI->hasConstantValue()) {
Offset = Tmp;
OffsetPHI->replaceAllUsesWith(Offset);
OffsetPHI->eraseFromParent();
+ InsertedInstructions.erase(OffsetPHI);
}
return std::make_pair(Size, Offset);
}