Skip to content

Commit b1e89f4

Browse files
arichardsongithub-actions[bot]
authored andcommitted
Automerge: [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: llvm/llvm-project#152221
2 parents d6132c2 + 3cf7262 commit b1e89f4

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

llvm/lib/Analysis/CaptureTracking.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,12 @@ UseCaptureInfo llvm::DetermineUseCaptureKind(const Use &U, const Value *Base) {
359359
case Instruction::AddrSpaceCast:
360360
// The original value is not captured via this if the new value isn't.
361361
return UseCaptureInfo::passthrough();
362+
case Instruction::PtrToAddr:
363+
// We treat ptrtoaddr as a location-independent capture of the address even
364+
// if it is ultimately not used. Continuing recursive analysis after
365+
// ptrtoaddr would be possible, but we'd need logic to do that correctly,
366+
// which is not the same as the current pointer following logic.
367+
return CaptureComponents::Address;
362368
case Instruction::ICmp: {
363369
unsigned Idx = U.getOperandNo();
364370
unsigned OtherIdx = 1 - Idx;

llvm/test/Transforms/FunctionAttrs/nocapture.ll

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,65 @@ define i64 @captures_not_ret_only(ptr %p) {
10821082
ret i64 %int
10831083
}
10841084

1085+
@gi = global i64 0
1086+
1087+
;; Unlike ptrtoint, ptrtoaddr only captures the address
1088+
define i64 @captures_ptrtoaddr_stored(ptr %p) {
1089+
; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none)
1090+
; FNATTRS-LABEL: define noundef i64 @captures_ptrtoaddr_stored
1091+
; FNATTRS-SAME: (ptr captures(address) [[P:%.*]]) #[[ATTR1]] {
1092+
; FNATTRS-NEXT: [[INT:%.*]] = ptrtoaddr ptr [[P]] to i64
1093+
; FNATTRS-NEXT: store i64 [[INT]], ptr @gi, align 8
1094+
; FNATTRS-NEXT: ret i64 0
1095+
;
1096+
; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
1097+
; ATTRIBUTOR-LABEL: define i64 @captures_ptrtoaddr_stored
1098+
; ATTRIBUTOR-SAME: (ptr nofree writeonly [[P:%.*]]) #[[ATTR1]] {
1099+
; ATTRIBUTOR-NEXT: [[INT:%.*]] = ptrtoaddr ptr [[P]] to i64
1100+
; ATTRIBUTOR-NEXT: store i64 [[INT]], ptr @gi, align 8
1101+
; ATTRIBUTOR-NEXT: ret i64 0
1102+
;
1103+
%int = ptrtoaddr ptr %p to i64
1104+
store i64 %int, ptr @gi, align 8
1105+
ret i64 0
1106+
}
1107+
1108+
;; Note: ptrtoaddr is a location-independent capture, so we don't get captures(ret: address) here.
1109+
define i64 @captures_ptrtoaddr_ret(ptr %p) {
1110+
; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1111+
; FNATTRS-LABEL: define i64 @captures_ptrtoaddr_ret
1112+
; FNATTRS-SAME: (ptr captures(address) [[P:%.*]]) #[[ATTR0]] {
1113+
; FNATTRS-NEXT: [[INT:%.*]] = ptrtoaddr ptr [[P]] to i64
1114+
; FNATTRS-NEXT: ret i64 [[INT]]
1115+
;
1116+
; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1117+
; ATTRIBUTOR-LABEL: define i64 @captures_ptrtoaddr_ret
1118+
; ATTRIBUTOR-SAME: (ptr nofree readnone [[P:%.*]]) #[[ATTR0]] {
1119+
; ATTRIBUTOR-NEXT: [[INT:%.*]] = ptrtoaddr ptr [[P]] to i64
1120+
; ATTRIBUTOR-NEXT: ret i64 [[INT]]
1121+
;
1122+
%int = ptrtoaddr ptr %p to i64
1123+
ret i64 %int
1124+
}
1125+
1126+
;; Note: ptrtoaddr is a location-independent capture, so we don't get captures(none) here.
1127+
define i64 @captures_ptrtoaddr_ignored(ptr %p) {
1128+
; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1129+
; FNATTRS-LABEL: define noundef i64 @captures_ptrtoaddr_ignored
1130+
; FNATTRS-SAME: (ptr captures(address) [[P:%.*]]) #[[ATTR0]] {
1131+
; FNATTRS-NEXT: [[INT:%.*]] = ptrtoaddr ptr [[P]] to i64
1132+
; FNATTRS-NEXT: ret i64 0
1133+
;
1134+
; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1135+
; ATTRIBUTOR-LABEL: define i64 @captures_ptrtoaddr_ignored
1136+
; ATTRIBUTOR-SAME: (ptr nofree readnone [[P:%.*]]) #[[ATTR0]] {
1137+
; ATTRIBUTOR-NEXT: [[INT:%.*]] = ptrtoaddr ptr [[P]] to i64
1138+
; ATTRIBUTOR-NEXT: ret i64 0
1139+
;
1140+
%int = ptrtoaddr ptr %p to i64
1141+
ret i64 0
1142+
}
1143+
10851144
define void @captures_read_provenance(ptr %p) {
10861145
; FNATTRS-LABEL: define void @captures_read_provenance
10871146
; FNATTRS-SAME: (ptr captures(address, read_provenance) [[P:%.*]]) {

0 commit comments

Comments
 (0)