diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -498,7 +498,12 @@ /// Determine if the function does not access or only writes memory. bool doesNotReadMemory() const { - return doesNotAccessMemory() || hasFnAttribute(Attribute::WriteOnly); + return doesNotAccessMemory() || hasFnAttribute(Attribute::WriteOnly) || + (hasFnAttribute(Attribute::ArgMemOnly) && + all_of(args(), [](const Argument &A) { + return !A.getType()->isPointerTy() || + A.hasAttribute(Attribute::WriteOnly); + })); } void setDoesNotReadMemory() { addFnAttr(Attribute::WriteOnly); diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -1673,7 +1673,8 @@ /// Determine if the call does not access or only writes memory. bool doesNotReadMemory() const { - return doesNotAccessMemory() || hasFnAttr(Attribute::WriteOnly); + return doesNotAccessMemory() || hasFnAttr(Attribute::WriteOnly) || + (onlyAccessesArgMemory() && argsWriteOnly()); } void setDoesNotReadMemory() { addAttribute(AttributeList::FunctionIndex, Attribute::WriteOnly); @@ -2146,6 +2147,14 @@ return hasFnAttrOnCalledFunction(Kind); } + + bool argsWriteOnly() const { + for (unsigned I = 0; I < getNumArgOperands(); I++) + if (getArgOperand(I)->getType()->isPointerTy() && + !paramHasAttr(I, Attribute::WriteOnly)) + return false; + return true; + } }; template <> diff --git a/llvm/test/Transforms/Attributor/readattrs.ll b/llvm/test/Transforms/Attributor/readattrs.ll --- a/llvm/test/Transforms/Attributor/readattrs.ll +++ b/llvm/test/Transforms/Attributor/readattrs.ll @@ -93,8 +93,7 @@ ; ATTRIBUTOR: declare <4 x i32> @test11_1 declare <4 x i32> @test11_1(<4 x i32*>) argmemonly nounwind readonly -; ATTRIBUTOR: readonly -; ATTRIBUTOR-NOT: readnone +; ATTRIBUTOR: readnone ; ATTRIBUTOR: define <4 x i32> @test11_2 define <4 x i32> @test11_2(<4 x i32*> %ptrs) { %res = call <4 x i32> @test11_1(<4 x i32*> %ptrs)