[llvm] 3cf7262 - [CaptureTracking] Handle ptrtoaddr
via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 8 14:22:45 PDT 2025
Author: Alexander Richardson
Date: 2025-08-08T14:22:42-07:00
New Revision: 3cf7262876cf261b5704bcf1d70d2de13d595e15
URL: https://github.com/llvm/llvm-project/commit/3cf7262876cf261b5704bcf1d70d2de13d595e15
DIFF: https://github.com/llvm/llvm-project/commit/3cf7262876cf261b5704bcf1d70d2de13d595e15.diff
LOG: [CaptureTracking] Handle ptrtoaddr
Unlike ptrtoint, ptrtoaddr does not capture provenance, only the address.
Note: As defined by the LangRef, we always treat `ptrtoaddr` as a
location-independent address capture since it is a direct inspection of the
pointer address.
Reviewed By: nikic
Pull Request: https://github.com/llvm/llvm-project/pull/152221
Added:
Modified:
llvm/lib/Analysis/CaptureTracking.cpp
llvm/test/Transforms/FunctionAttrs/nocapture.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/CaptureTracking.cpp b/llvm/lib/Analysis/CaptureTracking.cpp
index 076f4176c0219..bd0d417b1ed33 100644
--- a/llvm/lib/Analysis/CaptureTracking.cpp
+++ b/llvm/lib/Analysis/CaptureTracking.cpp
@@ -359,6 +359,12 @@ UseCaptureInfo llvm::DetermineUseCaptureKind(const Use &U, const Value *Base) {
case Instruction::AddrSpaceCast:
// The original value is not captured via this if the new value isn't.
return UseCaptureInfo::passthrough();
+ case Instruction::PtrToAddr:
+ // We treat ptrtoaddr as a location-independent capture of the address even
+ // if it is ultimately not used. Continuing recursive analysis after
+ // ptrtoaddr would be possible, but we'd need logic to do that correctly,
+ // which is not the same as the current pointer following logic.
+ return CaptureComponents::Address;
case Instruction::ICmp: {
unsigned Idx = U.getOperandNo();
unsigned OtherIdx = 1 - Idx;
diff --git a/llvm/test/Transforms/FunctionAttrs/nocapture.ll b/llvm/test/Transforms/FunctionAttrs/nocapture.ll
index 9d6acc410de75..26b5dc2dc7760 100644
--- a/llvm/test/Transforms/FunctionAttrs/nocapture.ll
+++ b/llvm/test/Transforms/FunctionAttrs/nocapture.ll
@@ -1082,6 +1082,65 @@ define i64 @captures_not_ret_only(ptr %p) {
ret i64 %int
}
+ at gi = global i64 0
+
+;; Unlike ptrtoint, ptrtoaddr only captures the address
+define i64 @captures_ptrtoaddr_stored(ptr %p) {
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none)
+; FNATTRS-LABEL: define noundef i64 @captures_ptrtoaddr_stored
+; FNATTRS-SAME: (ptr captures(address) [[P:%.*]]) #[[ATTR1]] {
+; FNATTRS-NEXT: [[INT:%.*]] = ptrtoaddr ptr [[P]] to i64
+; FNATTRS-NEXT: store i64 [[INT]], ptr @gi, align 8
+; FNATTRS-NEXT: ret i64 0
+;
+; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
+; ATTRIBUTOR-LABEL: define i64 @captures_ptrtoaddr_stored
+; ATTRIBUTOR-SAME: (ptr nofree writeonly [[P:%.*]]) #[[ATTR1]] {
+; ATTRIBUTOR-NEXT: [[INT:%.*]] = ptrtoaddr ptr [[P]] to i64
+; ATTRIBUTOR-NEXT: store i64 [[INT]], ptr @gi, align 8
+; ATTRIBUTOR-NEXT: ret i64 0
+;
+ %int = ptrtoaddr ptr %p to i64
+ store i64 %int, ptr @gi, align 8
+ ret i64 0
+}
+
+;; Note: ptrtoaddr is a location-independent capture, so we don't get captures(ret: address) here.
+define i64 @captures_ptrtoaddr_ret(ptr %p) {
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+; FNATTRS-LABEL: define i64 @captures_ptrtoaddr_ret
+; FNATTRS-SAME: (ptr captures(address) [[P:%.*]]) #[[ATTR0]] {
+; FNATTRS-NEXT: [[INT:%.*]] = ptrtoaddr ptr [[P]] to i64
+; FNATTRS-NEXT: ret i64 [[INT]]
+;
+; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+; ATTRIBUTOR-LABEL: define i64 @captures_ptrtoaddr_ret
+; ATTRIBUTOR-SAME: (ptr nofree readnone [[P:%.*]]) #[[ATTR0]] {
+; ATTRIBUTOR-NEXT: [[INT:%.*]] = ptrtoaddr ptr [[P]] to i64
+; ATTRIBUTOR-NEXT: ret i64 [[INT]]
+;
+ %int = ptrtoaddr ptr %p to i64
+ ret i64 %int
+}
+
+;; Note: ptrtoaddr is a location-independent capture, so we don't get captures(none) here.
+define i64 @captures_ptrtoaddr_ignored(ptr %p) {
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+; FNATTRS-LABEL: define noundef i64 @captures_ptrtoaddr_ignored
+; FNATTRS-SAME: (ptr captures(address) [[P:%.*]]) #[[ATTR0]] {
+; FNATTRS-NEXT: [[INT:%.*]] = ptrtoaddr ptr [[P]] to i64
+; FNATTRS-NEXT: ret i64 0
+;
+; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+; ATTRIBUTOR-LABEL: define i64 @captures_ptrtoaddr_ignored
+; ATTRIBUTOR-SAME: (ptr nofree readnone [[P:%.*]]) #[[ATTR0]] {
+; ATTRIBUTOR-NEXT: [[INT:%.*]] = ptrtoaddr ptr [[P]] to i64
+; ATTRIBUTOR-NEXT: ret i64 0
+;
+ %int = ptrtoaddr ptr %p to i64
+ ret i64 0
+}
+
define void @captures_read_provenance(ptr %p) {
; FNATTRS-LABEL: define void @captures_read_provenance
; FNATTRS-SAME: (ptr captures(address, read_provenance) [[P:%.*]]) {
More information about the llvm-commits
mailing list