From LangRef:
The '`llvm.memcpy.*`' intrinsics copy a block of memory from the
source location to the destination location, which are not allowed to overlap.
Quick demo with -aa-eval:
; opt -basicaa -aa-eval -print-all-alias-modref-info Transforms/Util/MemorySSA/basicaa-memcpy.ll declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind define void @source_clobber(i8* %a, i8* %b) { call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 128, i32 1, i1 false) %x = load i8, i8* %b ret void } ; Function: source_clobber: 2 pointers, 1 call sites ; MayAlias: i8* %a, i8* %b ; Just Mod: Ptr: i8* %a <-> call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 128, i32 1, i1 false) ; Just Ref: Ptr: i8* %b <-> call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 128, i32 1, i1 false)
Note the "Just {Mod,Ref}" results.
This entire change should be unnecessary. We have readonly and writeonly attributes with these semantics and the intrinsic should already be declared with them.
Reading further, it looks like you're change is mainly aimed at the no alias property right? If so, take a look at the noalias parameter attribute. It might be we've forgotten to tag the intrinsic correctly.