Skip to content

Commit a0017c2

Browse files
committed
[MemorySSA] Be more conservative when traversing MemoryPhis.
I think we need to be even more conservative when traversing memory phis, to make sure we catch any loop carried dependences. This approach updates fillInCurrentPair to use unknown sizes for locations when we walk over a phi, unless the location is guaranteed to be loop-invariant for any possible loop. Using an unknown size for locations should ensure we catch all memory accesses to locations after the given memory location, which includes loop-carried dependences. Reviewed By: asbirlea Differential Revision: https://reviews.llvm.org/D87778
1 parent 179a22e commit a0017c2

File tree

2 files changed

+43
-9
lines changed

2 files changed

+43
-9
lines changed

llvm/include/llvm/Analysis/MemorySSA.h

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
#include "llvm/IR/DerivedUser.h"
8989
#include "llvm/IR/Dominators.h"
9090
#include "llvm/IR/Module.h"
91+
#include "llvm/IR/Operator.h"
9192
#include "llvm/IR/Type.h"
9293
#include "llvm/IR/Use.h"
9394
#include "llvm/IR/User.h"
@@ -1217,27 +1218,61 @@ class upward_defs_iterator
12171218
BasicBlock *getPhiArgBlock() const { return DefIterator.getPhiArgBlock(); }
12181219

12191220
private:
1221+
/// Returns true if \p Ptr is guaranteed to be loop invariant for any possible
1222+
/// loop. In particular, this guarantees that it only references a single
1223+
/// MemoryLocation during execution of the containing function.
1224+
bool IsGuaranteedLoopInvariant(Value *Ptr) const {
1225+
auto IsGuaranteedLoopInvariantBase = [](Value *Ptr) {
1226+
Ptr = Ptr->stripPointerCasts();
1227+
if (auto *I = dyn_cast<Instruction>(Ptr)) {
1228+
if (isa<AllocaInst>(Ptr))
1229+
return true;
1230+
return false;
1231+
}
1232+
return true;
1233+
};
1234+
1235+
Ptr = Ptr->stripPointerCasts();
1236+
if (auto *GEP = dyn_cast<GEPOperator>(Ptr)) {
1237+
return IsGuaranteedLoopInvariantBase(GEP->getPointerOperand()) &&
1238+
GEP->hasAllConstantIndices();
1239+
}
1240+
return IsGuaranteedLoopInvariantBase(Ptr);
1241+
}
1242+
12201243
void fillInCurrentPair() {
12211244
CurrentPair.first = *DefIterator;
1245+
CurrentPair.second = Location;
12221246
if (WalkingPhi && Location.Ptr) {
1247+
// Mark size as unknown, if the location is not guaranteed to be
1248+
// loop-invariant for any possible loop in the function. Setting the size
1249+
// to unknown guarantees that any memory accesses that access locations
1250+
// after the pointer are considered as clobbers, which is important to
1251+
// catch loop carried dependences.
1252+
if (Location.Ptr &&
1253+
!IsGuaranteedLoopInvariant(const_cast<Value *>(Location.Ptr)))
1254+
CurrentPair.second = Location.getWithNewSize(LocationSize::unknown());
12231255
PHITransAddr Translator(
12241256
const_cast<Value *>(Location.Ptr),
12251257
OriginalAccess->getBlock()->getModule()->getDataLayout(), nullptr);
1258+
12261259
if (!Translator.PHITranslateValue(OriginalAccess->getBlock(),
12271260
DefIterator.getPhiArgBlock(), DT,
12281261
true)) {
1229-
if (Translator.getAddr() != Location.Ptr) {
1230-
CurrentPair.second = Location.getWithNewPtr(Translator.getAddr());
1262+
Value *TransAddr = Translator.getAddr();
1263+
if (TransAddr != Location.Ptr) {
1264+
CurrentPair.second = CurrentPair.second.getWithNewPtr(TransAddr);
1265+
1266+
if (TransAddr &&
1267+
!IsGuaranteedLoopInvariant(const_cast<Value *>(TransAddr)))
1268+
CurrentPair.second =
1269+
CurrentPair.second.getWithNewSize(LocationSize::unknown());
1270+
12311271
if (PerformedPhiTranslation)
12321272
*PerformedPhiTranslation = true;
1233-
return;
12341273
}
1235-
} else {
1236-
CurrentPair.second = Location.getWithNewSize(LocationSize::unknown());
1237-
return;
12381274
}
12391275
}
1240-
CurrentPair.second = Location;
12411276
}
12421277

12431278
MemoryAccessPair CurrentPair;

llvm/test/Analysis/MemorySSA/phi-translation.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -481,8 +481,7 @@ define void @another_loop_clobber() {
481481
; CHECK-NEXT: ; 4 = MemoryPhi({entry,1},{cond.read,3})
482482

483483
; CHECK-LABEL: cond.read:
484-
; NOLIMIT: ; MemoryUse(liveOnEntry)
485-
; LIMIT: ; MemoryUse(4)
484+
; CHECK: ; MemoryUse(4)
486485
; CHECK-NEXT: %use = load i32, i32* %ptr.1, align 4
487486
; CHECK-NEXT: ; 2 = MemoryDef(4)
488487
; CHECK-NEXT: %c.2 = call i1 @cond(i32 %use)

0 commit comments

Comments
 (0)