diff options
author | Slava Zakharin <szakharin@nvidia.com> | 2025-02-19 17:09:29 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-19 17:09:29 -0800 |
commit | 75bd46e01ff5c4f34e7b7fd8382f7f1028d81440 (patch) | |
tree | cf1382d1838241d71ae57d7a47a1cafa1c01bbec /llvm/lib/Analysis/GlobalsModRef.cpp | |
parent | 19bad2ac4a4b809b5442023ac85fb0b7cf26dd7c (diff) | |
download | llvm-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.cpp | 23 |
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; |