aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/GlobalsModRef.cpp
diff options
context:
space:
mode:
authorSlava Zakharin <szakharin@nvidia.com>2025-02-19 17:09:29 -0800
committerGitHub <noreply@github.com>2025-02-19 17:09:29 -0800
commit75bd46e01ff5c4f34e7b7fd8382f7f1028d81440 (patch)
treecf1382d1838241d71ae57d7a47a1cafa1c01bbec /llvm/lib/Analysis/GlobalsModRef.cpp
parent19bad2ac4a4b809b5442023ac85fb0b7cf26dd7c (diff)
downloadllvm-75bd46e01ff5c4f34e7b7fd8382f7f1028d81440.zip
llvm-75bd46e01ff5c4f34e7b7fd8382f7f1028d81440.tar.gz
llvm-75bd46e01ff5c4f34e7b7fd8382f7f1028d81440.tar.bz2
[globals-aa] Improved isNonEscapingGlobalNoAlias. (#127707)
A non-escaping global should never alias with non-pointer values and `ptr null`. This should improve disambiguation of global pointers with relation to Flang runtime calls (given that `nosync nocallback` attributes are properly set). It also seems to be an obvious improvement with little overhead.
Diffstat (limited to 'llvm/lib/Analysis/GlobalsModRef.cpp')
-rw-r--r--llvm/lib/Analysis/GlobalsModRef.cpp23
1 files changed, 19 insertions, 4 deletions
diff --git a/llvm/lib/Analysis/GlobalsModRef.cpp b/llvm/lib/Analysis/GlobalsModRef.cpp
index 1ceb1b2..644969d 100644
--- a/llvm/lib/Analysis/GlobalsModRef.cpp
+++ b/llvm/lib/Analysis/GlobalsModRef.cpp
@@ -713,13 +713,20 @@ static bool isNonEscapingGlobalNoAliasWithLoad(const GlobalValue *GV,
// active, or to be forced to operate as a module pass that cannot co-exist
// with an alias analysis such as GMR.
bool GlobalsAAResult::isNonEscapingGlobalNoAlias(const GlobalValue *GV,
- const Value *V) {
+ const Value *V,
+ const Instruction *CtxI) {
// In order to know that the underlying object cannot alias the
// non-addr-taken global, we must know that it would have to be an escape.
// Thus if the underlying object is a function argument, a load from
// a global, or the return of a function, it cannot alias. We can also
// recurse through PHI nodes and select nodes provided all of their inputs
// resolve to one of these known-escaping roots.
+
+ // A non-addr-taken global cannot alias with any non-pointer value.
+ // Check this early and exit.
+ if (!V->getType()->isPointerTy())
+ return true;
+
SmallPtrSet<const Value *, 8> Visited;
SmallVector<const Value *, 8> Inputs;
Visited.insert(V);
@@ -762,6 +769,14 @@ bool GlobalsAAResult::isNonEscapingGlobalNoAlias(const GlobalValue *GV,
continue;
}
+ if (CtxI)
+ if (auto *CPN = dyn_cast<ConstantPointerNull>(Input)) {
+ // Null pointer cannot alias with a non-addr-taken global.
+ const Function *F = CtxI->getFunction();
+ if (!NullPointerIsDefined(F, CPN->getType()->getAddressSpace()))
+ continue;
+ }
+
// Recurse through a limited number of selects, loads and PHIs. This is an
// arbitrary depth of 4, lower numbers could be used to fix compile time
// issues if needed, but this is generally expected to be only be important
@@ -820,7 +835,7 @@ bool GlobalsAAResult::invalidate(Module &, const PreservedAnalyses &PA,
/// address of the global isn't taken.
AliasResult GlobalsAAResult::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB,
- AAQueryInfo &AAQI, const Instruction *) {
+ AAQueryInfo &AAQI, const Instruction *CtxI) {
// Get the base object these pointers point to.
const Value *UV1 =
getUnderlyingObject(LocA.Ptr->stripPointerCastsForAliasAnalysis());
@@ -856,7 +871,7 @@ AliasResult GlobalsAAResult::alias(const MemoryLocation &LocA,
if ((GV1 || GV2) && GV1 != GV2) {
const GlobalValue *GV = GV1 ? GV1 : GV2;
const Value *UV = GV1 ? UV2 : UV1;
- if (isNonEscapingGlobalNoAlias(GV, UV))
+ if (isNonEscapingGlobalNoAlias(GV, UV, CtxI))
return AliasResult::NoAlias;
}
@@ -920,7 +935,7 @@ ModRefInfo GlobalsAAResult::getModRefInfoForArgument(const CallBase *Call,
!all_of(Objects, [&](const Value *V) {
return this->alias(MemoryLocation::getBeforeOrAfter(V),
MemoryLocation::getBeforeOrAfter(GV), AAQI,
- nullptr) == AliasResult::NoAlias;
+ Call) == AliasResult::NoAlias;
}))
return ConservativeResult;