diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -1013,7 +1013,7 @@ // The semantics of memcpy intrinsics either exactly overlap or do not // overlap, i.e., source and destination of any given memcpy are either // no-alias or must-alias. - if (auto *Inst = dyn_cast(Call)) { + if (auto *Inst = dyn_cast(Call)) { AliasResult SrcAA = getBestAAResults().alias(MemoryLocation::getForSource(Inst), Loc, AAQI); AliasResult DestAA = diff --git a/llvm/test/Analysis/BasicAA/modref.ll b/llvm/test/Analysis/BasicAA/modref.ll --- a/llvm/test/Analysis/BasicAA/modref.ll +++ b/llvm/test/Analysis/BasicAA/modref.ll @@ -253,7 +253,54 @@ ret i32 %Diff } +define i8 @test_memmove_noalias_locals() { +; CHECK-LABEL: @test_memmove_noalias_locals( +; CHECK-NEXT: ret i8 2 +; + %A = alloca i8 + %B = alloca i8 + + store i8 2, i8* %B ;; Not written to by memcpy + + call void @llvm.memmove.p0i8.p0i8.i8(i8* %A, i8* %B, i8 -1, i1 false) + + %C = load i8, i8* %B + ret i8 %C +} + + +define i8 @test_memmove_mayalias_args(i8 *%A, i8 *%B) { +; CHECK-LABEL: @test_memmove_mayalias_args( +; CHECK-NEXT: store i8 2, i8* [[B:%.*]], align 1 +; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i8(i8* [[A:%.*]], i8* [[B]], i8 -1, i1 false) +; CHECK-NEXT: [[C:%.*]] = load i8, i8* [[B]], align 1 +; CHECK-NEXT: ret i8 [[C]] +; + store i8 2, i8* %B ;; Not written to by memcpy + + call void @llvm.memmove.p0i8.p0i8.i8(i8* %A, i8* %B, i8 -1, i1 false) + + %C = load i8, i8* %B + ret i8 %C +} + +define i8 @test_memmove_noalias_args(i8 * noalias %A, i8 * noalias %B) { +; CHECK-LABEL: @test_memmove_noalias_args( +; CHECK-NEXT: store i8 2, i8* [[B:%.*]], align 1 +; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i8(i8* [[A:%.*]], i8* [[B]], i8 -1, i1 false) +; CHECK-NEXT: ret i8 2 +; + store i8 2, i8* %B ;; Not written to by memcpy + + call void @llvm.memmove.p0i8.p0i8.i8(i8* %A, i8* %B, i8 -1, i1 false) + + %C = load i8, i8* %B + ret i8 %C +} + + declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i1) nounwind declare void @llvm.memset.p0i8.i8(i8* nocapture, i8, i8, i1) nounwind declare void @llvm.memcpy.p0i8.p0i8.i8(i8* nocapture, i8* nocapture, i8, i1) nounwind declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind +declare void @llvm.memmove.p0i8.p0i8.i8(i8* nocapture, i8* nocapture, i8, i1) nounwind