aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp13
-rw-r--r--llvm/lib/Transforms/InstCombine/InstructionCombining.cpp1
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyCFG.cpp50
3 files changed, 32 insertions, 32 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index e877fb1..f5e320e 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -26,6 +26,7 @@
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumeBundleQueries.h"
#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/GuardUtils.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/Loads.h"
@@ -5273,6 +5274,18 @@ bool llvm::isGuaranteedToTransferExecutionToSuccessor(const Instruction *I) {
if (isa<UnreachableInst>(I))
return false;
+ if (isa<CatchPadInst>(I)) {
+ switch (classifyEHPersonality(I->getFunction()->getPersonalityFn())) {
+ default:
+ // A catchpad may invoke exception object constructors and such, which
+ // in some languages can be arbitrary code, so be conservative by default.
+ return false;
+ case EHPersonality::CoreCLR:
+ // For CoreCLR, it just involves a type test.
+ return true;
+ }
+ }
+
// An instruction that returns without throwing must transfer control flow
// to a successor.
return !I->mayThrow() && I->willReturn();
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 3931803..e00bcf8 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2870,6 +2870,7 @@ Instruction *InstCombinerImpl::visitReturnInst(ReturnInst &RI) {
return nullptr;
}
+// WARNING: keep in sync with SimplifyCFGOpt::simplifyUnreachable()!
Instruction *InstCombinerImpl::visitUnreachableInst(UnreachableInst &I) {
// Try to remove the previous instruction if it must lead to unreachable.
// This includes instructions like stores and "llvm.assume" that may not get
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index b8f6bf9..f08ab18 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -4655,6 +4655,7 @@ bool SimplifyCFGOpt::simplifyReturn(ReturnInst *RI, IRBuilder<> &Builder) {
return false;
}
+// WARNING: keep in sync with InstCombinerImpl::visitUnreachableInst()!
bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) {
BasicBlock *BB = UI->getParent();
@@ -4665,39 +4666,24 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) {
while (UI->getIterator() != BB->begin()) {
BasicBlock::iterator BBI = UI->getIterator();
--BBI;
- // Do not delete instructions that can have side effects which might cause
- // the unreachable to not be reachable; specifically, calls and volatile
- // operations may have this effect.
- if (isa<CallInst>(BBI) && !isa<DbgInfoIntrinsic>(BBI))
- break;
- if (BBI->mayHaveSideEffects()) {
- if (auto *SI = dyn_cast<StoreInst>(BBI)) {
- // Temporarily disable removal of volatile stores preceding unreachable,
- // pending a potential LangRef change permitting volatile stores to
- // trap.
- // TODO: Either remove this code, or properly integrate the check into
- // isGuaranteedToTransferExecutionToSuccessor().
- if (SI->isVolatile())
- break;
- } else if (isa<CatchPadInst>(BBI)) {
- // A catchpad may invoke exception object constructors and such, which
- // in some languages can be arbitrary code, so be conservative by
- // default.
- // For CoreCLR, it just involves a type test, so can be removed.
- if (classifyEHPersonality(BB->getParent()->getPersonalityFn()) !=
- EHPersonality::CoreCLR)
- break;
- } else if (!isa<LoadInst>(BBI) && !isa<AtomicRMWInst>(BBI) &&
- !isa<AtomicCmpXchgInst>(BBI) && !isa<FenceInst>(BBI) &&
- !isa<VAArgInst>(BBI) && !isa<LandingPadInst>(BBI)) {
- break;
- }
- // Note that deleting LandingPad's here is in fact okay, although it
- // involves a bit of subtle reasoning. If this inst is a LandingPad,
- // all the predecessors of this block will be the unwind edges of Invokes,
- // and we can therefore guarantee this block will be erased.
- }
+ if (!isGuaranteedToTransferExecutionToSuccessor(&*BBI))
+ break; // Can not drop any more instructions. We're done here.
+ // Otherwise, this instruction can be freely erased,
+ // even if it is not side-effect free.
+
+ // Temporarily disable removal of volatile stores preceding unreachable,
+ // pending a potential LangRef change permitting volatile stores to trap.
+ // TODO: Either remove this code, or properly integrate the check into
+ // isGuaranteedToTransferExecutionToSuccessor().
+ if (auto *SI = dyn_cast<StoreInst>(&*BBI))
+ if (SI->isVolatile())
+ break; // Can not drop this instruction. We're done here.
+
+ // Note that deleting EH's here is in fact okay, although it involves a bit
+ // of subtle reasoning. If this inst is an EH, all the predecessors of this
+ // block will be the unwind edges of Invoke/CatchSwitch/CleanupReturn,
+ // and we can therefore guarantee this block will be erased.
// Delete this instruction (any uses are guaranteed to be dead)
BBI->replaceAllUsesWith(PoisonValue::get(BBI->getType()));