aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/GlobalsModRef.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/GlobalsModRef.cpp')
-rw-r--r--llvm/lib/Analysis/GlobalsModRef.cpp16
1 files changed, 14 insertions, 2 deletions
diff --git a/llvm/lib/Analysis/GlobalsModRef.cpp b/llvm/lib/Analysis/GlobalsModRef.cpp
index 80989c2..c179fd3 100644
--- a/llvm/lib/Analysis/GlobalsModRef.cpp
+++ b/llvm/lib/Analysis/GlobalsModRef.cpp
@@ -511,6 +511,18 @@ void GlobalsAAResult::AnalyzeCallGraph(CallGraph &CG, Module &M) {
Handles.front().I = Handles.begin();
bool KnowNothing = false;
+ // Intrinsics, like any other synchronizing function, can make effects
+ // of other threads visible. Without nosync we know nothing really.
+ // Similarly, if `nocallback` is missing the function, or intrinsic,
+ // can call into the module arbitrarily. If both are set the function
+ // has an effect but will not interact with accesses of internal
+ // globals inside the module. We are conservative here for optnone
+ // functions, might not be necessary.
+ auto MaySyncOrCallIntoModule = [](const Function &F) {
+ return !F.isDeclaration() || !F.hasNoSync() ||
+ !F.hasFnAttribute(Attribute::NoCallback);
+ };
+
// Collect the mod/ref properties due to called functions. We only compute
// one mod-ref set.
for (unsigned i = 0, e = SCC.size(); i != e && !KnowNothing; ++i) {
@@ -525,7 +537,7 @@ void GlobalsAAResult::AnalyzeCallGraph(CallGraph &CG, Module &M) {
// Can't do better than that!
} else if (F->onlyReadsMemory()) {
FI.addModRefInfo(ModRefInfo::Ref);
- if (!F->isIntrinsic() && !F->onlyAccessesArgMemory())
+ if (!F->onlyAccessesArgMemory() && MaySyncOrCallIntoModule(*F))
// This function might call back into the module and read a global -
// consider every global as possibly being read by this function.
FI.setMayReadAnyGlobal();
@@ -533,7 +545,7 @@ void GlobalsAAResult::AnalyzeCallGraph(CallGraph &CG, Module &M) {
FI.addModRefInfo(ModRefInfo::ModRef);
if (!F->onlyAccessesArgMemory())
FI.setMayReadAnyGlobal();
- if (!F->isIntrinsic()) {
+ if (MaySyncOrCallIntoModule(*F)) {
KnowNothing = true;
break;
}