Skip to content

Commit f664d31

Browse files
authored
MemCpyOpt: replace an AA query with MSSA query (NFC) (#108535)
Fix a long-standing TODO.
1 parent fc661df commit f664d31

File tree

2 files changed

+27
-14
lines changed

2 files changed

+27
-14
lines changed

llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,7 @@ bool MemCpyOptPass::processStoreOfLoad(StoreInst *SI, LoadInst *LI,
638638
if (!LI->isSimple() || !LI->hasOneUse() || LI->getParent() != SI->getParent())
639639
return false;
640640

641+
BatchAAResults BAA(*AA);
641642
auto *T = LI->getType();
642643
// Don't introduce calls to memcpy/memmove intrinsics out of thin air if
643644
// the corresponding libcalls are not available.
@@ -647,19 +648,17 @@ bool MemCpyOptPass::processStoreOfLoad(StoreInst *SI, LoadInst *LI,
647648
(EnableMemCpyOptWithoutLibcalls ||
648649
(TLI->has(LibFunc_memcpy) && TLI->has(LibFunc_memmove)))) {
649650
MemoryLocation LoadLoc = MemoryLocation::get(LI);
650-
651-
// We use alias analysis to check if an instruction may store to
652-
// the memory we load from in between the load and the store. If
653-
// such an instruction is found, we try to promote there instead
654-
// of at the store position.
655-
// TODO: Can use MSSA for this.
656-
Instruction *P = SI;
657-
for (auto &I : make_range(++LI->getIterator(), SI->getIterator())) {
658-
if (isModSet(AA->getModRefInfo(&I, LoadLoc))) {
659-
P = &I;
660-
break;
661-
}
662-
}
651+
MemoryUseOrDef *LoadAccess = MSSA->getMemoryAccess(LI),
652+
*StoreAccess = MSSA->getMemoryAccess(SI);
653+
654+
// We use MSSA to check if an instruction may store to the memory we load
655+
// from in between the load and the store. If such an instruction is found,
656+
// we try to promote there instead of at the store position.
657+
auto *Clobber = MSSA->getWalker()->getClobberingMemoryAccess(
658+
StoreAccess->getDefiningAccess(), LoadLoc, BAA);
659+
Instruction *P = MSSA->dominates(LoadAccess, Clobber)
660+
? cast<MemoryUseOrDef>(Clobber)->getMemoryInst()
661+
: SI;
663662

664663
// If we found an instruction that may write to the loaded memory,
665664
// we can try to promote at this position instead of the store
@@ -707,7 +706,6 @@ bool MemCpyOptPass::processStoreOfLoad(StoreInst *SI, LoadInst *LI,
707706
// Detect cases where we're performing call slot forwarding, but
708707
// happen to be using a load-store pair to implement it, rather than
709708
// a memcpy.
710-
BatchAAResults BAA(*AA);
711709
auto GetCall = [&]() -> CallInst * {
712710
// We defer this expensive clobber walk until the cheap checks
713711
// have been done on the source inside performCallSlotOptzn.

llvm/test/Transforms/MemCpyOpt/fca2memcpy.ll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,19 @@ define void @throwing_call(ptr noalias %src, ptr %dst) {
141141
ret void
142142
}
143143

144+
define void @loop_memoryphi(ptr %a, ptr %b) {
145+
; CHECK-LABEL: @loop_memoryphi(
146+
; CHECK-NEXT: br label [[LOOP:%.*]]
147+
; CHECK: loop:
148+
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 8 [[B:%.*]], ptr align 8 [[A:%.*]], i64 16, i1 false)
149+
; CHECK-NEXT: br label [[LOOP]]
150+
;
151+
br label %loop
152+
153+
loop:
154+
%v = load { i64, i64 }, ptr %a
155+
store { i64, i64 } %v, ptr %b
156+
br label %loop
157+
}
158+
144159
declare void @call()

0 commit comments

Comments
 (0)