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.
Please add a comment here explaining why you can return MRI_Ref without even checking the destination (i.e. that you're relying on the memcpy semantics which forbid overlapping memory). With that, this LGTM.
We really should also add similar logic here for memmove and memset. Would you do this as follow-up?