[llvm] ccd2a3f - [BasicAA] Compute minimal access extents lazily (#226931)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 28 04:17:38 PDT 2026
Author: Dávid Bolvanský
Date: 2026-09-28T11:17:31Z
New Revision: ccd2a3f748d7a4898fe2850491796f01603e8d72
URL: https://github.com/llvm/llvm-project/commit/ccd2a3f748d7a4898fe2850491796f01603e8d72
DIFF: https://github.com/llvm/llvm-project/commit/ccd2a3f748d7a4898fe2850491796f01603e8d72.diff
LOG: [BasicAA] Compute minimal access extents lazily (#226931)
`aliasCheck` computes the minimal extent of an access before calling
`isObjectSmallerThan`, even though the latter immediately returns false
when the other pointer is not an identified object.
Move the extent computation behind the existing `isIdentifiedObject`
check. This preserves the result: whenever the extent can affect the
answer, the same value is computed and used as before; otherwise only
unused work is skipped.
Added:
Modified:
llvm/lib/Analysis/BasicAliasAnalysis.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index fd9a7bb935170..3aece3ca7d769 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -117,11 +117,33 @@ static std::optional<TypeSize> getObjectSize(const Value *V,
return std::nullopt;
}
+/// Return the minimal extent from \p V to the end of the underlying object,
+/// assuming the result is used in an aliasing query. E.g., we do use the query
+/// location size and the fact that null pointers cannot alias here.
+static TypeSize getMinimalExtentFrom(const Value &V,
+ const LocationSize &LocSize,
+ const DataLayout &DL,
+ bool NullIsValidLoc) {
+ // If we have dereferenceability information we know a lower bound for the
+ // extent as accesses for a lower offset would be valid. We need to exclude
+ // the "or null" part if null is a valid pointer. We can ignore frees, as an
+ // access after free would be undefined behavior.
+ bool CanBeNull;
+ uint64_t DerefBytes =
+ V.getPointerDereferenceableBytes(DL, CanBeNull, /*CanBeFreed=*/nullptr);
+ DerefBytes = (CanBeNull && NullIsValidLoc) ? 0 : DerefBytes;
+ // If queried with a precise location size, we assume that location size to be
+ // accessed, thus valid.
+ if (LocSize.isPrecise())
+ DerefBytes = std::max(DerefBytes, LocSize.getValue().getKnownMinValue());
+ return TypeSize::getFixed(DerefBytes);
+}
+
/// Returns true if we can prove that the object specified by V is smaller than
-/// Size. Bails out early unless the root object is passed as the first
-/// parameter.
-static bool isObjectSmallerThan(const Value *V, TypeSize Size,
- const DataLayout &DL,
+/// the minimal extent accessed from OtherV with size OtherSize. Bails out early
+/// unless the root object is passed as the first parameter.
+static bool isObjectSmallerThan(const Value *V, const Value &OtherV,
+ LocationSize OtherSize, const DataLayout &DL,
const TargetLibraryInfo &TLI,
bool NullIsValidLoc) {
// Note that the meanings of the "object" are slightly
diff erent in the
@@ -151,30 +173,11 @@ static bool isObjectSmallerThan(const Value *V, TypeSize Size,
// reads a bit past the end given sufficient alignment.
std::optional<TypeSize> ObjectSize = getObjectSize(V, DL, TLI, NullIsValidLoc,
/*RoundToAlign*/ true);
+ if (!ObjectSize)
+ return false;
- return ObjectSize && TypeSize::isKnownLT(*ObjectSize, Size);
-}
-
-/// Return the minimal extent from \p V to the end of the underlying object,
-/// assuming the result is used in an aliasing query. E.g., we do use the query
-/// location size and the fact that null pointers cannot alias here.
-static TypeSize getMinimalExtentFrom(const Value &V,
- const LocationSize &LocSize,
- const DataLayout &DL,
- bool NullIsValidLoc) {
- // If we have dereferenceability information we know a lower bound for the
- // extent as accesses for a lower offset would be valid. We need to exclude
- // the "or null" part if null is a valid pointer. We can ignore frees, as an
- // access after free would be undefined behavior.
- bool CanBeNull;
- uint64_t DerefBytes =
- V.getPointerDereferenceableBytes(DL, CanBeNull, /*CanBeFreed=*/nullptr);
- DerefBytes = (CanBeNull && NullIsValidLoc) ? 0 : DerefBytes;
- // If queried with a precise location size, we assume that location size to be
- // accessed, thus valid.
- if (LocSize.isPrecise())
- DerefBytes = std::max(DerefBytes, LocSize.getValue().getKnownMinValue());
- return TypeSize::getFixed(DerefBytes);
+ TypeSize Size = getMinimalExtentFrom(OtherV, OtherSize, DL, NullIsValidLoc);
+ return TypeSize::isKnownLT(*ObjectSize, Size);
}
/// Returns true if we can prove that the object specified by V has size Size.
@@ -1615,12 +1618,8 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
// If the size of one access is larger than the entire object on the other
// side, then we know such behavior is undefined and can assume no alias.
bool NullIsValidLocation = NullPointerIsDefined(&F);
- if ((isObjectSmallerThan(
- O2, getMinimalExtentFrom(*V1, V1Size, DL, NullIsValidLocation), DL,
- TLI, NullIsValidLocation)) ||
- (isObjectSmallerThan(
- O1, getMinimalExtentFrom(*V2, V2Size, DL, NullIsValidLocation), DL,
- TLI, NullIsValidLocation)))
+ if (isObjectSmallerThan(O2, *V1, V1Size, DL, TLI, NullIsValidLocation) ||
+ isObjectSmallerThan(O1, *V2, V2Size, DL, TLI, NullIsValidLocation))
return AliasResult::NoAlias;
if (EnableSeparateStorageAnalysis) {
More information about the llvm-commits
mailing list