Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions llvm/lib/IR/Value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,12 @@ bool Value::canBeFreed() const {
const Function *F = A->getParent();
if (F->doesNotFreeMemory() && F->hasNoSync())
return false;

// nofree on the argument ensures that it cannot be freed through that
// pointer. noalias additionally ensures that it can't be freed through
// another pointer to the same allocation. Readonly implies nofree.
if ((A->hasNoFreeAttr() || A->onlyReadsMemory()) && A->hasNoAliasAttr())
return false;
}

if (auto *ITP = dyn_cast<IntToPtrInst>(this);
Expand Down
23 changes: 18 additions & 5 deletions llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll
Original file line number Diff line number Diff line change
Expand Up @@ -265,25 +265,38 @@ define void @infer_func_attrs2(ptr dereferenceable(8) %p) readonly {
}

; CHECK-LABEL: 'infer_noalias1'
; GLOBAL: %p
; POINT-NOT: %p
; FIXME: Can be inferred from attributes
; CHECK: %p
define void @infer_noalias1(ptr dereferenceable(8) noalias nofree %p) {
call void @mayfree()
%v = load i32, ptr %p
ret void
}

; CHECK-LABEL: 'infer_noalias2'
; CHECK: %p
define void @infer_noalias2(ptr dereferenceable(8) noalias readonly %p) nosync {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe nit: the other PR may also drop nosync from this, as otherwise now possibly misleading?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, dropped.

call void @mayfree()
%v = load i32, ptr %p
ret void
}

; CHECK-LABEL: 'infer_missing_noalias1'
; GLOBAL: %p
; POINT-NOT: %p
; FIXME: Can be inferred from attributes
define void @infer_noalias2(ptr dereferenceable(8) noalias readonly %p) nosync {
define void @infer_missing_noalias1(ptr dereferenceable(8) nofree %p) {
call void @mayfree()
%v = load i32, ptr %p
ret void
}

; CHECK-LABEL: 'infer_missing_noalias2'
; GLOBAL: %p
; POINT-NOT: %p
define void @infer_missing_noalias2(ptr dereferenceable(8) readonly %p) {
call void @mayfree()
%v = load i32, ptr %p
ret void
}

; Just check that we don't crash.
; CHECK-LABEL: 'opaque_type_crasher'
Expand Down