aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/BasicAliasAnalysis.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2022-09-14 17:10:39 +0200
committerNikita Popov <npopov@redhat.com>2022-09-22 16:48:51 +0200
commit60990d9042b9668001bcfa095b970558fc63e5a9 (patch)
treee1a8f595dd4e00be71c7d849ce7a5cad9731de9c /llvm/lib/Analysis/BasicAliasAnalysis.cpp
parent8df376db7282b955e7990cb8887ee9dcd3565040 (diff)
downloadllvm-60990d9042b9668001bcfa095b970558fc63e5a9.zip
llvm-60990d9042b9668001bcfa095b970558fc63e5a9.tar.gz
llvm-60990d9042b9668001bcfa095b970558fc63e5a9.tar.bz2
[BasicAA] Move experimental.guard modelling to getModRefBehavior()
While we can't express this with attributes yet, we can model these intrinsics as readonly + writing inaccessible memory (for the control dependence) in FMRB. This way we don't need to special-case them in getModRefInfo(), it falls out of the usual logic.
Diffstat (limited to 'llvm/lib/Analysis/BasicAliasAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/BasicAliasAnalysis.cpp22
1 files changed, 9 insertions, 13 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index c0e373f..0641342 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -790,6 +790,15 @@ FunctionModRefBehavior BasicAAResult::getModRefBehavior(const Function *F) {
if (F->doesNotAccessMemory())
return FunctionModRefBehavior::none();
+ switch (F->getIntrinsicID()) {
+ case Intrinsic::experimental_guard:
+ case Intrinsic::experimental_deoptimize:
+ // These intrinsics can read arbitrary memory, and additionally modref
+ // inaccessible memory to model control dependence.
+ return FunctionModRefBehavior::readOnly() |
+ FunctionModRefBehavior::inaccessibleMemOnly(ModRefInfo::ModRef);
+ }
+
// If the function declares it only reads memory, go with that.
ModRefInfo MR = ModRefInfo::ModRef;
if (F->onlyReadsMemory())
@@ -980,19 +989,6 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
return ModRefInfo::NoModRef;
}
- // Guard intrinsics are marked as arbitrarily writing so that proper control
- // dependencies are maintained but they never mods any particular memory
- // location.
- //
- // *Unlike* assumes, guard intrinsics are modeled as reading memory since the
- // heap state at the point the guard is issued needs to be consistent in case
- // the guard invokes the "deopt" continuation.
- if (isIntrinsicCall(Call, Intrinsic::experimental_guard))
- return ModRefInfo::Ref;
- // The same applies to deoptimize which is essentially a guard(false).
- if (isIntrinsicCall(Call, Intrinsic::experimental_deoptimize))
- return ModRefInfo::Ref;
-
// Like assumes, invariant.start intrinsics were also marked as arbitrarily
// writing so that proper control dependencies are maintained but they never
// mod any particular memory location visible to the IR.