[llvm] [BasicAA] Reuse object size when both pointers share an object (NFC) (PR #230844)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Oct 10 12:47:30 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
Author: Florian Hahn (fhahn)
<details>
<summary>Changes</summary>
Computing the object size can be quite expensive, and often we analyze pointers to the same object.
Split off logic to compute the object size to getIdentifiedObjectSize and avoid unnecessary queries if both objects are the same.
This improves compile-time w/o LTO:
stage1-O3: -0.27%
stage1-ReleaseThinLTO: -0.42%
stage1-ReleaseLTO-g: -0.33%
stage1-aarch64-O3: -0.38%
stage2-O3: -0.03%
stage2-clang: -0.17%
https://llvm-compile-time-tracker.com/compare.php?from=6f6d126fb1544ea3527c1ae59f4a0a7b3b52da41&to=4de2a5088f3c7bfd8de6b67239513c0c00c6f22d&stat=instructions:u
Aided by Opus 5.5
---
Full diff: https://github.com/llvm/llvm-project/pull/230844.diff
1 Files Affected:
- (modified) llvm/lib/Analysis/BasicAliasAnalysis.cpp (+29-19)
``````````diff
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index 7a79b0d6e24f1..1e48709f7e18f 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -139,18 +139,17 @@ static TypeSize getMinimalExtentFrom(const Value &V,
return TypeSize::getFixed(DerefBytes);
}
-/// Returns true if we can prove that the object specified by V is smaller than
-/// 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) {
+/// Returns the size of the object specified by \p V, rounded up to its
+/// alignment. Returns std::nullopt if the size is unknown or \p V is not an
+/// identified object.
+static std::optional<TypeSize>
+getIdentifiedObjectSize(const Value *V, const DataLayout &DL,
+ const TargetLibraryInfo &TLI, bool NullIsValidLoc) {
// Note that the meanings of the "object" are slightly different in the
// following contexts:
// c1: llvm::getObjectSize()
// c2: llvm.objectsize() intrinsic
- // c3: isObjectSmallerThan()
+ // c3: getIdentifiedObjectSize()
// c1 and c2 share the same meaning; however, the meaning of "object" in c3
// refers to the "entire object".
//
@@ -163,21 +162,23 @@ static bool isObjectSmallerThan(const Value *V, const Value &OtherV,
//
// In the context of c3, the "object" refers to the chunk of memory being
// allocated. So, the "object" has 100 bytes, and q points to the middle the
- // "object". However, unless p, the root object, is passed as the first
- // parameter, the call to isIdentifiedObject() makes isObjectSmallerThan()
- // bail out early.
+ // "object". However, unless p, the root object, is passed as \p V, the
+ // isIdentifiedObject() check makes this function bail out early.
if (!isIdentifiedObject(V))
- return false;
+ return std::nullopt;
// This function needs to use the aligned object size because we allow
// 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 getObjectSize(V, DL, TLI, NullIsValidLoc, /*RoundToAlign*/ true);
+}
+/// Returns true if we can prove that an object of size \p ObjectSize is smaller
+/// than the minimal extent accessed from \p OtherV with size \p OtherSize.
+static bool isObjectSmallerThan(TypeSize ObjectSize, const Value &OtherV,
+ LocationSize OtherSize, const DataLayout &DL,
+ bool NullIsValidLoc) {
TypeSize Size = getMinimalExtentFrom(OtherV, OtherSize, DL, NullIsValidLoc);
- return TypeSize::isKnownLT(*ObjectSize, Size);
+ return TypeSize::isKnownLT(ObjectSize, Size);
}
/// Returns true if we can prove that the object specified by V has size Size.
@@ -1629,8 +1630,17 @@ 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, *V1, V1Size, DL, TLI, NullIsValidLocation) ||
- isObjectSmallerThan(O1, *V2, V2Size, DL, TLI, NullIsValidLocation))
+ std::optional<TypeSize> O2Size =
+ getIdentifiedObjectSize(O2, DL, TLI, NullIsValidLocation);
+ if (O2Size &&
+ isObjectSmallerThan(*O2Size, *V1, V1Size, DL, NullIsValidLocation))
+ return AliasResult::NoAlias;
+
+ std::optional<TypeSize> O1Size =
+ O1 == O2 ? O2Size
+ : getIdentifiedObjectSize(O1, DL, TLI, NullIsValidLocation);
+ if (O1Size &&
+ isObjectSmallerThan(*O1Size, *V2, V2Size, DL, NullIsValidLocation))
return AliasResult::NoAlias;
if (EnableSeparateStorageAnalysis) {
``````````
</details>
https://github.com/llvm/llvm-project/pull/230844
More information about the llvm-commits
mailing list