Skip to content

Commit e9bea41

Browse files
committed
[LAA] Support monotonic pointers in LoopAccessAnalysis
1 parent 2c9422e commit e9bea41

File tree

2 files changed

+43
-6
lines changed

2 files changed

+43
-6
lines changed

llvm/lib/Analysis/LoopAccessAnalysis.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "llvm/ADT/SmallVector.h"
2424
#include "llvm/Analysis/AliasAnalysis.h"
2525
#include "llvm/Analysis/AliasSetTracker.h"
26+
#include "llvm/Analysis/IVDescriptors.h"
2627
#include "llvm/Analysis/LoopAnalysisManager.h"
2728
#include "llvm/Analysis/LoopInfo.h"
2829
#include "llvm/Analysis/LoopIterator.h"
@@ -854,7 +855,8 @@ static bool isNoWrap(PredicatedScalarEvolution &PSE, const SCEVAddRecExpr *AR,
854855
if (AR->getNoWrapFlags(SCEV::NoWrapMask))
855856
return true;
856857

857-
if (Ptr && PSE.hasNoOverflow(Ptr, SCEVWrapPredicate::IncrementNUSW))
858+
if (Ptr && isa<SCEVAddRecExpr>(PSE.getSCEV(Ptr)) &&
859+
PSE.hasNoOverflow(Ptr, SCEVWrapPredicate::IncrementNUSW))
858860
return true;
859861

860862
// The address calculation must not wrap. Otherwise, a dependence could be
@@ -1088,6 +1090,20 @@ static void findForkedSCEVs(
10881090
}
10891091
}
10901092

1093+
// Conservatively replace SCEV of Ptr value if it can't be computed directly,
1094+
// e.g. for monotonic values (they can be treated as affine AddRecs that are
1095+
// updated under some predicate).
1096+
static const SCEV *
1097+
replacePtrSCEV(PredicatedScalarEvolution &PSE, Value *Ptr,
1098+
const DenseMap<Value *, const SCEV *> &StridesMap,
1099+
const Loop *L) {
1100+
ScalarEvolution *SE = PSE.getSE();
1101+
if (MonotonicDescriptor MD;
1102+
MonotonicDescriptor::isMonotonicVal(Ptr, L, MD, *SE))
1103+
return MD.getExpr();
1104+
return replaceSymbolicStrideSCEV(PSE, StridesMap, Ptr);
1105+
}
1106+
10911107
static SmallVector<PointerIntPair<const SCEV *, 1, bool>>
10921108
findForkedPointer(PredicatedScalarEvolution &PSE,
10931109
const DenseMap<Value *, const SCEV *> &StridesMap, Value *Ptr,
@@ -1110,7 +1126,7 @@ findForkedPointer(PredicatedScalarEvolution &PSE,
11101126
return Scevs;
11111127
}
11121128

1113-
return {{replaceSymbolicStrideSCEV(PSE, StridesMap, Ptr), false}};
1129+
return {{replacePtrSCEV(PSE, Ptr, StridesMap, L), false}};
11141130
}
11151131

11161132
bool AccessAnalysis::createCheckForAccess(
@@ -1141,8 +1157,7 @@ bool AccessAnalysis::createCheckForAccess(
11411157
// If there's only one option for Ptr, look it up after bounds and wrap
11421158
// checking, because assumptions might have been added to PSE.
11431159
if (TranslatedPtrs.size() == 1) {
1144-
AR =
1145-
cast<SCEVAddRecExpr>(replaceSymbolicStrideSCEV(PSE, StridesMap, Ptr));
1160+
AR = cast<SCEVAddRecExpr>(replacePtrSCEV(PSE, Ptr, StridesMap, TheLoop));
11461161
P.setPointer(AR);
11471162
}
11481163

llvm/test/Analysis/LoopAccessAnalysis/monotonic-pointers.ll

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,21 @@ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
66
define void @monotonic_ptr_simple(ptr writeonly %dst, ptr readonly %src, i32 %c, i32 %n) {
77
; CHECK-LABEL: 'monotonic_ptr_simple'
88
; CHECK-NEXT: for.body:
9-
; CHECK-NEXT: Report: cannot identify array bounds
9+
; CHECK-NEXT: Memory dependences are safe with run-time checks
1010
; CHECK-NEXT: Dependences:
1111
; CHECK-NEXT: Run-time memory checks:
12+
; CHECK-NEXT: Check 0:
13+
; CHECK-NEXT: Comparing group ([[GRP1:0x[0-9a-f]+]]):
14+
; CHECK-NEXT: %dst.addr.09 = phi ptr [ %dst, %entry ], [ %dst.addr.1, %for.inc ]
15+
; CHECK-NEXT: Against group ([[GRP2:0x[0-9a-f]+]]):
16+
; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %src, i64 %indvars.iv
1217
; CHECK-NEXT: Grouped accesses:
18+
; CHECK-NEXT: Group [[GRP1]]:
19+
; CHECK-NEXT: (Low: %dst High: ((4 * (zext i32 %n to i64))<nuw><nsw> + %dst))
20+
; CHECK-NEXT: Member: {%dst,+,4}<nsw><%for.body>
21+
; CHECK-NEXT: Group [[GRP2]]:
22+
; CHECK-NEXT: (Low: %src High: ((4 * (zext i32 %n to i64))<nuw><nsw> + %src))
23+
; CHECK-NEXT: Member: {%src,+,4}<nuw><%for.body>
1324
; CHECK-EMPTY:
1425
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
1526
; CHECK-NEXT: SCEV assumptions:
@@ -46,10 +57,21 @@ exit:
4657
define void @monotonic_ptr_indexed(ptr writeonly %dst, ptr readonly %src, i32 %c, i32 %n) {
4758
; CHECK-LABEL: 'monotonic_ptr_indexed'
4859
; CHECK-NEXT: for.body:
49-
; CHECK-NEXT: Report: cannot identify array bounds
60+
; CHECK-NEXT: Memory dependences are safe with run-time checks
5061
; CHECK-NEXT: Dependences:
5162
; CHECK-NEXT: Run-time memory checks:
63+
; CHECK-NEXT: Check 0:
64+
; CHECK-NEXT: Comparing group ([[GRP3:0x[0-9a-f]+]]):
65+
; CHECK-NEXT: %arrayidx5 = getelementptr inbounds i32, ptr %dst, i64 %idxprom4
66+
; CHECK-NEXT: Against group ([[GRP4:0x[0-9a-f]+]]):
67+
; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %src, i64 %indvars.iv
5268
; CHECK-NEXT: Grouped accesses:
69+
; CHECK-NEXT: Group [[GRP3]]:
70+
; CHECK-NEXT: (Low: %dst High: ((4 * (zext i32 %n to i64))<nuw><nsw> + %dst))
71+
; CHECK-NEXT: Member: {%dst,+,4}<%for.body>
72+
; CHECK-NEXT: Group [[GRP4]]:
73+
; CHECK-NEXT: (Low: %src High: ((4 * (zext i32 %n to i64))<nuw><nsw> + %src))
74+
; CHECK-NEXT: Member: {%src,+,4}<nuw><%for.body>
5375
; CHECK-EMPTY:
5476
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
5577
; CHECK-NEXT: SCEV assumptions:

0 commit comments

Comments
 (0)