diff options
author | Nikita Popov <npopov@redhat.com> | 2022-09-01 16:51:00 +0200 |
---|---|---|
committer | Nikita Popov <npopov@redhat.com> | 2022-09-22 11:15:20 +0200 |
commit | ab25ea6d357e0446bc53cbc6a7372fc79f24740d (patch) | |
tree | ba89fb5749099348377421cb8ff1cda5861e33f8 /llvm/lib/Analysis/BasicAliasAnalysis.cpp | |
parent | cc61c822e05c51e494c50d1e72f963750116ef08 (diff) | |
download | llvm-ab25ea6d357e0446bc53cbc6a7372fc79f24740d.zip llvm-ab25ea6d357e0446bc53cbc6a7372fc79f24740d.tar.gz llvm-ab25ea6d357e0446bc53cbc6a7372fc79f24740d.tar.bz2 |
[AA] Model operand bundles more precisely
Based on D130896, we can model operand bundles more precisely. In
addition to the baseline ModRefBehavior, a reading/clobbering operand
bundle may also read/write all locations. For example, a memcpy with
deopt bundle can read any memory, but only write argument memory.
This means that getModRefInfo() for memcpy with a pointer that does
not alias the arguments results in Ref, rather than ModRef, without
the need to implement any special handling.
Differential Revision: https://reviews.llvm.org/D130980
Diffstat (limited to 'llvm/lib/Analysis/BasicAliasAnalysis.cpp')
-rw-r--r-- | llvm/lib/Analysis/BasicAliasAnalysis.cpp | 36 |
1 files changed, 10 insertions, 26 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp index 965a1fa..c0e373f 100644 --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -769,12 +769,16 @@ FunctionModRefBehavior BasicAAResult::getModRefBehavior(const CallBase *Call) { else if (Call->onlyAccessesInaccessibleMemOrArgMem()) Min = FunctionModRefBehavior::inaccessibleOrArgMemOnly(MR); - // If the call has operand bundles then aliasing attributes from the function - // it calls do not directly apply to the call. This can be made more precise - // in the future. - if (!Call->hasOperandBundles()) - if (const Function *F = Call->getCalledFunction()) - Min &= getBestAAResults().getModRefBehavior(F); + if (const Function *F = Call->getCalledFunction()) { + FunctionModRefBehavior FMRB = getBestAAResults().getModRefBehavior(F); + // Operand bundles on the call may also read or write memory, in addition + // to the behavior of the called function. + if (Call->hasReadingOperandBundles()) + FMRB |= FunctionModRefBehavior::readOnly(); + if (Call->hasClobberingOperandBundles()) + FMRB |= FunctionModRefBehavior::writeOnly(); + Min &= FMRB; + } return Min; } @@ -976,26 +980,6 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call, return ModRefInfo::NoModRef; } - // Ideally, there should be no need to special case for memcpy/memove - // intrinsics here since general machinery (based on memory attributes) should - // already handle it just fine. Unfortunately, it doesn't due to deficiency in - // operand bundles support. At the moment it's not clear if complexity behind - // enhancing general mechanism worths it. - // TODO: Consider improving operand bundles support in general mechanism. - if (auto *Inst = dyn_cast<AnyMemTransferInst>(Call)) { - AliasResult SrcAA = - getBestAAResults().alias(MemoryLocation::getForSource(Inst), Loc, AAQI); - AliasResult DestAA = - getBestAAResults().alias(MemoryLocation::getForDest(Inst), Loc, AAQI); - // It's also possible for Loc to alias both src and dest, or neither. - ModRefInfo rv = ModRefInfo::NoModRef; - if (SrcAA != AliasResult::NoAlias || Call->hasReadingOperandBundles()) - rv |= ModRefInfo::Ref; - if (DestAA != AliasResult::NoAlias || Call->hasClobberingOperandBundles()) - rv |= ModRefInfo::Mod; - return rv; - } - // Guard intrinsics are marked as arbitrarily writing so that proper control // dependencies are maintained but they never mods any particular memory // location. |