Skip to content

Commit 619f7af

Browse files
artagnonfhahn
andauthored
[LAA] Clean up APInt-overflow related code (#140048)
Co-authored-by: Florian Hahn <flo@fhahn.com>
1 parent 8c77191 commit 619f7af

File tree

2 files changed

+20
-25
lines changed

2 files changed

+20
-25
lines changed

llvm/lib/Analysis/LoopAccessAnalysis.cpp

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -949,18 +949,12 @@ getStrideFromAddRec(const SCEVAddRecExpr *AR, const Loop *Lp, Type *AccessTy,
949949
int64_t Size = AllocSize.getFixedValue();
950950

951951
// Huge step value - give up.
952-
if (APStepVal->getBitWidth() > 64)
952+
std::optional<int64_t> StepVal = APStepVal->trySExtValue();
953+
if (!StepVal)
953954
return std::nullopt;
954955

955-
int64_t StepVal = APStepVal->getSExtValue();
956-
957956
// Strided access.
958-
int64_t Stride = StepVal / Size;
959-
int64_t Rem = StepVal % Size;
960-
if (Rem)
961-
return std::nullopt;
962-
963-
return Stride;
957+
return *StepVal % Size ? std::nullopt : std::make_optional(*StepVal / Size);
964958
}
965959

966960
/// Check whether \p AR is a non-wrapping AddRec. If \p Ptr is not nullptr, use
@@ -2135,15 +2129,18 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
21352129
DL, SE, *(PSE.getSymbolicMaxBackedgeTakenCount()), *Dist, MaxStride))
21362130
return Dependence::NoDep;
21372131

2138-
// Attempt to prove strided accesses independent.
2139-
const APInt *ConstDist = nullptr;
2140-
if (match(Dist, m_scev_APInt(ConstDist))) {
2141-
uint64_t Distance = ConstDist->abs().getZExtValue();
2132+
// The rest of this function relies on ConstDist being at most 64-bits, which
2133+
// is checked earlier. Will assert if the calling code changes.
2134+
const APInt *APDist = nullptr;
2135+
uint64_t ConstDist =
2136+
match(Dist, m_scev_APInt(APDist)) ? APDist->abs().getZExtValue() : 0;
21422137

2138+
// Attempt to prove strided accesses independent.
2139+
if (APDist) {
21432140
// If the distance between accesses and their strides are known constants,
21442141
// check whether the accesses interlace each other.
2145-
if (Distance > 0 && CommonStride && CommonStride > 1 && HasSameSize &&
2146-
areStridedAccessesIndependent(Distance, *CommonStride, TypeByteSize)) {
2142+
if (ConstDist > 0 && CommonStride && CommonStride > 1 && HasSameSize &&
2143+
areStridedAccessesIndependent(ConstDist, *CommonStride, TypeByteSize)) {
21472144
LLVM_DEBUG(dbgs() << "LAA: Strided accesses are independent\n");
21482145
return Dependence::NoDep;
21492146
}
@@ -2184,8 +2181,8 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
21842181
FoundNonConstantDistanceDependence |= ShouldRetryWithRuntimeCheck;
21852182
return Dependence::Unknown;
21862183
}
2187-
if (!HasSameSize || couldPreventStoreLoadForward(
2188-
ConstDist->abs().getZExtValue(), TypeByteSize)) {
2184+
if (!HasSameSize ||
2185+
couldPreventStoreLoadForward(ConstDist, TypeByteSize)) {
21892186
LLVM_DEBUG(
21902187
dbgs() << "LAA: Forward but may prevent st->ld forwarding\n");
21912188
return Dependence::ForwardButPreventsForwarding;

llvm/test/Analysis/LoopAccessAnalysis/dependences-i128-inductions.ll

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ define void @backward_i128(ptr %A, i128 %n) {
1010
; CHECK-LABEL: 'backward_i128'
1111
; CHECK-NEXT: loop:
1212
; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
13-
; CHECK-NEXT: Unsafe indirect dependence.
13+
; CHECK-NEXT: Backward loop carried data dependence.
1414
; CHECK-NEXT: Dependences:
15-
; CHECK-NEXT: IndirectUnsafe:
15+
; CHECK-NEXT: Backward:
1616
; CHECK-NEXT: %l = load i32, ptr %gep.A, align 4 ->
1717
; CHECK-NEXT: store i32 %l, ptr %gep.A.1, align 4
1818
; CHECK-EMPTY:
@@ -45,10 +45,9 @@ exit:
4545
define void @forward_i128(ptr %A, i128 %n) {
4646
; CHECK-LABEL: 'forward_i128'
4747
; CHECK-NEXT: loop:
48-
; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
49-
; CHECK-NEXT: Unsafe indirect dependence.
48+
; CHECK-NEXT: Memory dependences are safe
5049
; CHECK-NEXT: Dependences:
51-
; CHECK-NEXT: IndirectUnsafe:
50+
; CHECK-NEXT: Forward:
5251
; CHECK-NEXT: %l = load i32, ptr %gep.A.1, align 4 ->
5352
; CHECK-NEXT: store i32 %l, ptr %gep.A, align 4
5453
; CHECK-EMPTY:
@@ -81,10 +80,9 @@ exit:
8180
define void @forward_negative_step(ptr %A, i128 %n) {
8281
; CHECK-LABEL: 'forward_negative_step'
8382
; CHECK-NEXT: loop:
84-
; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
85-
; CHECK-NEXT: Unsafe indirect dependence.
83+
; CHECK-NEXT: Memory dependences are safe
8684
; CHECK-NEXT: Dependences:
87-
; CHECK-NEXT: IndirectUnsafe:
85+
; CHECK-NEXT: Forward:
8886
; CHECK-NEXT: %l = load i32, ptr %gep.A, align 4 ->
8987
; CHECK-NEXT: store i32 %l, ptr %gep.A.1, align 4
9088
; CHECK-EMPTY:

0 commit comments

Comments
 (0)