diff --git a/llvm/lib/Analysis/MemorySSA.cpp b/llvm/lib/Analysis/MemorySSA.cpp --- a/llvm/lib/Analysis/MemorySSA.cpp +++ b/llvm/lib/Analysis/MemorySSA.cpp @@ -2402,22 +2402,23 @@ MemorySSA::ClobberWalkerBase::getClobberingMemoryAccessBase( MemoryAccess *StartingAccess, const MemoryLocation &Loc, unsigned &UpwardWalkLimit) { - if (isa(StartingAccess)) - return StartingAccess; + assert(!isa(StartingAccess) && "Use cannot be defining access"); - auto *StartingUseOrDef = cast(StartingAccess); - if (MSSA->isLiveOnEntryDef(StartingUseOrDef)) - return StartingUseOrDef; + Instruction *I = nullptr; + if (auto *StartingUseOrDef = dyn_cast(StartingAccess)) { + if (MSSA->isLiveOnEntryDef(StartingUseOrDef)) + return StartingUseOrDef; - Instruction *I = StartingUseOrDef->getMemoryInst(); + I = StartingUseOrDef->getMemoryInst(); - // Conservatively, fences are always clobbers, so don't perform the walk if we - // hit a fence. - if (!isa(I) && I->isFenceLike()) - return StartingUseOrDef; + // Conservatively, fences are always clobbers, so don't perform the walk if + // we hit a fence. + if (!isa(I) && I->isFenceLike()) + return StartingUseOrDef; + } UpwardsMemoryQuery Q; - Q.OriginalAccess = StartingUseOrDef; + Q.OriginalAccess = StartingAccess; Q.StartingLoc = Loc; Q.Inst = nullptr; Q.IsCall = false; @@ -2425,16 +2426,14 @@ // Unlike the other function, do not walk to the def of a def, because we are // handed something we already believe is the clobbering access. // We never set SkipSelf to true in Q in this method. - MemoryAccess *DefiningAccess = isa(StartingUseOrDef) - ? StartingUseOrDef->getDefiningAccess() - : StartingUseOrDef; - MemoryAccess *Clobber = - Walker.findClobber(DefiningAccess, Q, UpwardWalkLimit); - LLVM_DEBUG(dbgs() << "Starting Memory SSA clobber for " << *I << " is "); - LLVM_DEBUG(dbgs() << *StartingUseOrDef << "\n"); - LLVM_DEBUG(dbgs() << "Final Memory SSA clobber for " << *I << " is "); - LLVM_DEBUG(dbgs() << *Clobber << "\n"); + Walker.findClobber(StartingAccess, Q, UpwardWalkLimit); + LLVM_DEBUG({ + dbgs() << "Clobber starting at access " << *StartingAccess << "\n"; + if (I) + dbgs() << " for instruction " << *I << "\n"; + dbgs() << " is " << *Clobber << "\n"; + }); return Clobber; } diff --git a/llvm/test/Transforms/MemCpyOpt/memcpy-in-loop.ll b/llvm/test/Transforms/MemCpyOpt/memcpy-in-loop.ll --- a/llvm/test/Transforms/MemCpyOpt/memcpy-in-loop.ll +++ b/llvm/test/Transforms/MemCpyOpt/memcpy-in-loop.ll @@ -12,7 +12,6 @@ ; CHECK: loop: ; CHECK-NEXT: [[CURRENT:%.*]] = phi [1000 x i32]* [ [[BEGIN]], [[START:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[CURRENT_I8:%.*]] = bitcast [1000 x i32]* [[CURRENT]] to i8* -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 4 dereferenceable(4000) [[CURRENT_I8]], i8* nonnull align 4 dereferenceable(4000) [[ALLOCA_I8]], i64 4000, i1 false) ; CHECK-NEXT: [[NEXT]] = getelementptr inbounds [1000 x i32], [1000 x i32]* [[CURRENT]], i64 1 ; CHECK-NEXT: [[COND:%.*]] = icmp eq [1000 x i32]* [[NEXT]], [[END]] ; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]] @@ -50,7 +49,7 @@ ; CHECK: loop: ; CHECK-NEXT: [[CURRENT:%.*]] = phi [1000 x i32]* [ [[BEGIN]], [[START:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[CURRENT_I8:%.*]] = bitcast [1000 x i32]* [[CURRENT]] to i8* -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 4 dereferenceable(4000) [[CURRENT_I8]], i8* nonnull align 4 dereferenceable(4000) [[ALLOCA_I8]], i64 4000, i1 false) +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[CURRENT_I8]], i8 0, i64 4000, i1 false) ; CHECK-NEXT: [[NEXT]] = getelementptr inbounds [1000 x i32], [1000 x i32]* [[CURRENT]], i64 1 ; CHECK-NEXT: [[COND:%.*]] = icmp eq [1000 x i32]* [[NEXT]], [[END]] ; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]]