aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/CodeGenPrepare.cpp
diff options
context:
space:
mode:
authorTim Northover <t.p.northover@gmail.com>2020-07-15 09:49:49 +0100
committerTim Northover <t.p.northover@gmail.com>2020-07-15 15:19:21 +0100
commit37b96d51d0cfc82a64598aaae2a567fa77e44de9 (patch)
tree428e4d090011c5f4087d693ccf02a385173105be /llvm/lib/CodeGen/CodeGenPrepare.cpp
parent313fca6520b43d95abb73e7c78a252a60ee4cf48 (diff)
downloadllvm-37b96d51d0cfc82a64598aaae2a567fa77e44de9.zip
llvm-37b96d51d0cfc82a64598aaae2a567fa77e44de9.tar.gz
llvm-37b96d51d0cfc82a64598aaae2a567fa77e44de9.tar.bz2
CodeGenPrep: remove AssertingVH references before deleting dead instructions.
CodeGenPrepare keeps fairly close track of various instructions it's seen, particularly GEPs, in maps and vectors. However, sometimes those instructions become dead and get removed while it's still executing. This triggers AssertingVH references to them in an asserts build and could lead to miscompiles in a release build (I've only seen a later segfault though). So this patch adds a callback to RecursivelyDeleteTriviallyDeadInstructions which can make sure the instruction about to be deleted is removed from CodeGenPrepare's data structures.
Diffstat (limited to 'llvm/lib/CodeGen/CodeGenPrepare.cpp')
-rw-r--r--llvm/lib/CodeGen/CodeGenPrepare.cpp52
1 files changed, 43 insertions, 9 deletions
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index e8b8e6c..465ba08 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -376,6 +376,7 @@ class TypePromotionTransaction;
return *DT;
}
+ void removeAllAssertingVHReferences(Value *V);
bool eliminateFallThrough(Function &F);
bool eliminateMostlyEmptyBlocks(Function &F);
BasicBlock *findDestBlockOfMergeableEmptyBlock(BasicBlock *BB);
@@ -383,6 +384,7 @@ class TypePromotionTransaction;
void eliminateMostlyEmptyBlock(BasicBlock *BB);
bool isMergingEmptyBlockProfitable(BasicBlock *BB, BasicBlock *DestBB,
bool isPreheader);
+ bool makeBitReverse(Instruction &I);
bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT);
bool optimizeInst(Instruction *I, bool &ModifiedDT);
bool optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
@@ -601,6 +603,33 @@ bool CodeGenPrepare::runOnFunction(Function &F) {
return EverMadeChange;
}
+/// An instruction is about to be deleted, so remove all references to it in our
+/// GEP-tracking data strcutures.
+void CodeGenPrepare::removeAllAssertingVHReferences(Value *V) {
+ LargeOffsetGEPMap.erase(V);
+ NewGEPBases.erase(V);
+
+ auto GEP = dyn_cast<GetElementPtrInst>(V);
+ if (!GEP)
+ return;
+
+ LargeOffsetGEPID.erase(GEP);
+
+ auto VecI = LargeOffsetGEPMap.find(GEP->getPointerOperand());
+ if (VecI == LargeOffsetGEPMap.end())
+ return;
+
+ auto &GEPVector = VecI->second;
+ const auto &I = std::find_if(GEPVector.begin(), GEPVector.end(),
+ [=](auto &Elt) { return Elt.first == GEP; });
+ if (I == GEPVector.end())
+ return;
+
+ GEPVector.erase(I);
+ if (GEPVector.empty())
+ LargeOffsetGEPMap.erase(VecI);
+}
+
// Verify BFI has been updated correctly by recomputing BFI and comparing them.
void LLVM_ATTRIBUTE_UNUSED CodeGenPrepare::verifyBFIUpdates(Function &F) {
DominatorTree NewDT(F);
@@ -5242,7 +5271,9 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
WeakTrackingVH IterHandle(CurValue);
BasicBlock *BB = CurInstIterator->getParent();
- RecursivelyDeleteTriviallyDeadInstructions(Repl, TLInfo);
+ RecursivelyDeleteTriviallyDeadInstructions(
+ Repl, TLInfo, nullptr,
+ [&](Value *V) { removeAllAssertingVHReferences(V); });
if (IterHandle != CurValue) {
// If the iterator instruction was recursively deleted, start over at the
@@ -5363,7 +5394,9 @@ bool CodeGenPrepare::optimizeGatherScatterInst(Instruction *MemoryInst,
// If we have no uses, recursively delete the value and all dead instructions
// using it.
if (Ptr->use_empty())
- RecursivelyDeleteTriviallyDeadInstructions(Ptr, TLInfo);
+ RecursivelyDeleteTriviallyDeadInstructions(
+ Ptr, TLInfo, nullptr,
+ [&](Value *V) { removeAllAssertingVHReferences(V); });
return true;
}
@@ -6647,7 +6680,8 @@ bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) {
Value *BC2 = Builder.CreateBitCast(Shuffle, SVIVecType);
SVI->replaceAllUsesWith(BC2);
- RecursivelyDeleteTriviallyDeadInstructions(SVI);
+ RecursivelyDeleteTriviallyDeadInstructions(
+ SVI, TLInfo, nullptr, [&](Value *V) { removeAllAssertingVHReferences(V); });
// Also hoist the bitcast up to its operand if it they are not in the same
// block.
@@ -7604,11 +7638,10 @@ bool CodeGenPrepare::optimizeInst(Instruction *I, bool &ModifiedDT) {
/// Given an OR instruction, check to see if this is a bitreverse
/// idiom. If so, insert the new intrinsic and return true.
-static bool makeBitReverse(Instruction &I, const DataLayout &DL,
- const TargetLowering &TLI) {
+bool CodeGenPrepare::makeBitReverse(Instruction &I) {
if (!I.getType()->isIntegerTy() ||
- !TLI.isOperationLegalOrCustom(ISD::BITREVERSE,
- TLI.getValueType(DL, I.getType(), true)))
+ !TLI->isOperationLegalOrCustom(ISD::BITREVERSE,
+ TLI->getValueType(*DL, I.getType(), true)))
return false;
SmallVector<Instruction*, 4> Insts;
@@ -7616,7 +7649,8 @@ static bool makeBitReverse(Instruction &I, const DataLayout &DL,
return false;
Instruction *LastInst = Insts.back();
I.replaceAllUsesWith(LastInst);
- RecursivelyDeleteTriviallyDeadInstructions(&I);
+ RecursivelyDeleteTriviallyDeadInstructions(
+ &I, TLInfo, nullptr, [&](Value *V) { removeAllAssertingVHReferences(V); });
return true;
}
@@ -7638,7 +7672,7 @@ bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, bool &ModifiedDT) {
while (MadeBitReverse) {
MadeBitReverse = false;
for (auto &I : reverse(BB)) {
- if (makeBitReverse(I, *DL, *TLI)) {
+ if (makeBitReverse(I)) {
MadeBitReverse = MadeChange = true;
break;
}