aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/BasicAliasAnalysis.cpp
diff options
context:
space:
mode:
authorDavid Goldblatt <davidgoldblatt@fb.com>2022-12-16 10:52:32 -0800
committerWenlei He <aktoon@gmail.com>2022-12-16 11:05:00 -0800
commit61042d2806af6b7202f1008d67b00c8dcfca62d6 (patch)
tree79bdcb698f14016809bce312ad62e5be7987edc6 /llvm/lib/Analysis/BasicAliasAnalysis.cpp
parentbc5e385e2fafc136629d879f5650557f30ab1f52 (diff)
downloadllvm-61042d2806af6b7202f1008d67b00c8dcfca62d6.zip
llvm-61042d2806af6b7202f1008d67b00c8dcfca62d6.tar.gz
llvm-61042d2806af6b7202f1008d67b00c8dcfca62d6.tar.bz2
[AA][Intrinsics] Add separate_storage assumptions.
This operand bundle on an assume informs alias analysis that the arguments point to regions of memory that were allocated separately (i.e. different heap allocations, different allocas, or different globals). As a safety measure, we leave the analysis flag-disabled by default. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D136514
Diffstat (limited to 'llvm/lib/Analysis/BasicAliasAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/BasicAliasAnalysis.cpp35
1 files changed, 32 insertions, 3 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index 03774b7..1ea1d41 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -68,6 +68,9 @@ using namespace llvm;
static cl::opt<bool> EnableRecPhiAnalysis("basic-aa-recphi", cl::Hidden,
cl::init(true));
+static cl::opt<bool> EnableSeparateStorageAnalysis("basic-aa-separate-storage",
+ cl::Hidden, cl::init(false));
+
/// SearchLimitReached / SearchTimes shows how often the limit of
/// to decompose GEPs is reached. It will affect the precision
/// of basic alias analysis.
@@ -824,10 +827,10 @@ static bool notDifferentParent(const Value *O1, const Value *O2) {
AliasResult BasicAAResult::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB, AAQueryInfo &AAQI,
- const Instruction *) {
+ const Instruction *CtxI) {
assert(notDifferentParent(LocA.Ptr, LocB.Ptr) &&
"BasicAliasAnalysis doesn't support interprocedural queries.");
- return aliasCheck(LocA.Ptr, LocA.Size, LocB.Ptr, LocB.Size, AAQI);
+ return aliasCheck(LocA.Ptr, LocA.Size, LocB.Ptr, LocB.Size, AAQI, CtxI);
}
/// Checks to see if the specified callsite can clobber the specified memory
@@ -1415,7 +1418,8 @@ AliasResult BasicAAResult::aliasPHI(const PHINode *PN, LocationSize PNSize,
/// array references.
AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
const Value *V2, LocationSize V2Size,
- AAQueryInfo &AAQI) {
+ AAQueryInfo &AAQI,
+ const Instruction *CtxI) {
// If either of the memory references is empty, it doesn't matter what the
// pointer values are.
if (V1Size.isZero() || V2Size.isZero())
@@ -1499,6 +1503,31 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
TLI, NullIsValidLocation)))
return AliasResult::NoAlias;
+ if (CtxI && EnableSeparateStorageAnalysis) {
+ for (auto &AssumeVH : AC.assumptions()) {
+ if (!AssumeVH)
+ continue;
+
+ AssumeInst *Assume = cast<AssumeInst>(AssumeVH);
+
+ for (unsigned Idx = 0; Idx < Assume->getNumOperandBundles(); Idx++) {
+ OperandBundleUse OBU = Assume->getOperandBundleAt(Idx);
+ if (OBU.getTagName() == "separate_storage") {
+ assert(OBU.Inputs.size() == 2);
+ const Value *Hint1 = OBU.Inputs[0].get();
+ const Value *Hint2 = OBU.Inputs[1].get();
+ const Value *HintO1 = getUnderlyingObject(Hint1);
+ const Value *HintO2 = getUnderlyingObject(Hint2);
+
+ if (((O1 == HintO1 && O2 == HintO2) ||
+ (O1 == HintO2 && O2 == HintO1)) &&
+ isValidAssumeForContext(Assume, CtxI, DT))
+ return AliasResult::NoAlias;
+ }
+ }
+ }
+ }
+
// If one the accesses may be before the accessed pointer, canonicalize this
// by using unknown after-pointer sizes for both accesses. This is
// equivalent, because regardless of which pointer is lower, one of them