diff options
author | Sanjay Patel <spatel@rotateright.com> | 2019-11-10 09:16:32 -0500 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2019-11-10 09:18:11 -0500 |
commit | ef02831f0a4e3b3ccaa45a5589e4cabecbf527ab (patch) | |
tree | 31fa4f248e89b8780bd205344fb3e83dd4560954 /llvm/lib | |
parent | 4ff246fef25e1353c6f5ebbde625ae30953def7a (diff) | |
download | bcm5719-llvm-ef02831f0a4e3b3ccaa45a5589e4cabecbf527ab.tar.gz bcm5719-llvm-ef02831f0a4e3b3ccaa45a5589e4cabecbf527ab.zip |
[InstCombine] avoid crash from deleting an instruction that still has uses (PR43723)
We gather a set of white-listed instructions in isAllocSiteRemovable() and then
replace/erase them. But we don't know in general if the instructions in the set
have uses amongst themselves, so order of deletion makes a difference.
There's already a special-case for the llvm.objectsize intrinsic, so add another
for llvm.invariant.end.
Should fix:
https://bugs.llvm.org/show_bug.cgi?id=43723
Differential Revision: https://reviews.llvm.org/D69977
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index b3db47bbbf9..33e3fa4ceb6 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2330,13 +2330,21 @@ static bool isAllocSiteRemovable(Instruction *AI, return false; LLVM_FALLTHROUGH; } - case Intrinsic::invariant_start: case Intrinsic::invariant_end: case Intrinsic::lifetime_start: case Intrinsic::lifetime_end: case Intrinsic::objectsize: Users.emplace_back(I); continue; + case Intrinsic::invariant_start: + // Only delete this if it has no uses or a single 'end' use. + if (I->use_empty()) + Users.emplace_back(I); + else if (I->hasOneUse() && + match(I->user_back(), + m_Intrinsic<Intrinsic::invariant_end>())) + Users.emplace_back(I); + continue; } } @@ -2384,14 +2392,13 @@ Instruction *InstCombiner::visitAllocSite(Instruction &MI) { if (isAllocSiteRemovable(&MI, Users, &TLI)) { for (unsigned i = 0, e = Users.size(); i != e; ++i) { - // Lowering all @llvm.objectsize calls first because they may - // use a bitcast/GEP of the alloca we are removing. if (!Users[i]) continue; Instruction *I = cast<Instruction>(&*Users[i]); - if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) { + // Lowering all @llvm.objectsize calls first because they may + // use a bitcast/GEP of the alloca we are removing. if (II->getIntrinsicID() == Intrinsic::objectsize) { Value *Result = lowerObjectSizeCall(II, DL, &TLI, /*MustSucceed=*/true); @@ -2399,6 +2406,12 @@ Instruction *InstCombiner::visitAllocSite(Instruction &MI) { eraseInstFromFunction(*I); Users[i] = nullptr; // Skip examining in the next loop. } + // Erase llvm.invariant.end because we expect that it uses an + // llvm.invariant.start that we will remove below. + if (II->getIntrinsicID() == Intrinsic::invariant_end) { + eraseInstFromFunction(*I); + Users[i] = nullptr; // Skip examining in the next loop. + } } } for (unsigned i = 0, e = Users.size(); i != e; ++i) { |