Index: llvm/lib/IR/Value.cpp =================================================================== --- llvm/lib/IR/Value.cpp +++ llvm/lib/IR/Value.cpp @@ -749,10 +749,9 @@ if (!F) return true; - // A pointer to an object in a function which neither frees, nor can arrange - // for another thread to free on its behalf, can not be freed in the scope - // of the function. - if (F->doesNotFreeMemory() && F->hasNoSync()) + // A pointer to an object in a function which doesn't free memory, directly + // or indirectly (e.g. via creation of other threads that do it). + if (F->doesNotFreeMemory()) return false; // With garbage collection, deallocation typically occurs solely at or after Index: llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll =================================================================== --- llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll +++ llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll @@ -261,8 +261,7 @@ ; CHECK-LABEL: 'infer_func_attrs2' ; GLOBAL: %p -; POINT-NOT: %p -; FIXME: Can be inferred from attributes +; POINT: %p define void @infer_func_attrs2(i32* dereferenceable(8) %p) readonly { call void @mayfree() %v = load i32, i32* %p