[llvm] 47abd87 - [CaptureTracking] Don't require offset to stay the same (#201106)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 2 07:26:14 PDT 2026
Author: Nikita Popov
Date: 2026-06-02T16:26:09+02:00
New Revision: 47abd870986690ed50eab4de59c9dffa56ac24b7
URL: https://github.com/llvm/llvm-project/commit/47abd870986690ed50eab4de59c9dffa56ac24b7
DIFF: https://github.com/llvm/llvm-project/commit/47abd870986690ed50eab4de59c9dffa56ac24b7.diff
LOG: [CaptureTracking] Don't require offset to stay the same (#201106)
For isIntrinsicReturningPointerAliasingArgumentWithoutCapturing() we
don't need the offset to stay the same. Even if the intrinsic applies an
offset to the pointer (like ptrmask), we can still continue by analyzing
the return value of the intrinsic, rather than considering the intrinsic
itself capturing.
Also clarify that this needs to stay in sync with isEscapeSource()
specifically, not getUnderlyingObject() or DecomposeGEP (which isn't
even possible, as they use different values for the argument). This used
to be different historically.
This was set to true in fd72bf21c958ae2fdfaa8654df55367c72575d3a, which
set all users to true, so I don't believe there was a specific reason
for this choice.
I ran into this when trying to replace some home-grown code in
FunctionAttrs with CaptureTracking.
Added:
Modified:
llvm/lib/Analysis/AliasAnalysis.cpp
llvm/lib/Analysis/CaptureTracking.cpp
llvm/test/Transforms/FunctionAttrs/writeonly.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/AliasAnalysis.cpp b/llvm/lib/Analysis/AliasAnalysis.cpp
index f3aa16ff2f790..a1e4a18718b52 100644
--- a/llvm/lib/Analysis/AliasAnalysis.cpp
+++ b/llvm/lib/Analysis/AliasAnalysis.cpp
@@ -935,7 +935,7 @@ bool llvm::isBaseOfObject(const Value *V) {
bool llvm::isEscapeSource(const Value *V) {
if (auto *CB = dyn_cast<CallBase>(V)) {
if (isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(
- CB, /*MustPreserveOffset=*/true))
+ CB, /*MustPreserveOffset=*/false))
return false;
// The return value of a function with a captures(ret: address, provenance)
diff --git a/llvm/lib/Analysis/CaptureTracking.cpp b/llvm/lib/Analysis/CaptureTracking.cpp
index 2bea8e2129b4f..b5ee2430796cf 100644
--- a/llvm/lib/Analysis/CaptureTracking.cpp
+++ b/llvm/lib/Analysis/CaptureTracking.cpp
@@ -278,11 +278,10 @@ UseCaptureInfo llvm::DetermineUseCaptureKind(const Use &U, const Value *Base) {
auto *Call = cast<CallBase>(I);
// The pointer is not captured if returned pointer is not captured.
// NOTE: CaptureTracking users should not assume that only functions
- // marked with nocapture do not capture. This means that places like
- // getUnderlyingObject in ValueTracking or DecomposeGEPExpression
- // in BasicAA also need to know about this property.
+ // marked with nocapture do not capture. This logic needs to stay in
+ // sync with isEscapeSource().
if (isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(
- Call, /*MustPreserveOffset=*/true))
+ Call, /*MustPreserveOffset=*/false))
return UseCaptureInfo::passthrough();
// Volatile operations effectively capture the memory location that they
diff --git a/llvm/test/Transforms/FunctionAttrs/writeonly.ll b/llvm/test/Transforms/FunctionAttrs/writeonly.ll
index 5342ad6f7000d..9a97dec6df2a9 100644
--- a/llvm/test/Transforms/FunctionAttrs/writeonly.ll
+++ b/llvm/test/Transforms/FunctionAttrs/writeonly.ll
@@ -181,14 +181,14 @@ define void @test_atomicrmw(ptr %p) {
define void @test_ptrmask(ptr %p) {
; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
; FNATTRS-LABEL: define {{[^@]+}}@test_ptrmask
-; FNATTRS-SAME: (ptr writeonly [[P:%.*]]) #[[ATTR3]] {
+; FNATTRS-SAME: (ptr writeonly captures(none) [[P:%.*]]) #[[ATTR3]] {
; FNATTRS-NEXT: [[MASK:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -5)
; FNATTRS-NEXT: store i8 0, ptr [[MASK]], align 1
; FNATTRS-NEXT: ret void
;
; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
; ATTRIBUTOR-LABEL: define {{[^@]+}}@test_ptrmask
-; ATTRIBUTOR-SAME: (ptr nofree writeonly [[P:%.*]]) #[[ATTR3]] {
+; ATTRIBUTOR-SAME: (ptr nofree writeonly captures(none) [[P:%.*]]) #[[ATTR3]] {
; ATTRIBUTOR-NEXT: [[MASK:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -5) #[[ATTR10:[0-9]+]]
; ATTRIBUTOR-NEXT: store i8 0, ptr [[MASK]], align 1
; ATTRIBUTOR-NEXT: ret void
More information about the llvm-commits
mailing list