diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp --- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -1427,7 +1427,8 @@ } MemoryUseOrDef *MA = MSSA->getMemoryAccess(M); - MemoryAccess *AnyClobber = MSSA->getWalker()->getClobberingMemoryAccess(MA); + // FIXME: Not using getClobberingMemoryAccess() here due to PR54682. + MemoryAccess *AnyClobber = MA->getDefiningAccess(); MemoryLocation DestLoc = MemoryLocation::getForDest(M); const MemoryAccess *DestClobber = MSSA->getWalker()->getClobberingMemoryAccess(AnyClobber, DestLoc); diff --git a/llvm/test/Transforms/MemCpyOpt/pr54682.ll b/llvm/test/Transforms/MemCpyOpt/pr54682.ll --- a/llvm/test/Transforms/MemCpyOpt/pr54682.ll +++ b/llvm/test/Transforms/MemCpyOpt/pr54682.ll @@ -1,7 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -memcpyopt < %s | FileCheck %s -; FIXME: This currently gets miscompiled. +; The memcpy here is *not* dead, because it reads memory written in a previous +; loop iteration. define void @test(i1 %c, i8* nocapture noundef readonly %path, i8* noundef writeonly %name) { ; CHECK-LABEL: @test( @@ -17,6 +18,7 @@ ; CHECK: exit: ; CHECK-NEXT: [[TMP_IV_1:%.*]] = getelementptr inbounds i8, i8* [[TMP_IV]], i64 1 ; CHECK-NEXT: [[LEN:%.*]] = sub nsw i64 259, [[IV]] +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 [[NAME:%.*]], i8* nonnull align 1 [[TMP_IV_1]], i64 [[LEN]], i1 false) ; CHECK-NEXT: ret void ; entry: