diff --git a/llvm/lib/Analysis/CaptureTracking.cpp b/llvm/lib/Analysis/CaptureTracking.cpp --- a/llvm/lib/Analysis/CaptureTracking.cpp +++ b/llvm/lib/Analysis/CaptureTracking.cpp @@ -314,8 +314,8 @@ // its return value and doesn't unwind (a readonly function can leak bits // by throwing an exception or not depending on the input value). if (Call->onlyReadsMemory() && Call->doesNotThrow() && - Call->getType()->isVoidTy()) - return UseCaptureKind::NO_CAPTURE; + (Call->getType()->isVoidTy() || Call->returnDoesNotAlias())) + return UseCaptureKind::NO_CAPTURE; // The pointer is not captured if returned pointer is not captured. // NOTE: CaptureTracking users should not assume that only functions diff --git a/llvm/test/Transforms/FunctionAttrs/nocapture.ll b/llvm/test/Transforms/FunctionAttrs/nocapture.ll --- a/llvm/test/Transforms/FunctionAttrs/nocapture.ll +++ b/llvm/test/Transforms/FunctionAttrs/nocapture.ll @@ -568,7 +568,7 @@ define ptr @noalias_ret(ptr %f, ptr %p) { ; CHECK-LABEL: define ptr @noalias_ret -; CHECK-SAME: (ptr nocapture readonly [[F:%.*]], ptr readonly [[P:%.*]]) #[[ATTR5]] { +; CHECK-SAME: (ptr nocapture readonly [[F:%.*]], ptr nocapture readonly [[P:%.*]]) #[[ATTR5]] { ; CHECK-NEXT: [[R:%.*]] = call noalias ptr [[F]](ptr [[P]]) #[[ATTR8]] ; CHECK-NEXT: ret ptr [[R]] ;