Index: lib/Analysis/BasicAliasAnalysis.cpp =================================================================== --- lib/Analysis/BasicAliasAnalysis.cpp +++ lib/Analysis/BasicAliasAnalysis.cpp @@ -616,6 +616,9 @@ } // FIXME: Handle memset_pattern4 and memset_pattern8 also. + if (CS.paramHasAttr(ArgIdx + 1, Attribute::ReadOnly)) + return MRI_Ref; + return AAResultBase::getArgModRefInfo(CS, ArgIdx); } Index: test/Analysis/BasicAA/modref.ll =================================================================== --- test/Analysis/BasicAA/modref.ll +++ test/Analysis/BasicAA/modref.ll @@ -190,6 +190,32 @@ ; CHECK: ret i32 %Diff } +; CHECK-LABEL: @test11( +define i32 @test11(i32* %P, i32* %P2) { + %V1 = load i32, i32* %P + call i32 @func_argmemonly(i32* readonly %P2) + %V2 = load i32, i32* %P + %Diff = sub i32 %V1, %V2 + ret i32 %Diff + ; CHECK-NOT: load + ; CHECK: ret i32 0 +} + +declare i32 @func_argmemonly_two_args(i32* %P, i32* %P2) argmemonly + +; CHECK-LABEL: @test12( +define i32 @test12(i32* %P, i32* %P2, i32* %P3) { + %V1 = load i32, i32* %P + call i32 @func_argmemonly_two_args(i32* readonly %P2, i32* %P3) + %V2 = load i32, i32* %P + %Diff = sub i32 %V1, %V2 + ret i32 %Diff + ; CHECK: load + ; CHECK: load + ; CHECK: sub + ; CHECK: ret i32 %Diff +} + declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind declare void @llvm.memset.p0i8.i8(i8* nocapture, i8, i8, i32, i1) nounwind declare void @llvm.memcpy.p0i8.p0i8.i8(i8* nocapture, i8* nocapture, i8, i32, i1) nounwind