aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2021-02-18 22:15:17 +0100
committerNikita Popov <nikita.ppv@gmail.com>2021-02-19 11:56:01 +0100
commit370addb996138a9e3634899cf264c7621307617a (patch)
treee34a9e83d25ebc40c2186e66652d67d1787201e8 /llvm/lib/Analysis/ValueTracking.cpp
parent1d9f4903c6151f1b3f90a743eac339dde8ef5d29 (diff)
downloadllvm-370addb996138a9e3634899cf264c7621307617a.zip
llvm-370addb996138a9e3634899cf264c7621307617a.tar.gz
llvm-370addb996138a9e3634899cf264c7621307617a.tar.bz2
[IR] Move willReturn() to Instruction
This moves the willReturn() helper from CallBase to Instruction, so that it can be used in a more generic manner. This will make it easier to fix additional passes (ADCE and BDCE), and will give us one place to change if additional instructions should become non-willreturn (e.g. there has been talk about handling volatile operations this way). I have also included the IntrinsicInst workaround directly in here, so that it gets applied consistently. (As such this change is not entirely NFC -- FuncAttrs will now use this as well.) Differential Revision: https://reviews.llvm.org/D96992
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp28
1 files changed, 3 insertions, 25 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 493eb08..edf165c 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5056,36 +5056,14 @@ bool llvm::isGuaranteedToTransferExecutionToSuccessor(const Instruction *I) {
// arbitrary length of time, but programs aren't allowed to rely on that.
// If there is no successor, then execution can't transfer to it.
- if (const auto *CRI = dyn_cast<CleanupReturnInst>(I))
- return !CRI->unwindsToCaller();
- if (const auto *CatchSwitch = dyn_cast<CatchSwitchInst>(I))
- return !CatchSwitch->unwindsToCaller();
- if (isa<ResumeInst>(I))
- return false;
if (isa<ReturnInst>(I))
return false;
if (isa<UnreachableInst>(I))
return false;
- // Calls can throw, or contain an infinite loop, or kill the process.
- if (const auto *CB = dyn_cast<CallBase>(I)) {
- // Call sites that throw have implicit non-local control flow.
- if (!CB->doesNotThrow())
- return false;
-
- // A function which doens't throw and has "willreturn" attribute will
- // always return.
- if (CB->hasFnAttr(Attribute::WillReturn))
- return true;
-
- // FIXME: Temporarily assume that all side-effect free intrinsics will
- // return. Remove this workaround once all intrinsics are appropriately
- // annotated.
- return isa<IntrinsicInst>(CB) && CB->onlyReadsMemory();
- }
-
- // Other instructions return normally.
- return true;
+ // An instruction that returns without throwing must transfer control flow
+ // to a successor.
+ return !I->mayThrow() && I->willReturn();
}
bool llvm::isGuaranteedToTransferExecutionToSuccessor(const BasicBlock *BB) {